HPCメモ

HPC(High Performance Computing)に関連したりしなかったりすることのメモ書き

docker環境構築 on Mac

travisCIでdockerを使えばubuntu以外の色々なOSでテストができるらしいということを知って、試行錯誤していたんですが try and errorで.travis.ymlを書き変えてはgithubにpushしてtraviCIに「ちゃうでー」と怒られるのを繰り返すのが辛くなってきたので 手元のmacにdockerの環境を作ってみました。

必要なのはこれだけ

> brew cask install docker
> open /Applications/Docker.app

アプリが立ち上がって、パスワードを聞かれるので正直に答えるとdockerが使えます。

> docker --version
Docker version 18.03.1-ce, build 9ee9f40
> docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

> docker run -it ubuntu bash
# uname -a
Linux 562794c23cf8 4.9.87-linuxkit-aufs #1 SMP Wed Mar 14 15:12:16 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
>docker rm `docker ps -a -q`
562794c23cf8
df64e1d5290b
9da30ff61d16
384cdda9dd3a
````

vagrantでvirtual boxを立ち上げるのに比べると、格段に早いですねー

まーchroot環境(微妙に違うか)だから、障害対応とかはvagrant + virtual boxで再現環境を作らんとだめだろうけど、普段の開発はこっちでも良いような気がしてきた。

あとはdocker環境でテストが動くように書き換えてから、.travis.ymlに再挑戦か・・・

git stash popで発生したコンフリクトを解消する。

さきに参考URL

dackdive.hateblo.jp d.hatena.ne.jp

こんな流れで作業していてはまりました。

あるファイルを編集中に障害の調査をしなきゃならん事態が発生

編集中のファイルをstashして同じブランチで障害の調査を開始*1

デバッグコードを埋め込んだり、ついでに見つかったバグを修正したりでstashした時に修正中のファイル以外を修正

さて、編集したファイルは被ってないからstash popするべー*2

あら、コンフリクトしてますな・・・

という状況です。

"foo" "bar" "baz"の3ファイルがリポジトリにあったとすると fooとbarは手元のファイルを残して"baz"だけstashしてたものをとり込むという操作をやりたいのです。

こんな時はこんな感じで、必要なファイルだけをstashからcheckoutして上書きできます。

> git checkout --theirs stash@{0} baz

この後、bazはgit stashした時のファイルに戻って、さらにgit addされた状態になってます。 stashの方も残ったままなので、不要であれば

> git stash drop

して消しておきましょう。

stashしたものだからpop時のオプションでなんとかなるだろうと思って調べてたんですが、どうやらそういうわけではないようです。 しかし、スタックに積んでおいて全部出さずにちょっとだけ持っていくとかお行儀悪いなwww*3

*1:これがそもそもの間違い。一旦ブランチを切って保存した上で元のブランチから調査用のブランチを切るべき・・・なんだけど作業を始める時の精神状態だと全部破棄してstash popで戻ってくりゃおっけーって思うんですよねorz

*2:一時的に修正中のファイルをリネームしてgit checkoutしたような感覚でいたけど、stashはあくまでworking directory全体を保存してるので別のファイルを弄ったらそりゃーコンフリクトしますね・・・

*3:いや、最終的にはdropしてるけど・・・

mermeidのサポート状況

今までgitlabのこと微妙なやつだと思ってたんですが、markdownでmermaidをサポートしてたんですね!!

docs.gitlab.com

普段使っているbitbucket & githubでどうなるかというと、こんな感じでただのコードブロックとして表示されます。*1

bitbucketの場合 f:id:n_so5:20180405220451p:plain

githubの場合 f:id:n_so5:20180405220459p:plain

ところがgit labだとこんな感じでグラフとして表示されます。 f:id:n_so5:20180405220255p:plain

ちなみに、はてなだと

graph

graph TD
    A-->B;
    A-->C;
    B-->D;
    C-->D;

sequence diagram

sequenceDiagram
    participant Alice
    participant Bob
    Alice->John: Hello John, how are you?
    loop Healthcheck
        John->John: Fight against hypochondria
    end
    Note right of John: Rational thoughts <br/>prevail...
    John-->Alice: Great!
    John->Bob: How about you?
    Bob-->John: Jolly good!

gantt chart

gantt
        dateFormat  YYYY-MM-DD
        title Adding GANTT diagram functionality to mermaid
        section A section
        Completed task            :done,    des1, 2014-01-06,2014-01-08
        Active task               :active,  des2, 2014-01-09, 3d
        Future task               :         des3, after des2, 5d
        Future task2               :         des4, after des3, 5d
        section Critical tasks
        Completed task in the critical line :crit, done, 2014-01-06,24h
        Implement parser and jison          :crit, done, after des1, 2d
        Create tests for parser             :crit, active, 3d
        Future task in critical line        :crit, 5d
        Create tests for renderer           :2d
        Add to mermaid                      :1d

やっぱ駄目かー

今だと簡単な図を作るのにも、画像として挿入する必要があるので、本文は更新されてるのに図だけ古いままなんて状況になることが多くて困ってるので、ぜひgithubやbitbucketにも追従してもらいたいところです。 ついでに、はてなの脚注機能(はてな記法と同じく二重括弧でくくると中の分が脚注として表示される機能)も便利なので、他のサイトでもサポートしてくれると有り難いなー*2

*1:各グラフはmermaidの公式ページにあるサンプルです

*2:Quiitaの脚注が使い難いのでアカウントは作ったけど、ついついはてなに書いちゃうんですよね・・・

タブレットPCスタンド

去年購入したASUSタブレットPC(surfaceっぽいやつ)がスタンドを立ててキーボードを手前に置くと画面の下の方が隠れて見えなくなるので、何種類か上方に持ち上げて保持するタイプのタブレットスタンドを使ってきたんですが、どれも使いはじめて1、2ヶ月もすると歪んでしまってディスプレイが水平を保てなくなってしまいました・・・

結構気持ち悪いのでどうしようかと悩んでたんですが、ふと思い立ってカメラ用の三脚と三脚にタブレットを保持する台を導入してみました。

サンコー カメラ三脚用タブレットデスク CLHCMAN3

サンコー カメラ三脚用タブレットデスク CLHCMAN3

Manfrotto ミニ三脚 PIXI ブラック MTPIXI-B カメラ用

Manfrotto ミニ三脚 PIXI ブラック MTPIXI-B カメラ用

このマンフロットの三脚についてる雲台が、あまり下を向けられないので、雲台on雲台とかいう間抜けな状態にはなってますが、一応満足できるスタンドが完成しました。

1/4インチネジのメス同士を90度くらいで固定できれば良い話なので、アルミブロックを買ってきてネジを二本埋め込んでから頭を飛ばせば良いのかなーとか考えてたんですが、既にそれっぽい製品があるんですね・・・

panproduct.com

これと接合用のネジを2本買えばビシっと決まるけど総額1万円を越える高級タブレットスタンドになりそうですo...rz

f:id:n_so5:20180307152726j:plainf:id:n_so5:20180307152743j:plain

【結論】 タブレットは机の上に直置きでキーボードを膝の上に置けば良いんじゃないか?

git mergeで特定のファイルを取り込む

別のブランチで修正したファイルの一部だけを取り込む必要があってぐぐってたんですが、なかなか同じシチュエーションの人が居ないようなので作業の記録を残しときます。

git mergeに特定のファイルを指定するようなオプションは無いので、ちょっと面倒ですがmerge -> 不要なファイルをreset ->commitという流れになります。

実際に使うコマンドはこんな感じです。

> git merge --no-commit -Xtheirs {mergeしたいブランチ名}
> git reset HEAD {mergeしたくないファイル名}
> git checkout {mergeしたくないファイル名}
> git commit

ぐぐるとcherry-pickでできるよ!みたいなことが書かれてるページもあったけど、cherry-pickはあくまで個別のコミットを適用するだけなので、mergeするブランチ側で同じコミットに必要なファイルと不要なファイルが混ざっていたり、複数のコミットでmergeしたいファイルを編集してると難しいです。*1

mergeするファイルが少なければ、こちらでやられているようにmergeするブランチ側でパッチを作って適用というのも一つの手だとは思います。今回は、mergeするファイルが大量&バイナリファイルがかなり含まれていたので使いませんでしたが。*2

blog.bgbgbg.net

*1:1回mergeされる側のブランチでコミットを分割してやればできそうだけど、面倒そう・・・

*2:merge commitの履歴が残らないというのも人によっては気になるかもしれませんね

node.jsのfs.Statsからファイルのパーミッションを読み取る

node.jsのfs.stat, fs.lstat, fs.fstatが返すfs.Statsクラスには、その名もずばりのmodeというpropertyがあるのですが、この値からファイルのパーミッションを直接知る手段が標準では用意されていません。1 まーそんなに難しい話ではないので、頭の体操がてらちょちょいとコードを書いてみましょう。

まず、fs.Stats.modeの値の正体ですが、これはそのまんまstat(), lstat(), fstat()が返すstat構造体のst_modeフィールドの値と同じようなので、下位の(8進数で)3桁をマスクしてやれば通常のパーミッションが値として取得できます。 javascriptでのbit演算はCと同じで、&がbit-wise ANDなのでmode & maskとすればOKです。

developer.mozilla.org

ただし、modeの値は10進数だけど、我々が普段使っているumask値は8進数なので、この変換を行う必要があります。 といっても、parseInt関数を使えばOKでparseInt(777,8)で下位3桁のmaskが作れます。 もしスティッキービットとかも必要だったら7777にすればOKです。

developer.mozilla.org

これで、ファイルのパーミッションが10進数の整数値として取得できたので、最後に8進数の表現に直します。 こちらも、javascriptの標準の範囲内でできてしまって、toString()に引数として8を渡してあげればOKです。

developer.mozilla.org

この3つを組み合わせて、カレントディレクトリのファイルのパーミッションを8進数で表示するプログラムを作るとこんな感じになります。

const {promisify} = require('util');
const fs = require('fs');

async function getFileMode(filename){
  let stats = await promisify(fs.stat)(filename);
  return (stats.mode & parseInt(777, 8)).toString(8);
}

async function main(){
  let files = await promisify(fs.readdir)('./');
  files.forEach(async (file)=>{
    console.log(file, await getFileMode(file));
  });
}

main();

テスト結果

$ ls -l .
total 8
---xrwxrwx  1 so5  staff    0 12 13 23:06 file177
--w-rwxrwx  1 so5  staff    0 12 13 23:07 file277
--wxrwxrwx  1 so5  staff    0 12 13 23:07 file377
-r--rwxrwx  1 so5  staff    0 12 13 23:06 file477
-r-xrwxrwx  1 so5  staff    0 12 13 23:08 file577
-rw-rwxrwx  1 so5  staff    0 12 13 23:07 file677
-rwx--xrwx  1 so5  staff    0 12 13 23:11 file717
-rwx-w-rwx  1 so5  staff    0 12 13 23:11 file727
-rwx-wxrwx  1 so5  staff    0 12 13 23:11 file737
-rwxr--rwx  1 so5  staff    0 12 13 23:11 file747
-rwxr-xrwx  1 so5  staff    0 12 13 23:11 file757
-rwxrw-rwx  1 so5  staff    0 12 13 23:11 file767
-rwxrwx--x  1 so5  staff    0 12 13 23:11 file771
-rwxrwx-w-  1 so5  staff    0 12 13 23:11 file772
-rwxrwx-wx  1 so5  staff    0 12 13 23:11 file773
-rwxrwxr--  1 so5  staff    0 12 13 23:11 file774
-rwxrwxr-x  1 so5  staff    0 12 13 23:11 file775
-rwxrwxrw-  1 so5  staff    0 12 13 23:11 file776
-rwxrwxrwx  1 so5  staff    0 12 13 23:11 file777
-rw-r--r--  1 so5  staff  378 12 13 23:35 test.js
$ node test.js 
file177 177
file277 277
file377 377
file477 477
file577 577
file677 677
file717 717
file727 727
file737 737
file747 747
file757 757
file767 767
file771 771
file772 772
file773 773
file774 774
file775 775
file776 776
file777 777
test.js 644

10進数->8進数(もちろん2進数や16進数も)の変換にtoStringを使うっていうのは違和感がありますが、JSだと10進数以外の整数は文字列として表すしかないから当然といえば当然かもしれませんが。


  1. fs.accessの方は引数にパーミッションの条件を指定できるので、ファイルのパーミッションが見たけりゃstat系じゃなくてこっちを使ってねってことかと思いますが。

echo

みんな大好きなecho(1)ですが、最近Amazonから物理デバイスとして発売されたようですね。



しょうもないボケはさておき、Amazon Echoの発表と合わせてMusic Unlimitedという新サービスを開始するなど、スマートスピーカーの売り込みを頑張ってるようですね。
pc.watch.impress.co.jp

個人的には、ここ数年はAmazon Prime会員で特に最近はほとんど音楽はkindle FireからPrime musicの音楽を聴くばっかりという生活なので、echoはこのスピーカー機能だけでも買いたいんですが、ひとつ重大な問題があります。

amazon musicの検索機能がクラシック音楽に対して弱すぎる

発表資料のなかに「アレクサ、スピッツをかけて」なんてのが載ってましたが、クラシック音楽でこれをやるとたぶん使いものになりません。
というのも、曲名も人名も長すぎるのでメジャーな曲やら作曲者の場合こんな感じで俗称というか略語がついてるんですが、amazon musicで検索してもまったくひっかからないんです。
クラシック音楽の曲名の俗称の一覧 - Wikipedia

例えば、チャイコフスキーが作曲したヴァイオリン協奏曲は通常「チャイコン」と呼ばれますがこれで検索するとまったくひっかかりません。
f:id:n_so5:20171109095455p:plain

それどころか、チャイコフスキーで検索するのとTchaikovskyで検索するのでは結果が違うというていたらくです。
f:id:n_so5:20171109095549p:plain
f:id:n_so5:20171109095553p:plain

また、ストラヴィンスキーが作曲した「春の祭典」という曲は「ハルサイ」と呼ばれてますが、これで検索するとナクソスから出てるネタアルバム「ハルサイとか聴いてるヤバい奴はクラスで俺だけ。」しかひっかかりません。
f:id:n_so5:20171109100516p:plain


amazon echo(に限らずスマートスピーカー)と音楽再生サービスの組合せには大いに期待してるんですが、このままでは「年末に第九でも聴くかー」という状況で「アレクサ、ベートーベンの交響曲第9番をかけて」と言わなくちゃならんようなコレジャナイ未来が待ってそうなので、今朝からひたすらAlexa Skills Kitのドキュメントを読み漁ってます。

https://developer.amazon.com/ja/alexa-skills-kit

音楽再生の要求に対して、検索キーワードを俗称ー>正式名称に変換するパイプを作れれば十分目的は果たしそうなんだけど、そういう機能は無いのかなぁ