sunzi を試してみる - Memo で試した Sunzi だけど sudo が使えないのが困った。
今の職場は root 権限は貰えないけど個人のアカウントに sudo は付けて貰える。
なので sudo ができるのが前提。
シェルスクリプトの中で sudo を付けて、sunzi deploy を実行するとこんなエラーになる。
sudo: sorry, you must have a tty to run sudo
単純に ssh コマンドを発行している所で -t を付けたら行けると思ったが以下のようなエラーになった。
Pseudo-terminal will not be allocated because stdin is not a terminal. Warning: Permanently added '192.168.1.10' (RSA) to the list of known hosts. user@192.168.1.10's password: sudo: sorry, you must have a tty to run sudo
仮に本体の方を sudo できるように issue をたてたり、パッチを作っても取り入れられなさそう。
Always use the root user.
GitHub - kenn/sunzi: Sunzi: Server configuration automation for minimalists
と Readme に書かれている通り root 前提という設計思想。
Sunzi をとても気に入ったのでラッパーを作る事にした。
SSH で sudo できる関連の事を調べている最中に Python の Fabric は sudo が使える事を思い出した。
Sunzi のコードを読んみると、定義したシェルスクリプトを一つのディレクトリ(compiled)にまとめるのと、compiled を転送してリモートサーバで install.sh を実行するタスクが分かれていた。
なので全てポーティングするではなく、Sunzi を利用して転送、実行の箇所だけ Fabric を使う事にした。
GitHub - heavenshell/sunzi-sudo: Wrapper for Sunzi using Python Fabric
- Fabric で Sunzi の compile を実行し(sunzi compile)、compiled ディレクトリを作る
- Fabric で compiled を tar.gz 形式に圧縮し、Fabric の put() を作ってリモートサーバに転送
- Fabric でリモートサーバに転送したファイルを展開
- Fabric でリモートサーバの install.sh を sudo() を使って実行
やってるのはこんな感じ。
使い方
Fabric と PyYaml が必要なのでインストールする。
$ sudo pip install Fabric $ sudo pip install PyYaml
Github のリポジトリより fabfile を sunzi プロジェクトと同階層にダウンロードする。
$ git clone https://github.com/heavenshell/sunzi-sudo.git
実行
$ fab sunzi:foo@example.com
bundler を使ってる場合は以下の様にする。
$ fab sunzi:bundle,foo@example.com
Fabric のオプションを利用した書き方もできる。
$ fab sunzi:bundle -H example.com -u foo
複数ホストに対して実行する場合は以下のように書く。
$ fab sunzi:bundle -H a.example.com,b.example.com -u foo
本来なら Ruby でラッパーを作るのが筋なんだろうけど、動く事が目的だし自分の為のツールだし、sudo やリモートの操作が出来る Fabric を使いたいから Python で書いた。
これで便利になった!
あと、Fabric は exit ステータスが 0 じゃないと警告を出すので、install.sh とかの最後は sunzi::silencer で終わらない方が良い。