その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

req_mirror書いた

req_mirrorというサーバアプリケーションを書いた.受け取ったHTTP requestをJSONにserializeして,responseに詰めて返してくれるというやつ.つまりHTTP requestをおうむ返しにしてくれる雰囲気です.鏡的な挙動なのでreq_mirrorという名前にした次第.

github.com

Exampleのところにも書いているのだけれど,要はこういう動き方をします (localhost:22222でreq_mirror serverが立ち上がっている前提).

$ curl -s -XPOST -F "foo=bar" -F "buz=qux" 127.0.0.1:22222/hoge/fuga | jq .
{
  "Method": "POST",
  "URL": {
    "Scheme": "",
    "Opaque": "",
    "User": null,
    "Host": "",
    "Path": "/hoge/fuga",
    "RawPath": "",
    "ForceQuery": false,
    "RawQuery": "",
    "Fragment": ""
  },
  "Proto": "HTTP/1.1",
  "Header": {
    "Accept": [
      "*/*"
    ],
    "Content-Length": [
      "236"
    ],
    "Content-Type": [
      "multipart/form-data; boundary=------------------------74755673fc9beca6"
    ],
    "Expect": [
      "100-continue"
    ],
    "User-Agent": [
      "curl/7.43.0"
    ]
  },
  "Body": "--------------------------74755673fc9beca6\r\nContent-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n--------------------------74755673fc9beca6\r\nContent-Disposition: form-data; name=\"buz\"\r\n\r\nqux\r\n--------------------------74755673fc9beca6--\r\n",
  "TransferEncoding": null,
  "Host": "127.0.0.1:22222"
}

はじめて使うHTTP Clientの挙動を確かめながらコード書く場合とかに地味に便利.あとは自作のHTTP Clientのテストをする時とかに威力を発揮します (発揮している).

まあコード自体はめちゃめちゃシンプルというか特になにもやっていないんですが,あると便利だったので外に置いた次第.なおhttp.Requestをそのままjson.Marshalに投げ込んだら処理系に怒られたという心温まるエピソードが開発中にはありました.
以上です.

PHPでテストに使うための空きポートを取ってくる

kazuhoさんのこの記事と同じことがPHPでも出来る.

d.hatena.ne.jp

<?php
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sock, '127.0.0.1', 0); // localhostのport 0をbindする
socket_getsockname($sock, $address, $port); // ここの$portに取得した空きポートが入ってくる
socket_close($sock); // closeしないともちろんalready bindが出るので閉じておく

以上です.元記事にもあるように競合する可能性がありますが,テスト用途だったらなんとかなるでしょう.

最近の社内Wikiの書き出し

最近,社内Wiki書く時にその記事の頭に「この記事で分かること」というセクションを持ってくるようにしている.こんな感じ.

f:id:moznion:20161118190135p:plain

wikiのページを開いた時に真っ先に「どういう情報が得られるか」が書いてあると,取捨選択を早い段階から行えるので調べ物のスピードが上がって良いような気がしている.
あと所属している組織ではConfluenceを使っていて,Confluenceの検索機能に引っかかるような (引っかけやすいような) ワードを「この記事で分かること」に含めるように心がけている.
地味に便利になりつつある気がしている.

[追記]
そう言えばConfluenceの検索結果は「タイトル」と「サマリ」が出るんだけど,冒頭にこういう情報を書いておくとそれがサマリ部分に表示されるから,検索結果一覧の段階から情報の取捨選択できて便利というのもあった.

golangで書いたツールをCircleCI上でビルドしてその成果物をGitHub Releasesにリリースする

表題の通り.いくらかポイントがあったのでメモとして記す.

基本的にこの記事の内容を真似した.

medium.com

あらかじめ,CircleCIの側の設定でGITHUB_TOKENという環境変数を登録しておく.なおGitHubのPersonal access tokenにはrepoのpermissionを付与しておく.

とは言えこれでは動かない.理由はghr (ghrについてはこちら: 高速に自作パッケージをGithubにリリースするghrというツールをつくった | SOTA) がcontextに依存しているからで,contextはgo 1.7以降でないと利用できない.しかしながらCircleCIのgolang環境は1.6系が使える内の最新なので *1 このままではghrをgo getすることが出来ない.
というわけでCircleCI上でgo 1.7を使うようにしましょう,ということでそういうconfigをcircle.ymlに書く.基本的にこのgistの真似.
しかしこのgistにはタイポがあってそのままでは動かない.ので以下のようにする.

machine:
  environment:
    GODIST: "go1.7.3.linux-amd64.tar.gz"
  post:
    - mkdir -p downloads
    - test -e downloads/$GODIST || curl -o downloads/$GODIST https://storage.googleapis.com/golang/$GODIST
    - sudo rm -rf /usr/local/go
    - sudo tar -C /usr/local -xzf downloads/$GODIST

こうしておくとgo 1.7.3がビルド時に利用されるようになる.

そして以下のようなdeploymentセクションを書く.オリジナルの記事ではmasterにpushする度にGitHub Releasesにアップロードされてしまうので,git tagがpushされた時にだけリリース処理が走るようにする (deployment.release.tagの部分でそうしている).

deployment:
  release:
    tag: /[0-9]+\.[0-9]+\.[0-9]+/
    commands:
    - go get github.com/tcnksm/ghr
    - make clean
    - make VERSION=`git describe --tags | perl -anlE 'm/\A([^\-]+)-?/; print $1'`
    - rm bin/.gitkeep
    - ghr -t $GITHUB_TOKEN -u $CIRCLE_PROJECT_USERNAME -r $CIRCLE_PROJECT_REPONAME --replace `git describe --tags | perl -anlE 'm/\A([^\-]+)-?/; print $1'` bin/

その他の細々した差としては,ghrのオプション部分で--replace `git describe --tags`として渡されている部分を--replace `git describe --tags | perl -anlE 'm/\A([^\-]+)-?/; print $1'`というperlワンライナーを噛ませた形に書き換えている.git describe --tagsを実行すると{タグ名}-{ハッシュ}という結果が出てくる場合があるので,タグ名以降の内容を落とすためにそうしている.
あとは.gitkeepがアップロード元のディレクトリに含まれているとghrのアップロード時に失敗する (そんなものアップロードするな,みたいなエラーが出る) のであらかじめ消しておくという感じ.
なおビルド自体はmakeコマンドを叩くだけでglide installからクロスコンパイルまでやるという感じにしている (Makefileはこんな感じ
https://github.com/moznion/linenotcat/blob/4349058d9557d49e1f2fc9a23ebeb79e2279f81d/Makefile).

最終的なcircle.ymlとしては以下のような感じ.

machine:
  environment:
    GODIST: "go1.7.3.linux-amd64.tar.gz"
  post:
    - mkdir -p downloads
    - test -e downloads/$GODIST || curl -o downloads/$GODIST https://storage.googleapis.com/golang/$GODIST
    - sudo rm -rf /usr/local/go
    - sudo tar -C /usr/local -xzf downloads/$GODIST
deployment:
  release:
    tag: /[0-9]+\.[0-9]+\.[0-9]+/
    commands:
    - go get github.com/tcnksm/ghr
    - make clean
    - make VERSION=`git describe --tags | perl -anlE 'm/\A([^\-]+)-?/; print $1'`
    - rm bin/.gitkeep
    - ghr -t $GITHUB_TOKEN -u $CIRCLE_PROJECT_USERNAME -r $CIRCLE_PROJECT_REPONAME --replace `git describe --tags | perl -anlE 'm/\A([^\-]+)-?/; print $1'` bin/

これでtagをpushしたら自動的にGitHub Releasesにビルド成果物がリリースされるようになった.めでたしめでたし.それはそうとghr便利ですね.

[追記]

確かに!!!! ghrのバイナリダウンロードしてくれば良いですね.

linenotcatをhomebrewでインストール出来るようにした

この前書いたlinenotcatをhomebrew経由でインストール出来るようにしました.そうすると便利だと思ったからです.
linenotcatはこんなの.

要はコマンドラインからLINE Notifyにメッセージを投げつけられるツールです.

もともとはGitHub Releasesにビルド済みバイナリをポンと置いていたのですが,それをbrewで引っ張ってこれるようにしましたという話.
こんな感じでインストールが出来るようになって楽ちん.

$ brew tap moznion/homebrew-linenotcat
$ brew install linenotcat

brewで公開するのははじめてやったのですが,案外手軽にできて良かったです.

こんな感じのリポジトリを作ってFormulaを書くだけでいける.
urlGitHub Releasesに置いてあるビルド済みバイナリのURLを指定するとそのバイナリがダウンロードされてきて,それをmvでいい感じのファイル名にrenameして,bin.installでパスが通ってる所にそのバイナリに対するsymlinkを張る,という感じ.
こうすることで,クライアント側でgo buildとかを走らせて各自コンパイルしてもらう必要なく,ビルド済みバイナリを配布するだけで即利用可能になって便利!!

という感じでした.ご利用下さいませ.

「Open Beer Serverの理論とその実装」というタイトルでbuilderscon tokyo 2016にて発表します

builderscon.io

で表題の通り発表します.

builderscon.io

内容としては物理のビールサーバをイチから組み立てて,更にそのビールサーバにHTTPを喋らせるという何を言ってるんだかよくわからない感じですが当方至って真剣です.
ビールサーバってどうやって動いてるの? ビール樽の構造ってどうなってるの? というところから,ビール樽を継続的に監視する為のシステムの構築までざっくばらんに話せたらな〜と思っています.
皆さんぜひ来て下さい!


ところで以下は現時点でOpen Beer Serverの構築にかかっている費用になりますが,今後更にかかります.

f:id:moznion:20161110144738p:plain

なんてこった,これでは年が越せません.破産してしまいます.Open Beer Serverではカンパを募集しています.

linenotcatというツールを書いた

LINE Notifyが便利でよく使っています.LINE Notifyが何かとか何が便利なのかとかをご存じない方は

コマンドラインから LINE にメッセージを送れる LINE Notify « LINE Engineers' Blog

を読んでいただければと思いますが,あえてものすごくざっくり説明するとim.kayacのLINE版みたいなやつです.

んで,Slackというやつも便利で,こちらはチャットツールなわけですが,そのSlackにはslackcatというこれまた便利なコマンドラインツールがあり,これはコマンドを叩くだけで任意のSlackのchannelに対してメッセージやファイルの中身を送ることが出来ます.その名の通りcatコマンドの結果がSlackに流れるという感じ.

というわけでそのLINE Notify版を作ったという話です.コマンドライン経由でLINE Notifyにメッセージを送ることが出来ます.

github.com

LINE NOTify + catということでlinenotcatという名称です *1

基本的な使い方としてはslackcatとだいたい同じで,

$ echo 'YOUR_ACCESS_TOKEN' > $HOME/.linenotcat

という感じでAccess Tokenを登録するともう使えます.

$ echo 'Hello world!' | linenotcat

という風にすれば標準入力経由で投稿が出来て,

$ linenotcat /your/awesome/file.txt

という風にすればファイルの中身を投稿できます.

$ echo 'Hello world!' | linenotcat --tee
Hello world!

teeもできます.

$ tail -f /your/awesome/error.log | linenotcat --stream

stream modeなんてのもあり,上記の例の場合はtailが何か出力したらその内容を投稿するようになります (現状だと3秒間内容を溜め込んで投稿するようになっています).

$ linenotcat --message 'Hello world!'

なにかと便利だったのでそのままメッセージ送れるモードなんてのもあります.

$ linenotcat --image /path/to/your/awesome/image.png

LINE Notifyは実は画像をアップロードして送れるという機能もあるので画像も送れるようにしました

$ linenotcat --image /path/to/your/awesome/image.png --message "Yo!"

メッセージも添えられます.

$ linenotcat --config_file /path/to/your/config

config fileつまりAccess Tokenも差し替える事ができます.送り先を差し替えられたり出来ます.

$ linenotcat --status
{"status":200,"message":"ok","targetType":"USER","target":"moznion"}

今のTokenの情報を引いてくることも出来ます.


という感じです.まあこんなん無くてもshell scriptで大概解決するんですがバイナリポン置きで動くと楽だなという感じでこさえた次第です.
動くバイナリはGitHub Releasesにあるのでご利用下さい.

github.com

[追記]

homebrewに対応しました.

$ brew tap moznion/homebrew-linenotcat
$ brew install linenotcat

*1:そしてLINEは猫ではない