SSH_CONFIGを使用してgitのリポジトリURLを短縮する
gitのリポジトリにSSHでアクセスするときに限るがSSH_CONFIG
を使用することでホスト名を簡略化でき、リポジトリURLを短縮することができる。
SSH_CONFIGでの設定
例えば以下のようにする。
Host gh User git Hostname github.com
cloneする
git@github.com:kawaken/repositry.git
短縮して、
gh:kawaken/repositry.git
となる。さらに最後の.git
は無くてもいいので、最終的にコマンドは以下のようになる。
git clone gh:kawaken/repositry
ちょっとだけ便利。
ちなみにSVNでもこのテクニックは使える。
DynamoDB Local(Amazon公式)のDockerイメージを使う
先日の8月22日に、Amazonから公式にDynamoDBのDockerイメージが公開された。
ググっても野良のイメージしか出てこないのでまだあまり認知されてないっぽい。
ちょうどDynamoDB Localを利用していたところだったので、早速試してみた。
とりあえず立ち上げる
$ docker run --rm amazon/dymamodb-local Initializing DynamoDB Local with the following configuration: Port: 8000 InMemory: true DbPath: null SharedDb: false shouldDelayTransientStatuses: false CorsParams: *
jarで配布されていたものと同じっぽい。
オプションを使用したい
とりあえず開発時のテストとはいえ、データを永続化したい。
jar版では起動時の引数で設定することができたので、Dockerイメージにおいても引数を渡せれば設定できるはず。 Dockerfileは見当たらないので、とりあえずinspectしてみる。
$ docker inspect amazon/dynamodb-local:latest (snip) "Config": { "Hostname": "", "Domainname": "", "User": "dynamodblocal", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "ExposedPorts": { "8000/tcp": {} }, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "-jar", "DynamoDBLocal.jar", "-inMemory" ], "ArgsEscaped": true, "Image": "sha256:6901b80d033a1d94e1283711be031f2657d90edf0768118bb22c952feba780bd", "Volumes": null, "WorkingDir": "/home/dynamodblocal", "Entrypoint": [ "java" ], "OnBuild": null, "Labels": { "aws.java.sdk.version": "1.11.119" } }, (snip)
- Entrypoint: java
- Cmd: -jar DynamoDBLocal.jar -inMemory
となっているので、docker runの際に javaのオプションとなる部分をすべて指定することで設定を変えられそう。
データを永続化する
dbPathでパスを指定することができるので、Volumeを指定してそこにデータを置くようにする。 ひとまずフォアグラウンドで起動する。
$ docker run --rm -p 8000:8000 -v ~/dynamodb-data:/home/dynamodblocal/data \ amazon/dynamodb-local -jar DynamoDBLocal.jar -dbPath /home/dynamodblocal/data Initializing DynamoDB Local with the following configuration: Port: 8000 InMemory: false DbPath: /home/dynamodblocal/data SharedDb: false shouldDelayTransientStatuses: false CorsParams: *
別のターミナルからawsコマンドを使用し、テーブルを作成してみる。
$ aws dynamodb create-table --table-name Clients \ --attribute-definitions AttributeName=id,AttributeType=S \ --key-schema AttributeName=id,KeyType=HASH \ --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 \ --endpoint-url http://localhost:8000 { "TableDescription": { "TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/Clients", (snip) } }
一覧で取得できるか確認。
$ aws dynamodb list-tables --endpoint-url http://localhost:8000 { "TableNames": [ "Clients" ] }
ホスト側のデータ保存先に指定した場所を確認してみる。
$ ls ~/dynamodb-data AKIAIOSFODNN7EXAMPLE_ap-northeast-1.db
この中にデータが入ってそう。
まとめ
DockerイメージでのDynamoDB Localの動作確認ができた。
Javaの環境を用意しなくても動作ができるので、気楽に利用できるようになった。ありがたい。
rmdirの使い方
rmdir
は対象のディレクトリが空の時だけ削除できる。そのため、中身は問わずディレクトリ消したいときは、rm -fr
を使用していた。Linuxを使い始めてから長いことそうしていて、rmdir
を使うことはほとんどなかった。
確実に空のディレクトリだけを削除できる
この1年くらいコードの整理をする機会が増えたため、確実に空のディレクトリだけ削除したいということが増えた。最初はfind
などで中身が空か確認してから削除するようにしていた。しかしfind -> rm -fr
というのも手間なので、rmdir
を使用するようになった。
rm -r
でいいのでは?とも思ったが、rm -fr
とついつい誤って打ってしまうことがありコマンド自体を使い分けることにした。
rmdir
の対象が空ではない場合、
rmdir
で失敗する- 中身を確認する
- 残っているファイルを処理する(だいたい
rm
する) - 改めて
rmdir
を実行
というフローを踏むようになった。たまに本当に消してはいけない何かがあることがあり、誤って消してしまうような致命的なミスは避けられるようになった。
ちょっと便利なオプション
rmdir
にも当然オプションがあり、とりあえず空のディレクトリをガサッと消すぞ!みたいなときに使える。
--ignore-fail-on-non-empty
: 対象が空のディレクトリではなく、削除できなかった時にfailしない。forやxargsと組み合わせて削除していく際に、このオプションを付与したりする。
-p
: 対象のディレクトリの親も削除する。mkdir -p
の逆の動作をする。manには以下のように書いてある。
'rmdir -p a/b/c' is similar to 'rmdir a/b/c a/b a'
とりあえず雑に以下のような使い方をする。
$ find target_dir -type d | xargs rmdir --ignore-fail-on-non-empty -p
あまり嬉しくないのは、どのディレクトリを消したか教えてくれるオプションがないこと。なので、その辺を確認したいときはあらかじめfind
で一覧を残しておく。
あとrmdir
に.
を渡すとrmdir: failed to remove '.': Invalid argument
として怒られる。
おしまい
iPhone/Macで使えるMarkdownエディタを検討する
ブログの執筆を前提にしたエディタを評価してみた。
あるといい機能
- ファイル名を指定せずに書き始めることができる
- 先頭行がタイトルとなる
- メモ一覧でもタイトルが表示される
- iPhone/Macの同期がスムーズにできる
- iPhoneでは、Markdown用のキーボードがあるとよい
- 使用できるマークアップがカスタマイズできるとよい
- 自分の使用頻度の高いものが使いやすい位置にあるとよい
- Macでは、独立した編集/プレビューのモードがある
- Split表示嫌いなんで
- 編集モードであってもヘッダーやリストなどはスタイルが変わるとうれしい
- iPhoneではプレビューが容易だとうれしい
- タグ付けができるとよい
ちなみに、この辺り全部満たしてる感じのやつはなかった。
bear
最終的にこれを使うことにした。iPhone/Macで同期を行う機能は有料で年間1500円。やすっ。
Bear - Notes for iPhone, iPad and Mac
いいところ
- 編集中でもスタイルが変わるのでわかりやすい
- ファイル名を指定せずに書き始めることができる
- データの同期がすごいスムーズ
- 別の端末でアプリを開いた際の待ち時間を感じたことがない
おしいところ
- 逆にプレビューモードがない
- iPhoneでは、HTMLに出力する機能がプレビューの代替として使えるがやや手間
- リストが完全にリストになってしまうので、ちょっとインデントの編集で手間取ることがある
- MacだとTabで変更可能
- 自分が頻繁に使用するマークアップへのアクセスが良くない(iPhone)
- タグ付けできるが、文章内に
#tag
という感じで書かないといけない - TODOというドキュメントの種類があるが、文章中に
- [ ]
を含んでいるだけでは該当しない- タスク数などが簡単に確認できるわけでもない
MWeb
ちょっと同期周りがめんどくさい気がした。ちゃんと試してない。
MWeb - Pro Markdown writing, note taking and static blog generator App - MWeb
いいところ
おしいところ
- ファイル名を指定しないと書き始めることができない
Inkdrop
作者の人、すごいなーと思って試してみた。
Note-taking App with Robust Markdown Editor - Inkdrop
いいところ
- タグ付けとステータスの管理ができる
- Completeとかにするとデフォルトのメモ一覧から表示されない
- TODOが含まれているとカウントされる
- ファイル名指定せずに書き始めることができる
- メモ一覧の情報量と視認性がとてもいい
おしいところ
Mac版の方はすごく良かった。しばらくしたらもっと使いやすくなっているかもしれないので、たまに試してみたい。
Boostnote
会社では使ってるけど、iPhoneアプリが非公開になっているらしく、候補から外れた。
1つ気になるのが、編集モードからフォーカスが外れるとプレービューモードに切り替わってしまうのが好きではなくて、Snippetをもっぱら使用している。
Issueも上がっているけど、しばらく進展してないっぽい。
コンテナのzoneinfoとGoのLocationについて
以前書いたAlpine Linuxで時刻をJSTに設定する(Dockerfile)で、コンテナ内の時刻をJSTとして扱えるようにした。
しかし、以下が気になった。
- コンテナのイメージ作成においてタイムゾーンを変更するような記述を見かけたことがなかった
- もしかしてアンチパターンとかではないかと気になった
- コンテナのタイムゾーンを変更しなくても、アプリ内でJSTとして扱うことはできるので、不要なセットアップではないか
ということでアプリケーション(Go)の方で対処できないか、検証してみた。
結論
結果、以下のような挙動となった。
time.LoadLocation
はコンテナの中に該当するzoneinfoがないと失敗する- Alpine Linuxのデフォルトでは
Asia/Tokyo
などは存在しないため確実に失敗する /etc/localtime
が/usr/share/zoneinfo/Asia/Tokyo
などで上書きされていても、/usr/share/zoneinfo/Asia/Tokyo
自体がないとやはり失敗する
- Alpine Linuxのデフォルトでは
time.FixedLocation
は直接time.Location
を生成するためzoneinfoの有無の影響を受けない
軽量コンテナを使用する際にはUTC
を前提とするか、time.FixedLocation
を使用した方が良さそう。
もしJST
をデフォルトとしたコンテナを作成したかったら、以下のようなDockerfileにすべき。
FROM alpine:latest # インストールしたtzdataは削除しない RUN apk --no-cache add tzdata && \ cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
以下、検証した内容。
Goのプログラム
以下のように4回時刻を出力するようにした。
package main import ( "fmt" "time" ) func main() { t := time.Now() fmt.Println(t) jst, err := time.LoadLocation("Asia/Tokyo") if err != nil { fmt.Println(err) } else { fmt.Println(t.In(jst)) } jst = time.FixedZone("JST", 9*60*60) fmt.Println(t.In(jst)) time.Local = jst fmt.Println(time.Now()) }
表示は以下のようになると予想していた。
time.Now
ではコンテナのタイムゾーンに基づいた時刻表示t.In(jst)
ではJSTの時刻表示がされるtime.LoadLocation
でerrが起きるとは思ってなかった
- 最後の
time.Now
ではJSTの時刻が表示される
バイナリは以下のようにしてtime-test
として出力しておく。
GOOS=linux GOARCH=amd64 go build -o time-test
検証1: zoneinfoを特に設定しない
まずはコンテナを作っとく。Dockerfileは以下の通り。
FROM alpine:latest COPY ["time-test", "/"] CMD [ "/time-test" ]
docker buildして、jst-time-test1というタグにしておく。
docker build -t jst-time-test1 -f Dockerfile1 .
docker runで実行する。
$ docker run --rm jst-time-test1 2018-08-30 00:36:56.4097601 +0000 UTC m=+0.000328601 open /usr/local/Cellar/go/1.9.2/libexec/lib/time/zoneinfo.zip: no such file or directory 2018-08-30 09:36:56.4097601 +0900 JST 2018-08-30 09:36:56.4098805 +0900 JST m=+0.000448301
最初はUTCが出力され、最後はJSTが出力された。しかしtime.LoadLocation
ではエラーが出力された。
open /usr/local/Cellar/go/1.9.2/libexec/lib/time/zoneinfo.zip: no such file or directory
と表示されるのは、time.LoadLocation
の説明にあるとおりで、
The time zone database needed by LoadLocation may not be present on all systems, especially non-Unix systems. LoadLocation looks in the directory or uncompressed zip file named by the ZONEINFO environment variable, if any, then looks in known installation locations on Unix systems, and finally looks in $GOROOT/lib/time/zoneinfo.zip.
最終的に$GOROOT/lib/time/zoneinfo.zip
を参照するということなので、システムのzoneinfoもないし、$GOROOT/lib/time/zoneinfo.zip
もない(GoのSDKは存在しない)ためエラーとなった様子。
検証2: JSTをローカルタイムに設定しzoneinfoを削除した状態
今度はAlpine Linuxで時刻をJSTに設定する(Dockerfile)で設定した環境で、dateコマンドだとJSTが表示される状態になっている。Dockerfileは以下の通り。
FROM alpine:latest RUN apk --no-cache add tzdata && \ cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \ apk del tzdata COPY ["time-test", "/"] CMD [ "/time-test" ]
docker buildする。
docker build -t jst-time-test2 -f Dockerfile2 .
実行する。
$ docker run --rm jst-time-test2 2018-08-30 09:37:09.7907743 +0900 JST m=+0.000254901 open /usr/local/Cellar/go/1.9.2/libexec/lib/time/zoneinfo.zip: no such file or directory 2018-08-30 09:37:09.7907743 +0900 JST 2018-08-30 09:37:09.7908918 +0900 JST m=+0.000372901
最初はJSTが出力され、最後はJSTが出力された。しかしtime.LoadLocation
ではエラーが出力された。
このコンテナでは/etc/localtime
は上書きされているが、zoneinfo(/usr/share/zoneinfo/Asia/Tokyo
)がないから、やはりエラーとなった様子。
検証3: JSTをローカルタイムに設定しzoneinfoを残した状態
検証2の結果から、Dockerfileを以下のように修正した。
FROM alpine:latest # 前回実施していた apk del tzdata を消去 RUN apk --no-cache add tzdata && \ cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime COPY ["time-test", "/"] CMD [ "/time-test" ]
docker buildする。
docker build -t jst-time-test3 -f Dockerfile3 .
実行してみる。
$ docker run --rm jst-time-test3 2018-08-30 09:37:15.3019175 +0900 JST m=+0.000325101 2018-08-30 09:37:15.3019175 +0900 JST 2018-08-30 09:37:15.3019175 +0900 JST 2018-08-30 09:37:15.3020498 +0900 JST m=+0.000457301
今度はうまくいった!やはり参照するzoneinfoがなかったからエラーになっていたのだろう。
time.FixedLocation
を使用した場合にはすべて問題なく実行できたのも確認できた。
終わりに
今回検証した辺りのzoneinfo(tzdata)について詳しくなかったので、勉強になった。
とりあえず今後は
package main import "time" func init() { time.Local = time.FixedZone("JST", 9*60*60) }
としておくようにしよう。
Alpine Linuxで時刻をJSTに設定する(Dockerfile)
公式の手順があるのでそれを参考にした。
Setting the timezone - Alpine Linux
Dockerfileには以下のように記述した。
FROM alpine:latest RUN apk --no-cache add tzdata && \ cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \ apk del tzdata
公式の手順に従って/etc/timezone
を設定するとGMTになってしまったので、それは設定しないようにした。
作ったイメージでdateを実行して確認する。
$ docker build -t jst-alpine . (snip) $ docker run --rm jst-alpine date Tue Aug 28 23:07:21 JST 2018 $ docker run --rm alpine date Tue Aug 28 14:07:31 UTC 2018
上手くいった。JSTと表示されている。
というか、そもそもアプリケーション側でlocaltimeがJSTだってのを前提にするのが良くない気がする(今までそうしてたけど)。今度検証してみよう。
「入門 Kubernetes」を読んだ
- 作者: Kelsey Hightower,Brendan Burns,Joe Beda,松浦隼人
- 出版社/メーカー: オライリージャパン
- 発売日: 2018/03/22
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
k8sについてちゃんと勉強したかったので読んだ。
k8sをやるにあたって知っておくべき最低限のことが書いてあって、それを実際に動かしながら確認していくスタイル。著者の執筆時点から変わっていることについて訳注が入っているのだけれど、それもさらに変わっているところもあった。
それだけ進化が速いってことかな。
コンテナ化されたアプリケーションを作る方は楽になりそうだけど、k8s自体の運用は大変そうだなぁとも思った。まだプロダクションでやってないんで、わからんけど。
Docker/Kubernetes辺りはキャッチアップできてなかったところなので、他にも新しい出るみたいだし、そっちも読んでみたい。
- 作者: 山田明憲
- 出版社/メーカー: 技術評論社
- 発売日: 2018/08/25
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る