ConoHa CLI 開発日誌 vol.8

  • POST
ConoHa-CLIの進捗報告。 まだまだやりたいことには届いてないから引き続き考えていくよ! 現状 Golangのパッケージに関して 複数環境のリリースに関して SSHに関して Golangのパッケージに関して Node.jsのrequireは1ファイル内でmodule.exportsに記載したものだけ返すが、 Golangのパッケージは1ディレクトリを1パッケージとして、全角英字で始まる関数やインスタンス等が全て返ってくる。 抽象化は1度しか行えないのでしっかりとオブジェクト指向的な設計が必要になる。 今回Go初挑戦ということで適当に作ったパッケージがあまり使い物にならないので見直す必要が出てきた。 現状の問題点としては、conf.Read()関数がconfigファイルを返す為、spec.tomlを操ろうと思ったらRead関数が使用済みの為に困ってしまう。 一旦はこの2つにリファクタリングしよう。 config endpoints 書籍を購入して勉強しているのだが、ディレクトリによるパッケージはサブディレクトリを切ればネスト出来るのでNode.js的な管理方法も十分可能に思える。 この辺を視野にいれて調査していこう。 参考サイト: パッケージについて - はじめてのGo言語 Go言語入門 複数環境のリリースに関して GitHubではタグを打った後、ファイルをアップロードすることでバイナリファイルをGitHub上に設置出来るらしい。 64bitのWindows、Mac、Linuxの3つくらいは上げておきたいから勉強必須。 ゆくゆくはMakefileかなんかで一撃でリリース出来るようにしたい。 参考サイト: Go のクロスコンパイル環境構築 - Qiita privateなGitHub Releaseページのリリース物をcurl+jqでダウンロードするワンライナー - Qiita GitHubのリリース機能を使う - Qiita Creating Releases - GitHub Help Release Your Software SSHに関して GolangにはSSHパッケージがデフォルトで用意されており、osの標準入力/出力につなげてやると簡単に実装出来るとのこと。 これによりWindows環境でも(多分)動作するSSHになりうる。 でもメインが電車によるSSH接続なのでMoshにも対応したいなあ。。。 というわけで、もう少し調査した後に再開という形になる。 参考サイト: Windows からも ssh でリモートコマンド実行したい、それ golang で出来るよ artyom/mosh - GitHub StanfordSNR/guardian-agent - GitHub

ConoHa CLI 開発日誌 vol.7

  • POST
ConoHa-CLIの進捗報告。 20連勤と毎日午前様のせいで全く進まないままアドベントカレンダー当日になってしまった… 結論から言うと、コピペコードでなんとか納めて公開したわけなんだが… 現状 infoサブコマンドの実装 imports を動的に生成 コピペコードで実装(苦 infoサブコマンドの実装 では早速作っていこう、 エンドポイントはこんな感じになるのかな。 var endpoints = map[string]string]{ "images": "https://image-service.tyo1.conoha.io/v2/images", "flavors": "https://compute.tyo1.conoha.io/v2/1864e71d2deb46f6b47526b69c65a45d/flavors", } …ってのっけからテナントID求めるのかよ。 ん〜…%sで引っ掛けてfmt.Sprintf使うか imports を動的に生成 Vim使いなのでシンタックスハイライト用にvim-goを入れていたが、 どうやらimportsを自動的に表現してくれるコマンドがあるらしいとのこと。 hnakamur/vim-go-tutorial-ja - GitHub インポートパスを手動で操作するのはとても 2010 年っぽい (訳注: 時代遅れ) です。この問題を扱うもっとよいツールを提供しています。もしまだ聞いたことがなければ それは goimports と呼ばれています。 私たちは :GoImports コマンド (最後の s に 注意) も用意しています。これで明示的に goimports を実行することができます。 これだね。 let g:go_fmt_command = "goimports" これ入れておけば自動的にやってくれるみたいだから入れておこう。 不要になったら削除までしてくれるらしいから完璧だね。 さて、早速実験。 fmt.printfn("hogehoge")で保存っと、よしよしちゃんとimport "fmt"になった。 じゃあconf.Read()を使ったらどうなるのっと…"github.com/miyabisun/conoha-cli/conf" 嘘だろ……!? これもバッチリ解決するとは恐ろしい…… もう私は長いGolang人生でimport文を自分で修正することは多分無い。 とはいえ、viperだけで”github.com/spf13/viper”を提示することは難しいと思うので、 この辺の依存関係をどう解決するかは今後も確認する必要がありそうだね。

ConoHa CLI 開発日誌 vol.6

  • POST
ConoHa-CLIの進捗報告。 今回も前回と同様に仕様回りを固める 現状 spec.tomlのフォーマットに関して instance.tomlは必要ないのではないかと考え直す conoha.tomlのフォーマットに関して spec.tomlのフォーマットに関して VM追加 - Compute API v2を元に最低限必要なものを見繕う instance_name_tag : インスタンス名 image: イメージ(UUID) flavor: VMプラン(UUID) user_data: cloud-config (URL or ./cloud.cfg) key_name: SSHキー名 おっ、最小で考えたら意外と少なくいけるな。 ユーザースクリプトがAPI越しだとcloud-configオンリーなのが悲しい。 ところで、考えないようにしてたけどこのイメージとVMプランのUUIDとはなんぞや? イメージ一覧画面を見たが何も書いて無かったので、 VM追加 - Compute API v2のページから推測しよう。 Request Json (最低指定時) { "server": { "imageRef": "1f7bcc63-4a18-4371-85b1-bcdd4301ff31", "flavorRef": "b60acd11-3fd5-46e1-9387-aae4737d49aa", "adminPass":"72LY2hf38Kf84vCy4sUr" } } ハイフンでセパレートされた4-2-2-2-6バイトの文字列がそれっぽいな。 どれどれ、この情報を踏まえてイメージ一覧を。。 イメージ一覧取得(nova) - Compute API v2 images[n].nameの他にimages[n].idがあって、このidがUUIDの形式に一致することがわかる。 { "images": [ { "id": "fb1d084f-357f-40e2-a2c3-59b8ecc1f6f2", "links": [{link}, {link}, {link}], "name": "vmi-centos-7.

ConoHa CLI 開発日誌 vol.5

  • POST
ConoHa-CLIの進捗報告。 個々の所午前様ばかりで全然作業が進まない。 今回はしっかり時間を作ってどう作って行くかを考えていきたい。 現状 ConoHaのゴールに関して カレントディレクトリのファイル仕様 コマンド一覧(予定) ConoHaのゴールに関して 前回考えたConoHaのゴールに関して、vagrant sshコマンドが再現出来れば良い事はわかっている。 諦める前に一回確認しておこう、というわけでGitHubに公開されているソースコードを閲覧してみた。 該当するスクリプトはこの辺にありそうだ。 vagrant/lib/vagrant/action/builtin/ssh_exec.rb vagrant/lib/vagrant/action/builtin/ssh_run.rb vagrant/lib/vagrant/util/ssh.rb まぁ、Rubyのコードをあまり読めないから大変なんだが、どうやらvagrant/action/ssh_run.rbを読む限り、具体的な処理はutil/ssh.rbに移譲しているようだ。 うーむ、やはりサブプロセスで動作させて、インタラクティブな状態で紐付けているようだ。 しかしこれでSSHで繋いだ先でVimやtmuxを平然と使えるって凄いな。 なんとなくできそうな事はわかったが、Goだとどうやって実装すればいいんだ。 How can I open an interactive subprogram from within a go program? josephspurrier/sshclient.go - GitHub Gist ん?なんかめっちゃ簡単な事書いてないか? cmd := exec.Command("ssh", option) cmd.Stdout = os.Stdout cmd.Stdin = os.Stdin cmd.Stderr = os.Stderr cmd.Run() まさかこれだけでいける? オプションのあたりは作り込む必要がありそうだけど、一応覚えておこう。 既存sshと連携したければvagrantと同じくconoha ssh-configで表示されるようにしたい。 カレントディレクトリのファイル仕様 spec.toml: 仕様(名前, OS, ssh-key, インスタンスタイプ…などなど) instance.toml: ConoHaのインスタンスの情報 1ディレクトリ、1設定ファイル、1インスタンス。 これもvagrantにある程度合わせる形で考えた。

ConoHa CLI 開発日誌 vol.4

  • POST
ConoHa-CLIの進捗報告。 チラ裏成分多め。 車駆動開発だとGoの依存ライブラリを落とすだけで世界が止まる。 早くConoHa環境でオラオラ作業したいわぁ。 現状 切り出したログイン処理のリファクタリング コンパイルエラーとの戦い Windows用のホームディレクトリの調整 Glideはオワコン ゴールをどうするか悩む 切り出したログイン処理のリファクタリング 切り出したログイン処理が汚いが諦めて布団に潜った所、 翌日の朝に閃いてリファクタリング、まだまだ拙いが良い感じの粒度で切り出せたように思える。 コンパイルエラーとの戦い single-value contextというエラーが出て中々解消出来ない。 とりあえず色々ググっていたら、戻り値が2個のものを1個だけ受け取っていた事が原因らしい。 不要の場合でも_で受け取る必要があるのね。 全部のコンパイルが通ってログインが通った所で一旦コミットしてGitHubへプッシュ。 Go言語の気に入ったところ/気に入らなかったところ Windows用のホームディレクトリの調整 viperは$HOMEというパワーワードをよしなに解釈してくれるので問題なさそうだが、 コンフィグファイルを読み書きしている箇所はosパッケージを利用しているので、 Windows環境では恐らくコンフィグファイルを読み書き出来ない不具合が登場しそう。 go-homedirというパッケージを用意して読み書きに対応する まずGitHubのプロジェクトルートへジャンプ! うわ、ReadmeにUsageないじゃんピンチ! あ、でも英語読めば十分理解出来る。 一応関数の使い方を確認しておきたいのでgolang go-homedirでぐぐったらGoDocなるサイトが引っかかって理解出来た。 念のためプロジェクトのhomedir.goも確認、たったの100行じゃん楽勝。 確かにDirは引数無しのstring, errを返すし、Expandはstringを受け取りstring, errを返す。 $ glide get github.com/mitchellh/go-homedir Golang で filepath.Abs に ~(ホームディレクトリ) を指定した時にカレントワーキングディレクトリが先頭についてしまう package homedir - GoDoc Glideはオワコン Glideで入れたgo-homedirが使えないので使い方の確認を兼ねて探していたら、 Glide から dep に移行せよ - Qiita の記事でdepに移行せよとか煽られてる この間教えて貰ったばっかりなのに! いやまだわからん、公式で確認しておこう。 GlideのGitHubプロジェクトルートへ行ってみると…… Golang Dep The Go community now has the dep project to manage dependencies.

ConoHa CLI 開発日誌 vol.3

  • POST
ConoHa-CLIの進捗報告。 まだちゃんと全てを切り出せたわけではないが、 現状 ログイン処理の外出し 時刻の比較 ログインの再実行 ログイン処理の外出し ログインコマンドは出来上がった。 ConoHaのAPIへ接続し、TokenIdを持ち帰り~/.config/conoha.tomlに吐き出せるようになった。 しかし、このTokenIdはわずか1日しか有効期限がない上、APIの殆どはTokenIdを求めてくる。 現状の作りでは日付を跨ぐ度にTokenIdの有効期限が切れていますエラーを食らい、 その度にログインコマンドを打ち込む作業が待っている。 ログイン処理を抽象化して取り出す必要がある。 早速プロジェクトルートにutilというディレクトリを作成した。 (ベストプラクティスはまだ良くわかっていないが、公開して有識者の目に止まればPRでも貰えるだろう) Go言語でエラーを書くときに気をつけること - taknb2nchのメモ Go言語でパッケージの修飾名が重複した場合の対応方法 - taknb2nchのメモ 時刻の比較 まずは時刻。 トークン時刻が期限切れか否かを確かめる方法がよく分からない。 Time同士の比較はないのか? 一度Unixタイムに変換して数値同士で比較するように修正した。 Package time Go言語で時刻を - そこはかとなく書くよん。 逆引きGolang (日付と時刻) How to convert ISO 8601 time in golang? ログインの再実行 トークンが古ければもう一度ログインを試みて取得しなおすように修正。 Golangだと処理的になってしまうなぁ……色々とださいがまぁまぁええわ。 動くの大事。 最低限体裁を整えたので一度完了として次へ Next… Mac以外のHomedirectoryも取得出来るようにしたい Golang で filepath.Abs に ~(ホームディレクトリ) を指定した時にカレントワーキングディレクトリが先頭についてしまう package homedir

ConoHa CLI 開発日誌 vol.2

  • POST
今日のConoHa-CLIの進捗報告。 ConoHa-CLIの報告だと、上司はこのはちゃんになるのだろうか? 現状 標準入力からの値取得 ConoHaのAPIを叩いてログイン(トークンID取得) トークン情報を引き出す TOMLファイルを更新 標準入力からの値取得 現在loginコマンドを実装中。 オプションでID、Password、テナントIDを入力させる作りにはしたが、 入力項目が足りない場合は標準入力から煽って入力させる作りを目指した。 参考サイト: flag パッケージ - golang.jp Go 言語で標準入力から読み込む競技プログラミングのアレ — 改訂第二版 早速参考サイトを元に実装を行う。 優先順位の要件は下記。 コマンドライン引数-tからの入力値 $HOME/.conohaの設定項目 標準入力と標準出力で入力させる まずはcmd/root.goでcobraとviperの設定を行う func init() { cobra.OnInitialize(initConfig) RootCmd.AddCommand(versionCmd) } func initConfig() { viper.AddConfigPath("$HOME") viper.SetConfigName(".conoha") viper.SetConfigType("toml") viper.ReadInConfig() } 次にcmd/login.goで各種値を取得するように設定を行う。 func init() { rootcmd.addcommand(logincmd) logincmd.flags().stringp("tenantid", "t", "", "port to run application server on") viper.bindpflag("auth.tenantid", logincmd.flags().lookup("tenantid")) } var loginCmd = &cobra.Command{ Use: "login", Short: "Calculator of addition.