ようへいの日々精進XP

よかろうもん

2018 年 10 月 31 日 (水)

ジョギング

  • 自宅から天神交差点まで (40 分弱)
  • 懸垂 x 5

日課

  • おやすみ

気づいたら 10 月も終わった... 今日のトゥウィート

あっという間に福岡マラソンだ.

ちょっと忘れそうになっていたけど, 鹿児島マラソンにも当選した. 入金は 11/15 まで. 忘れずに.

2018 年 10 月 30 日 (火)

ジョギング

  • 山王公園往復
  • 懸垂 x 5

日課

  • (腕立て x 50 + 腹筋 x 50) x 3

夕飯, 今日も鍋

  • 今日も久原のあごだしで鍋

肌の乾燥

  • まだ秋口くらいなのに...
  • 乾燥がひどいのであります

新しい MacBook Air

が発表になっていた.

www.apple.com

へ〜〜〜って感じ.

試しに, メモリ 16GB にしてストレージを 512GB にしたら簡単に 20 万円を超えた...

2018 年 10 月 29 日 (月)

ジョギング

  • 山王公園往復
  • おニューの靴がいい感じ

日課

  • (腕立て x 50 + 腹筋 x 50) x 3

新しいソファが届く

  • 待ちに待ったソファが届いた
  • かなりの存在感を醸し出している

夕飯

  • 久原のあごだしで鍋
  • さすが久原, 上品な感じで〆まで美味しかった

今日のトゥウィート

2018 年 10 月 28 日 (日)

ジョギング

  • 山王公園往復
  • おニューのシューズで走ったけど, やっぱりグリップが違うね〜〜〜
  • 懸垂 5 回 , もう雰囲気でいけるようになったので, そろそろ 10 回を目指していこう

日課

  • おやすみ

正三おじさんとその仲間たちの JAZZ ライブ

  • 去年も招待頂いて, すごく良かったので楽しみにしていた
  • 平均年齢 75 歳のおじいさん達が楽しそうに奏でる姿に元気を頂いた
  • これからも頑張って欲しいけど, 今年でライブは終わりとのこと

2018 年 10 月 27 日 (土)

ジョギング

  • 山王公園往復
  • 懸垂 5 回, 最近は楽に 5 回まではいけるようになった

日課

  • (腕立て x 50 + 腹筋 x 50) x 3

香椎で買い物

  • 奥さんの通院のついでに諸々
  • ランニング用のシューズがヘタっていたので購入, 来月の福岡マラソンの準備も
  • 久しぶりのダイレックスで食材の買い込み

引っ越しその後...

  • 奥さんがいろいろと頑張って部屋が片付きつつある
  • ありがとう

夕飯

  • 久しぶりの鍋
  • 〆のおじやまでお腹いっぱい

液晶モニタ

  • 今, 利用している液晶モニタは FullHD で, もう少し解像度の高いモニタを 1 枚で運用したいと考えている (机の周りを出来るだけさっぱりさせたい為)
  • 4K までは不要で, 2560×1440 という解像度 (WQHD) の液晶モニタがあるらしいので, それを物色できればなあと考えている

気になる書籍

上司に「いいよ〜」とおすすめされた.

www.oreilly.co.jp

目次を見ると, Go で書かれたサンプルプログラムを動かしながら HTTP プロトコルや RESTful API の実装について学べるようだ. 是非, 読みたい.

あと, これも読みたい.

gihyo.jp

amiCtrl をちょっとバージョンアップした

tl;dr

どうも, かっぱです.

世界で 100 万人の方々からご愛顧頂きたい EC2 AMI を作ったりする「俺のツールズ」シリーズの甘えん坊 amiCtrl をちょっとバージョンアップしました.

github.com

amiCtrl を利用することで, AMI を作ったり, 削除したり, 自分のアカウントに登録されている AMI 一覧を取得することが可能です. 詳しい使い方は README をご一読下さい.

更新内容

アカウントに登録されている AMI 一覧を取得

今までなんで無かったんだろうと過去の自分を問い詰めたい気分ですが, アカウントに登録されている AMI 一覧を取得出来ます. 以下のような感じです.

$ amiCtrl
+--------------------------------------------+--------------+-----------+------------------------+
|                  AMI NAME                  |    AMI ID    |   STATE   |      SNAPSHOT ID       |
+--------------------------------------------+--------------+-----------+------------------------+
| tokito-ami2                                | ami-1234567a | available | snap-0000000a8de111a2a |
|                                            |              |           | snap-0000000a8de111a2b |
+--------------------------------------------+--------------+-----------+------------------------+
| tokito-ami                                 | ami-1234567b | available | snap-0000000a8de111a2c |
+--------------------------------------------+--------------+           +------------------------+
| suzuki-ami2                                | ami-1234567c |           | snap-0000000a8de111a2d |
+--------------------------------------------+--------------+-----------+------------------------+

登録の件数が多いとそれなりの出力行数となります. 現在のところ AMI のオーナー指定は self 固定となっていますが, 将来的には任意のオーナーを指定可能にし, フィルタで絞り込むような既存の AWS CLI 同等の機能を実装する予定です.

JSON 出力

AMI の一覧について, テーブル出力以外に JSON 出力が出来るようになりました. 以下のような感じです.

$ amiCtrl -json
{
  "amis": [
    {
      "ami_name": "tokito-ami2",
      "ami_id": "ami-1234567a",
      "instance_type": "available",
      "snapshot_ids": [
        "snap-0000000a8de111a2a",
        "snap-0000000a8de111a2b"
      ]
    },
    {
      "ami_name": "tokito-ami",
      "ami_id": "ami-1234567b",
      "instance_type": "available",
      "snapshot_ids": [
        "snap-0000000a8de111a2c"
      ]
    },
    {
      "ami_name": "suzuki-ami2",
      "ami_id": "ami-1234567c",
      "instance_type": "available",
      "snapshot_ids": [
        "snap-0000000a8de111a2d"
      ]
    }
  ]
}

JSON 出力は, 他のツールと組み合わせた利用を想定しています. 例えば, 不要な AMI をまるっと削除したい場合, 以下のように使えるんじゃないかなーと思っています.

for id in $(amiCtrl -json | jq -r .amis[].ami_id)
do
  amiCtrl -delete -ami=${id} -batch
done

-delete オプションに -batch オプションを追加することで, 削除確認の出力をスキップすることが可能となります.

# -batch オプションを指定しない場合
$ amiCtrl -delete -ami=ami-e4985d82
+------------+--------------+-----------+------------------------+
|  AMI NAME  |    AMI ID    |   STATE   |      SNAPSHOT ID       |
+------------+--------------+-----------+------------------------+
| suzuki-ami | ami-1234567e | available | snap-0000000a8de111a2d |
+------------+--------------+-----------+------------------------+
上記の AMI を削除しますか?(y/n): n
処理を停止します.

-batch オプションを付与する場合, 問答無用に AMI は削除されてしまいますので注意して利用しましょう.

テストの追加

ユニットテストではありませんが, コマンドの実行結果等をテストする小さなテストを追加しました. 以下のように bytes パッケージを利用してコマンドラインの出力結果をパースしています.

import (
    "bytes"
    "os/exec"
    _ "fmt"
    "strings"
    _ "time"
    "testing"
)

func TestVersionFlag(t *testing.T) {
    cmd := exec.Command("gom", "run", "amiCtrl.go", "-version")
    stdout := new(bytes.Buffer)
    cmd.Stdout = stdout

    _ = cmd.Run()

    if ! strings.Contains(stdout.String(), AppVersion) {
        t.Fatal("Failed Test")
    }
}

exec.Command にダラダラとコマンドを並べるのは見栄えが良くないと思ったので, コマンド自体はシンプルなシェルスクリプトに書いています. 以下のような感じです.

$ cat tests/test_stdout_list.sh
INSTANCE_ID=$(aws --profile=dummy_profile --region=us-east-1 --endpoint=http://192.168.0.100:5000 \
    ec2 run-instances \
      --image-id=ami-1a2b3c4d \
      --count=1 \
      --instance-type=c3.large \
      --key-name=MyKeyPair \
      --security-groups=MySecurityGroup \
      --query=Instances[].InstanceId --output=text)

aws --profile=dummy_profile --region=us-east-1 --endpoint=http://192.168.0.100:5000 \
  ec2 create-image \
    --instance-id=$(echo ${INSTANCE_ID} | tr -d \\r) \
    --name=test-image --output=text

gom run amiCtrl.go -profile=dummy_profile -region=us-east-1 -endpoint=http://192.168.0.100:5000

尚, テストは docker-compose で環境を構築, 実行し, Travis CI でテストを実行するようにしています.

$ docker-compose exec amictrl make test
=== RUN   TestVersionFlag
--- PASS: TestVersionFlag (1.11s)
=== RUN   TestStdoutList
--- PASS: TestStdoutList (2.32s)
=== RUN   TestStdoutCreate
--- PASS: TestStdoutCreate (1.69s)
=== RUN   TestStdoutCreateError
--- PASS: TestStdoutCreateError (1.67s)
=== RUN   TestStdoutDelete
--- PASS: TestStdoutDelete (2.25s)
=== RUN   TestStdoutDeleteError
--- PASS: TestStdoutDeleteError (2.25s)
=== RUN   TestStdoutDeleteNo
--- PASS: TestStdoutDeleteNo (2.33s)
=== RUN   TestStdoutState
--- PASS: TestStdoutState (2.80s)
=== RUN   TestStdoutJson
--- PASS: TestStdoutJson (2.80s)
PASS
ok      amiCtrl 19.219s

.travis.yml は以下の通りです.

sudo: required
matrix:
  include:
  - name: "Go 1.11"
    env: TEST_TARGET=amictrl
services:
  - docker
before_install:
  - docker-compose build
  - docker-compose up -d
install:
before_script:
  - docker-compose exec amictrl make depend
script:
  - docker-compose exec amictrl make test
after_script:
notifications:

こんな感じでテストが走っています.

ということで

この Infrastructure as Code な時代にこんな CLI ツールの存在価値について悩んでいますが, ツールをいじくることで AWSAPI や Go の書き方について学びになっているので, 引き続きこれらのツールを書いていこうと思いますーε≡≡ヘ( ´Д`)ノ

もし, よろしければ amiCtrl をご利用頂きましてフィードバック等を頂けると嬉しいでございます.

2018 年 10 月 26 日 (金)

ジョギング

  • 山王公園往復
  • 懸垂 5 回

日課

  • おやすみ

夕飯

  • パスタを作る
  • サニーで買ったカツオのタタキが美味しかった

最近

  • 夜になると眠気がひどい...
  • なんとか歯磨きまでは出来るけど, ストンと落ちるように寝てしまっている...

ギョームにてすぐに日本時間が欲しい時に僕がやること

tl;dr

AWS がメールで送ってくる EC2 等のメンテナンス通知. メンテナンスの日時が UTC で表記されているので, その時間を日本時間 (JST) で欲しい時に僕がやっていることをメモっておきます.

何やるか

まずは irb を起動します.

$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
$ irb -v
irb 0.9.6(09/06/30)
$ irb

そして, おもむろに time ライブラリを require します.

irb(main):001:0> require 'time'
=> true

そして, Time クラス parse メソッドの引数に UTC 時間を付与し, さらに getlocal メソッドで日本時間を得ます.

irb(main):002:0> Time.parse('2018-11-08T20:00:00.000Z').getlocal
=> 2018-11-09 05:00:00 +0900

getlocal は以下のドキュメントを参考にさせて頂きました.

docs.ruby-lang.org

上記の例だと, UTC 時間で 2018 年 11 月 8 日の 20 時は日本時間で 2018 年 11 月 9 日の 5 時ということになります.

また, Object クラスをオープンクラスして, 以下のようなメソッドを差し込むと...

class Object
  def to_local_time
    require 'time'
    Time.parse(self).getlocal
  end
end

以下のように書くことが出来る.

irb(main):001:0> class Object
irb(main):002:1>   def to_local_time
irb(main):003:2>     require 'time'
irb(main):004:2>     Time.parse(self).getlocal
irb(main):005:2>   end
irb(main):006:1> end
=> :to_local_time
irb(main):007:0> '2018-11-08T20:00:00.000Z'.to_local_time
=> 2018-11-09 05:00:00 +0900

Ruby のこういうところ (オレオレメソッドを Ruby 本体に追加出来る) が好きだな〜.

同じようなことを python でも

検算という意味で python でも同じようなことをやってみます.

$ python -V
Python 3.6.5
$ python
>>> from pytz import timezone
>>> from dateutil import parser
>>> u = '2018-11-08T20:00:00.000Z'
>>> j = parser.parse(u).astimezone(timezone('Asia/Tokyo'))
>>> print(j)
2018-11-09 05:00:00+09:00

前述の Ruby で試した場合と同じ結果を得ることが出来ました.

尚, 本検算については, 以下の記事を参考にさせて頂きました. ありがとうございます.

qiita.com

以上

メモでした.

2018 年 10 月 25 日 (木)

ジョギング

  • 山王公園往復
  • 懸垂 5 回

日課

  • おやすみ

JAWS-UG 福岡もくもく会

  • 忘年会の企画について議論する
  • 多くの人の意見をまとめて事を進めるというのは大変だよなあ

夕飯

  • JAWS-UG 福岡もくもく会の帰りに「とんとん」で一杯
  • 砂肝の唐揚げと地鶏の叩き, ああ, これで十分的な感じ

今日のトゥウィート

ここ最近, ↑ですよね〜と思っていながら言語化出来ていなかったこと. 抽象化されているからこそ, そこに包まれている本質を見抜ける力や技を身につけるべきだと思っているけど, そもそも自分がそんなステージにいないのでアレですよね...

道下さん, 以前, 福岡マラソンで颯爽と抜かれた印象が強く残っていて, 奥さんの次くらいに笑顔が素敵なので, もう, これからはライバルとして負けないように走りたいと思っているし, ずっと走り続けて欲しい. ずっと応援していきたと思う.