読者です 読者をやめる 読者になる 読者になる

オープンソースこねこね

Webプログラミングなどについてあれこれ。

Altax PHP Deploy tool - PHPでデプロイツールを作った

PHP deploy

PHPでデプロイツールを作ってみました。

なんでこんなものを作ったかというと

を読んで、普段PHP使いの自分としてはPHPで動くシンプルなデプロイツールがほしいかなと思ったからです。 結構まじめにつくりました。

機能

CapistranoみたいにSSHを並列に動かして、定義したタスクを実行します。

1ファイルだけで動作します。

タスクはPHPで記述します。

インストール

インストールスクリプトがあるので、それを実行してください。

$ curl https://raw.github.com/kohkimakimoto/altax/master/installer.sh | bash -s system

PHPのソースファイルを一つにまとめて作られる実行ファイルを/usr/local/bin配下に配置するので、rootユーザの権限が必要です。

※上記コマンドでインストールするファイルは/usr/local/bin/altaxだけなので不要になってアンインストールしたくなったらこのファイルを消すだけでOKです。

インストールできたら、試しにコマンドを実行してみてください。

$ altax

以下のようなコマンドラインオプションなどの情報が表示されます。

Altax is a simple deployment tool running SSH in parallel.

Altax version 1.0.3
Copyright (c) Kohki Makimoto <kohki.makimoto@gmail.com>
Apache License 2.0

Usage:
  altax [-d|-h|-f|-l|-c] TASK [ARGS..]

Options:
  -d         : Switch the debug mode to output log on the debug level.
  -h         : List available command line options (this page).
  -f=FILE    : Specify to load configuration file (default altax.php).
  -l         : List available tasks.
  -c         : List configurations.

Built-in tasks:
  init       : Create default configuration file (altax.php).

使い方

$ altax init

を実行するとカレントディレクトリにaltax.phpというファイルを生成します。このファイルを修正してホストやタスクの定義を書いていきます。

host('foo.sample.com',   'web');
host('bar.sample.com',   'web');
host('hoge.sample.com',  'db');

/**
 * Web 再起動
 */
desc('Restart web.');
task('restart_web',array('roles' => 'web'), function($host, $args){

  run("sudo /etc/init.d/httpd stop");
  run("sudo /etc/init.d/httpd start");
});

/**
 * DB 再起動
 */
desc('Restart db.');
task('restart_db',array('roles' => 'db'), function($host, $args){

  run("sudo /etc/init.d/mysqld stop");
  run("sudo /etc/init.d/mysqld start");

});

サーバ再起動だけのサンプルですけど、まあこんなかんじに。Capistranoっぽくかけるはず。上記のタスク定義ではPHPの無名関数を使っているのでPHP5.3以降でないと動きませんが、functionの定義部分を明示的に関数を作ってコールバック関数として渡すようにしてやれば、それ以前のバージョンでも動くと思います。

SSHの鍵設定や、リモートサーバのsudoの設定も適宜しておきます。

実行は以下のようにタスク名を指定するだけ。

$ altax restart_web

必要に応じてタスクの後ろに引数を渡して、タスク内のロジックで参照することもできます。またrun関数にユーザを指定するオプションをつけることで実行ユーザを変えることもできます。

desc('引数を使う');
task('sample_task', array('roles' => 'web'), function($host, $args){

  if (count($args) < 1) {
    echo "You must pass 1 argument.\n";
    return;
  }

  run("echo $args[0]", array("user" => "root"));

});

実行

$ altax sample_task helloworld

また-dオプションをつけて実行すれば、デバッグレベルのログを出力しますので、うまく動作しないときなどに利用してください。

$ altax -d sample_task helloworld
[2013-02-02T11:06:41+09:00] INFO *** Altax version 1.0.5 ***
[2013-02-02T11:06:41+09:00] INFO Executing task: [sample_task]
[2013-02-02T11:06:41+09:00] DEBUG Processing to fork process.
[2013-02-02T11:06:41+09:00] DEBUG Setup signal handler.
[2013-02-02T11:06:41+09:00] DEBUG Forked child to process to host [127.0.0.1] pid = 25136
[2013-02-02T11:06:41+09:00] DEBUG [127.0.0.1] Processing execute
[2013-02-02T11:06:41+09:00] DEBUG [127.0.0.1] Executing SSH Command [ssh -t 127.0.0.1 " sudo -uroot sh -c 'echo helloworld'"]
helloworld
Connection to 127.0.0.1 closed.
[2013-02-02T11:06:41+09:00] DEBUG [127.0.0.1] Child process 25136 is completed.
[2013-02-02T11:06:41+09:00] INFO [127.0.0.1] Altax process is completed.

で、このログにあるように内部的にはSSHのコマンドラッパーとして動いているので、run関数の処理の実態は

ssh -t 127.0.0.1 " sudo -uroot sh -c 'echo helloworld'"

というSSHコマンドだったりするのもわかります。

Githubに多少ドキュメントも書いたので参考までに。

雑記

マルチプロセスなプログラムは、結構ハマりどころがあって大変だったです。SSHの擬似端末とかの処理でハマったり。このへんも気が向いたら、そのうち書こうかな。