YOwatari's blog

思うままに。

cobra を使って golang で cli ツールを作ってみる

この記事は、 Advent Calendar 2016 - VOYAGE GROUP techlog の17日目のエントリです。

こんにちは。 fluct でエンジニアしている @YOwatari です。

今日は、 golangcli ツールを作ってみた話です

ある日

fluct では、バッチが生成するファイルに、何かしらの時刻が 0005 のような形で含まれたりするものがあります。 そうしたファイルを扱いたい時に、現在時刻から直近のものを取得したいなどのケースがままあります。 そんな中、ある日の社内Slack にてこんなやり取りがありました。

f:id:wata88:20161218173623p:plain

ということで、 ニッチな cli ツールを作ってみるかとやってみました。

cobra

golangcli ツールを使う場合、様々な便利がパッケージがあるのでその中から選択して利用することになるかと思われます。 これまで私は https://github.com/codegangsta/cli をよく使っていましたが、今回は気持ち新しく cobra を使ってみます。

github.com

cobra コマンドを使ってコードを自動生成してくれるようで

go get -v github.com/spf13/cobra/cobra

でインストールして

cobra init github.com/YOUR ACCOUNT/REPOSITORY

すると、$GOPATH/src/github.com/YOUR ACCOUNT/REPOSITORY にテンプレートを生成してくれます。 この時、 $HOME/.cobra.yaml を用意していれば、それに基づいてライセンス表記などの項目を埋めてくれます。

さらにサブコマンド追加は

cd $GOPATH/src/github.com/YOUR ACCOUNT/REPOSITORY
cobra add sub

とすると、sub をサブコマンドとして追加してくれます

テンプレートで生成されるコードの構成は以下のようになっていて

├── LICENSE
├── cmd
│   ├── root.go
│   └── sub.go
└── main.go

sub コマンドの処理を書きたい場合は

// subCmd represents the sub command
var subCmd = &cobra.Command{
    Use:   "sub",
    Short: "A brief description of your command",
    Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
    Run: func(cmd *cobra.Command, args []string) {
        // TODO: Work your own magic here
        fmt.Println("sub called")
    },
}

の Run の関数の中身を変更すれば良さそうです。 フラグの作り方など、さらに詳しい内容は cobra の README を参照してください。

つくってみる

さて、先ほどの 1日をn分割して現在時刻より前 or 後の HHMM を取り出す clicobra で作ってみたのが以下になります。

github.com

一日を 288分割して 現在の前後を取ってみると、以下のように

$ date
Sun Dec 18 18:19:21 JST 2016

$ hhmm -d 288 show after 
1820

$ hhmm -d 288 show before
1815

ちゃんと出力してくれます。 タイムゾーンを考慮してなかったり秒数を考慮してなかったりでまだまだですが、 それっぽく動くところまでは簡単に作れました。

おわりに

cobra を使って cliツール を作ってみました。 フラグにスコープを持たせることができたり、実行前後に処理をフックできたり、と cobra 便利さを感じたので、今後 cli ツールを使う際には cobra を積極的に使ってみようかなと思います。

それでは、明日のエントリもお楽しみに。

ruby 1.8.7-p249 がビルドできなくて困った

tl;dr

openssl のバージョンとの差で 1.8.7-p249 がビルドできないマンになったので、パッチを当ててインストールした

パッチ

ruby-openssl-1.0.0.patch · GitHubUbuntu 13.10にruby 1.9.2をインストールする時にSSLv2のエラーが出たら - Qiita を使えばビルドできる

単純にくっつけたパッチ ruby-1.8.7-p249.patch.diff · GitHub

ビルド

GitHub - rbenv/ruby-build: Compile and install Ruby の通りにやればモーマンタイ

$ rbenv install --patch 1.8.7-p249 < <(curl -sSL https://git.io/ruby-1.8.7-p249-patch)

余談

gist の raw なリンクは長くてつらいので git.io を使うと便利。指定の名前にしたい時は↓を参考に。

qiita.com

Electronにtypescriptで入門する

yapcasia.org

YAPCに行ってElectron楽しそうだなと思ったので、遊んでみることに。

Electron

electron.atom.io

Electronとは、GitHubの開発したエディアAtomの実行環境をSDKとして公開されたAtomShellの新しい名前で、HTML5+Node.jsでデスクトップアプリケーションを開発できるクロスプラットフォーム開発環境です。
Electronの情報を探す上で、まだまだAtomShellで検索したほうがヒットしやすいかなという印象です。

SlackやQiitaのKobito、Visual Stadio Codeなどでも採用されており、非常に親しみ深いです。
内部にChromiumを内蔵しているため、Chromiumだけを対象にして開発できる分、複数ブラウザの制約を考えなくて良い心地よさがある一方で、デスクトップアプリケーションなので、Chromiumの問題かOSの問題かなど、問題の切り分けを意識する必要があります。

似たものとしては、nw.js(node webkit)があるようです。

nwjs.io

Hello World

http://electron.atom.io/docs/latest/tutorial/quick-start/ に従えば、手元でElectronで動くアプリケーションを体験できます。
HTMLとjavascriptだけで書けて楽ちんです。

typescript

とりあえず、QuickStartを動かした後に、javascriptよりもtypescriptが好きなので、typescriptで書いてみました。

YOwatari/picnic · GitHub

typescriptのコンパイル時にエラーが出てしまいますが、とりあえずは動作します。
gulpを使って、typescript→ES6→ES5→minifyするだけです。(冗長な感じ

型定義ファイルについては、 https://github.com/borisyankov/DefinitelyTyped にある、github-electronをtsdで指定して利用させてもらっています。

これでアニメーションGIFのビューワーっぽいものでも作ってみようかなと思いつつ、次はReactを導入してみるのも良い遊びかなと思ったり。

今度はjupyter notebookでirubyを動かす

Rを動かしたついでに、rubyも動かしたいという声を聞いたのでjupyterから使えるようにしてみます。

準備

irubyのインストールはgemから簡単にできます。
その前に、automakeとlibtoolをインストールします。

brew install automake libtool

また、irubyはruby 2.1.0以降でないとgemからインストールできないので2.2.2をrbenvでインストールします

rbenv install 2.2.2
rbevn rehash

続いて、jupyter_consoleをインストールします

git clone git@github.com:jupyter/jupyter_console.git
cd jupyter_console
pip install -r requirements.txt -e .

irubyのインストール

ここまでくれば、irubyのインストール準備は整ったのでpryも一緒にインストールします。

gem install pry iruby

f:id:wata88:20150707230639p:plain

ついでに、グラフをかっこよく描けるnyaplot使おうとしたら、nyaplotjsのセットアップが面倒になったのでやめました。

jupyter notebookでRを動かす

iPython notebookが進化して様々な言語を扱えるようになったjupyterが登場しました。
今までpythonのためぐらいにしか使っていませんでしたが、Rを使う機会があったのでjupyterで動かせるようにしてみます。メモです。

下準備

brew install ZMQ

zeromqをインストールしても、libzmq.4.dylibが無いと怒られるので、
とりあえずリンクを作っておきます。もっとまともなやり方はありそうです。

ln -s /usr/local/Cellar/zeromq/4.1.2/lib/libzmq.dylib /usr/local/lib/libzmq.4.dylib

jupyterインストールの準備

github.com

pyenvとvirtualenvが使える前提です。
jupyter notebookをインストールします。

pyenv virtualenv 3.4.3 jupyter
pyenv local jupyter
pip install pycurl
git clone git@github.com:jupyter/notebook.git
cd notebook
pip install -r requirements.txt -e .
pyenv rehash

IRkernelのインストール

github.com

これはRのコンソール上で

install.packages(c('rzmq','repr','IRkernel','IRdisplay'),
                 repos = c('http://irkernel.github.io/', getOption('repos')))
IRkernel::installspec(user=F)

jupyter notebookの起動

jupyter notebook

f:id:wata88:20150703094047p:plain

RTX1200のVPN(L2TP/IPsec)の認証にActive Directoryを使う

RTX1200のファームアップデート

firmware release for Yamaha Network ProductsからRTX1200のファームウェアをダウンロードして,RT-Tftp Clientを使ってアップデートを行います.

これを行わなくても問題ないですが,L2TP/IPsecの設定がGUIから行えるようになっているので便利です.

RTX1200でanonymous待ち受けのVPNを作る

最新ファームウェアGUIからVPN設定を行えるので,適当に作ります.
PPP認証方式をCHAPにしておきます.

f:id:wata88:20150213221549p:plain

RTX1200のradius認証の設定

radius認証は,GUIから設定可能です.迷う部分は特に無し.

認証 ON
アカウンティング ON
サーバーのIPアドレス サーバー(1) ネットワークポリシーサーバのIP
シークレット文字列 ********
認証で使うポート番号 1812
アカウンティングで使うポート番号 1813

ローカルとradiusの認証判定

radiusとローカルの認証について,どのように分岐するのかは,以下が参考になりました.

RADIUSを使用したログインユーザーの管理

要は,ローカルユーザが無ければradiusへ認証を行うようになっています.
なので,ADユーザとローカルユーザで同一名があると,ローカル側が優先されます.

radiusクライントの追加

Active DirectoryにはWindows Server 2012R2を使っています.
ネットワークポリシーサーバをサーバーマネージャーから起動して,RADIUSクライアントとサーバ->RADIUSクライアントを右クリックで新規を開きます.

f:id:wata88:20150213215013p:plain

IPアドレスにはRTX1200のIPを入れ,radius認証設定で記述したシークレット文字列と同じものを共有シークレットに書きます.

ポリシーの設定

ウィザードで追加したポリシーでは上手く利用できません.下の通りに設定を書き直します.

接続要求ポリシー

条件にNAS IPv4radiusクライアントのIPを指定したものを追加します.
ポリシーの条件は,ポリシーを適用する条件なのでradiusクライアントで特定しておけば問題なし.

ネットワークポリシー

同様にNAS IPv4radiusクライアントのIPを指定した条件を追加します.
さらに追加で,WindowsグループにVPN認証したいユーザグループを指定します.
ここは,グループにするかユーザにするか好きにする感じ.
僕は,VPNグループを作成して用いました.ユーザ全体が良いならDocument Usersを指定すると良いでしょう.

f:id:wata88:20150213220223p:plain

RTX1200におけるL2TP/IPsecのPPP認証にはCHAPかPAPしか使えないそうなので,そのように認証方法を設定します.

f:id:wata88:20150213220410p:plain

ここが最大の迷いどころ.
Service-TypeをFramedからLoginに変更します.
なぜか,FramedやAdministrativeでは上手く認証が行えません.

ADアカウントのパスワード保存

CHAP認証を用いる場合,パスワードの暗号化を元に戻せる状態で保存する必要があります.

f:id:wata88:20150213220834p:plain

VPN認証したいユーザの暗号化オプションを「暗号化を元に戻せる状態でパスワードを保存する」にチェックを入れておきます.
既にパスワードが設定されている場合は,再度パスワードを設定します.

これで,ADアカウントでVPNできる設定が完了しました.
ログインにはADアカウントを使えますが,ドメインを含めないで書く必要があります.

以上で完了.

FiddlirをOSXに入れてみる

f:id:wata88:20140803032657p:plain

Fiddler free web debugging proxy

クライアントとサーバの間に立って、パケットをキャプチャするだけじゃなくて改変もできるFiddlirを入れてみる。

Fiddlirを動かすには.NET環境が必要で、Windowsか...となるところを、Windowsが提供している.NETをクロスプラットフォーム動作を目指すMonoのお世話になることで頑張れます。

Mono - Fiddler

ここから、Mono版Fiddlerをダウンロードしてインストール。 起動すると、Monoをインストールするようにと言われるので、飛ばされるページからOSXのものをダウンロードしてインストール。 今回は、実行するだけなのでMREを入れてみました。

Download - Mono

これで起動するようになりますが、起動に凄い時間かかります

f:id:wata88:20140803034007p:plain

蛇足

Monoを調べてみたら、Mono上のゲーム用フレームワークMonoGameが面白そうでした。

XNA互換で、BastionやTerrariaがMonoGameで動いてるらしい。

僕の考えた最強のゲームフレームワーク『MonoGame』を試す - 5.1さらうどん