k-holyのPHPとか諸々メモ

Webで働くk-holyがPHP(スクリプト言語)とか諸々のことをメモしていきます。ソースコードはだいたいWindowsで動かしてます。

Fabricで接続情報を指定する方法いろいろ&FabricからPHPスクリプトを実行してみたメモ

Windows7 (MinGW / MSYS) で Fabric の続きです。

ですが、多分今回の内容は実行環境に関係なく共通だと思います。

fabコマンドでSSHの接続情報を指定する方法

接続情報は fabfile.py の中で以下のように指定するのが基本ですが…

from fabric.api import env

env.hosts = ['133.242.2.104']
env.key_filename = ['~/.ssh/id_rsa']
env.user = 'kholy'
env.password = 'hoge'

fabコマンドにはこれだけのオプションがあって、引数で接続情報を指定することもできます。

Usage: fab [options] <command>[:arg1,arg2=val2,host=foo,hosts='h1;h2',...] ...

Options:
  -h, --help            show this help message and exit
  -d NAME, --display=NAME
                        print detailed info about command NAME
  -F FORMAT, --list-format=FORMAT
                        formats --list, choices: short, normal, nested
  -I, --initial-password-prompt
                        Force password prompt up-front
  -l, --list            print list of possible commands and exit
  --set=KEY=VALUE,...   comma separated KEY=VALUE pairs to set Fab env vars
  --shortlist           alias for -F short --list
  -V, --version         show program's version number and exit
  -a, --no_agent        don't use the running SSH agent
  -A, --forward-agent   forward local agent to remote end
  --abort-on-prompts    abort instead of prompting (for password, host, etc)
  -c PATH, --config=PATH
                        specify location of config file to use
  -D, --disable-known-hosts
                        do not load user known_hosts file
  -e, --eagerly-disconnect
                        disconnect from hosts as soon as possible
  -f PATH, --fabfile=PATH
                        python module file to import, e.g. '../other.py'
  -g HOST, --gateway=HOST
                        gateway host to connect through
  --hide=LEVELS         comma-separated list of output levels to hide
  -H HOSTS, --hosts=HOSTS
                        comma-separated list of hosts to operate on
  -i PATH               path to SSH private key file. May be repeated.
  -k, --no-keys         don't load private key files from ~/.ssh/
  --keepalive=N         enables a keepalive every N seconds
  --linewise            print line-by-line instead of byte-by-byte
  -n M, --connection-attempts=M
                        make M attempts to connect before giving up
  --no-pty              do not use pseudo-terminal in run/sudo
  -p PASSWORD, --password=PASSWORD
                        password for use with authentication and/or sudo
  -P, --parallel        default to parallel execution method
  --port=PORT           SSH connection port
  -r, --reject-unknown-hosts
                        reject unknown hosts
  --system-known-hosts=SYSTEM_KNOWN_HOSTS
                        load system known_hosts file before reading user
                        known_hosts
  -R ROLES, --roles=ROLES
                        comma-separated list of roles to operate on
  -s SHELL, --shell=SHELL
                        specify a new shell, defaults to '/bin/bash -l -c'
  --show=LEVELS         comma-separated list of output levels to show
  --skip-bad-hosts      skip over hosts that can't be reached
  --ssh-config-path=PATH
                        Path to SSH config file
  -t N, --timeout=N     set connection timeout to N seconds
  -T N, --command-timeout=N
                        set remote command timeout to N seconds
  -u USER, --user=USER  username to use when connecting to remote hosts
  -w, --warn-only       warn, instead of abort, when commands fail
  -x HOSTS, --exclude-hosts=HOSTS
                        comma-separated list of hosts to exclude
  -z INT, --pool-size=INT
                        number of concurrent processes to use in parallel mode

たとえば以下のような fabfile.py が定義されているとして…

from fabric.api import run

def hostname():
    run('hostname')

ホスト(133.242.2.104) ポート(22) ユーザー(kholy) 秘密鍵(~/.ssh/id_rsa) パスフレーズ(hoge) をそれぞれ fab コマンドの引数で指定して上記 hostname() を実行する場合、こんな感じになります。

(oppy)[k_horii@horii ~]$ fab -H 133.242.2.104 -u kholy -i ~/.ssh/id_rsa -p hoge --port=22 hostname
[133.242.2.104] Executing task 'hostname'
[133.242.2.104] run: hostname
[133.242.2.104] out: s11
[133.242.2.104] out:


Done.
Disconnecting from 133.242.2.104... done.

この例での接続先は契約中のレンタルサーバー Gehirn RS2 ですが、Fabric からコマンドを実行できました。

関数内で実行中タスクの env.host 等を参照できますので、こんな風に run() の実行前に接続設定を切り替えることもできます。

from fabric.api import run, env

def hostname():
    if env.host == '133.242.2.104':
        env.port = 22
        env.user = 'kholy'
        env.key_filename = '~/.ssh/id_rsa'
        env.password = 'hoge'
    run('hostname')
(oppy)[k_horii@horii ~]$ fab -H 133.242.2.104 hostname
[133.242.2.104] Executing task 'hostname'
[133.242.2.104] run: hostname
[133.242.2.104] out: s11
[133.242.2.104] out:


Done.
Disconnecting from 133.242.2.104... done.

fab コマンドのオプションの説明を読むと分かりますが、ホスト指定は fab -H 192.168.1.1,192.168.1.2 のようにカンマ区切りで複数記述することもできます。

こちらの記事も参考になります。

Python製デプロイツール Fabricを初めて使う際に役立つTips

fab 関数1 関数2 という風に呼んで関数1で env を書き換えて関数2を実行する方法や、外部ファイルに定義する方法も紹介されています。

なお、今のところ Windows7 で Pageant を使った接続には成功していません…。

fabコマンドからPHPスクリプトを実行

そろそろ真性PHPerらしく、なるべくPythonを使わずに済むよう、PHPスクリプトを設置して実行してみようと思います。

~/php/test.php

<?php
printf('Hello, %s in %s', (isset($argv[1]) && strlen($argv[1]) >= 1) ? $argv[1] : 'anonymous', php_uname());

~/fabfile.py

from fabric.api import run, env, put
from fabric.contrib.files import exists

def _env():
    if env.host == '133.242.2.104':
        env.port = 22
        env.user = 'kholy'
        env.key_filename = '~/.ssh/id_rsa'
        env.password = 'hoge'

def php_test(name=''):
    _env()
    local_file = '~/php/test.php'
    server_dir = '~/php'
    server_file = '%s/test.php' %(server_dir)
    if not exists(server_dir):
        run('mkdir -p %s' %(server_dir))
    if exists(server_file):
        run('rm %s' %(server_file))
    put(local_file, server_file)
    hello = run('php -f %s %s' %(server_file, name))
    print hello

こんな感じで、run() で実行した結果の出力を変数に取得することもできます。

(oppy)[k_horii@horii ~]$ fab -H 133.242.2.104 php_test
[133.242.2.104] Executing task 'php_test'
[133.242.2.104] put: c:/Users/k_horii/php/test.php -> /home/kholy/php/test.php
[133.242.2.104] run: php -f ~/php/test.php anonymous
[133.242.2.104] out: Hello, anonymous in Linux s11 2.6.32-5-amd64 #1 SMP Mon Feb 25 00:26:11 UTC 2013 x86_64
Hello, anonymous in Linux s11 2.6.32-5-amd64 #1 SMP Mon Feb 25 00:26:11 UTC 2013 x86_64

Done.
Disconnecting from 133.242.2.104... done.

うんうん…

(oppy)[k_horii@horii ~]$ fab -H 133.242.2.104 php_test:k-holy
[133.242.2.104] Executing task 'php_test'
[133.242.2.104] run: rm ~/php/test.php
[133.242.2.104] put: c:/Users/k_horii/php/test.php -> /home/kholy/php/test.php
[133.242.2.104] run: php -f ~/php/test.php k-holy
[133.242.2.104] out: Hello, k-holy in Linux s11 2.6.32-5-amd64 #1 SMP Mon Feb 25 00:26:11 UTC 2013 x86_64
Hello, k-holy in Linux s11 2.6.32-5-amd64 #1 SMP Mon Feb 25 00:26:11 UTC 2013 x86_64

Done.
Disconnecting from 133.242.2.104... done.

よしよし。

コマンドの実行ユーザーには気をつけないといけませんが、とりあえずここまでできれば後はPHPで色々やれそうです。