3

準備中の Vagrant ボックスと、プロビジョニング ファイルとしてのシェル スクリプトがあります。私はそれを機能させるために数日を費やしましたが、今では安定して完全に見えます. ベース ボックスは Ubuntu 12.04 (32 ビット) で、VM で Postgres、Redis、および Memcached が実行されています。プロビジョニング スクリプトは、Nginx 構成をセットアップし、空のデータベースを作成し、いくつかの基本的なハウスキーピングを行います。

VM をパッケージ化し、自宅の別のマシンで再実行しようとしたとき、最初の実行で問題が発生し続け ( vagrant up)、どのサービスも実行されていなかったため、実行しようとしdropdbたりcreatedb失敗したりしました.

なぜこれが起こったのかを掘り下げてみると (そして、私は元 Windows の人間なので、これにはある程度の作業が必要でした)、実行レベルと/etc/rc[0-6,S].dファイルの奥深くにいることに気づきました。

興味のある 3 つのサービスに関連する S (開始) ファイルがあります。

vagrant@precise32:~$ ls -l /etc/rc2.d
total 4
-rw-r--r-- 1 root root 677 Apr 14  2012 README
lrwxrwxrwx 1 root root  20 Dec 29 10:05 S19postgresql -> ../init.d/postgresql
lrwxrwxrwx 1 root root  19 Dec 29 10:05 S20memcached -> ../init.d/memcached
lrwxrwxrwx 1 root root  15 Dec 29 10:05 S20nginx -> ../init.d/nginx
lrwxrwxrwx 1 root root  22 Dec 29 10:05 S20redis-server -> ../init.d/redis-server
...

および実行レベル 0 (シャットダウン) の K 個のファイルなので、すべてが順番に表示されます。

vagrant@precise32:~$ ls -l /etc/rc0.d
total 4
lrwxrwxrwx 1 root root  19 Dec 29 10:05 K20memcached -> ../init.d/memcached
lrwxrwxrwx 1 root root  15 Dec 29 10:05 K20nginx -> ../init.d/nginx
lrwxrwxrwx 1 root root  22 Dec 29 10:05 K20redis-server -> ../init.d/redis-server
lrwxrwxrwx 1 root root  20 Dec 29 10:05 K21postgresql -> ../init.d/postgresql
....

これは、基盤となる VM ランレベルが 2 ではないことを示唆しているように思われたため、この問題をデバッグするために、a.) プロビジョニング時のランレベル、および b.) 予想されるプロセスが実行されていました (memcache、prostgres、redis):

ps aux | grep memcache
ps aux | grep postgres
ps aux | grep redis
# expected output is 'N 2'
runlevel

を実行しvagrant destroy、次にvagrant upこれを実行した結果は次のとおりです。

[default] Running provisioner: Vagrant::Provisioners::Shell...
root       791  0.0  0.2   4624   840 ?        S    10:33   0:00 grep memcache
root       793  0.0  0.2   4624   836 ?        S    10:33   0:00 grep postgres
root       795  0.0  0.2   4624   840 ?        S    10:33   0:00 grep redis
unknown

つまり、プロビジョニング スクリプトの実行時にはサービスが実行されておらず、さらに紛らわしいことに、runlevelコマンドは認識されません。

その後、実行中の VM で を使用してプロビジョニング スクリプトを繰り返し再実行するvagrant provisionと、最初の数回は同じ結果が得られ、最終的に (2 ~ 3 分後) 最初に期待していたことがわかります。

[default] Running provisioner: Vagrant::Provisioners::Shell...
memcache  1103  0.2  0.2  46336  1072 ?        Sl   10:56   0:00 /usr/bin/memcached -m 64 -p 11211 -u memcache -l 127.0.0.1
root      1267  0.0  0.2   4624   840 ?        S    10:56   0:00 grep memcache
postgres  1073 13.0  2.0  50440  7828 ?        S    10:56   0:02 /usr/lib/postgresql/9.1/bin/postgres -D /var/lib/postgresql/9.1/main -c config_file=/etc/postgresql/9.1/main/postgresql.conf
postgres  1077  0.3  0.3  50440  1248 ?        Ss   10:56   0:00 postgres: writer process
postgres  1078  0.3  0.3  50440  1244 ?        Ss   10:56   0:00 postgres: wal writer process
postgres  1079  0.1  0.6  50860  2296 ?        Ss   10:56   0:00 postgres: autovacuum launcher process
postgres  1080  0.0  0.3  20640  1284 ?        Ss   10:56   0:00 postgres: stats collector process
root      1269  0.0  0.2   4624   836 ?        S    10:56   0:00 grep postgres
redis     1123  0.6  0.2   3292  1036 ?        Ss   10:56   0:00 /usr/bin/redis-server /etc/redis/redis.conf
root      1271  0.0  0.2   4624   840 ?        S    10:56   0:00 grep redis
N 2

すべてが立ち上がるまでに少し時間がかかっているようですが、これは理にかなっていますが、プロビジョニングスクリプトが最初は常に失敗するという大きな問題があります.

これは既知の状況ですか? もしそうなら、解決策は何ですか? 理想的には、プロビジョニング スクリプトは、ランレベルが 2 に変更されるまで一時停止します。つまり、ボックスがシェル コマンドを受け入れる準備が整うまでです。

[更新: ハック]

次のスクリプトを一緒にハッキングすることで、この問題を回避することができました。

while [ "`runlevel`" = "unknown" ]; do
    echo "runlevel is 'unknown' - waiting for 10s"
    sleep 10
done
echo "runlevel is now valid ('`runlevel`'), kicking off provisioning..."

これを「pre-provision.sh」として保存すると、Vagrantfile は次のようになります。

# Enable provisioning with a shell script.
config.vm.provision :shell, :path => "pre-provision.sh"
config.vm.provision :shell, :path => "provision.sh", :args => "myapp"

次の出力が得られます。

[default] Running provisioner: Vagrant::Provisioners::Shell...
runlevel is 'unknown' - waiting for 10s
runlevel is 'unknown' - waiting for 10s
runlevel is 'unknown' - waiting for 10s
runlevel is 'unknown' - waiting for 10s
runlevel is 'unknown' - waiting for 10s
runlevel is 'unknown' - waiting for 10s
runlevel is 'unknown' - waiting for 10s
runlevel is 'unknown' - waiting for 10s
runlevel is 'unknown' - waiting for 10s
runlevel is 'unknown' - waiting for 10s
runlevel is 'unknown' - waiting for 10s
runlevel is now valid ('N 2'), kicking off provisioning...
[default] Running provisioner: Vagrant::Provisioners::Shell...
...

その後、オリジナルprovision.shが実行され、すべて問題ありません。

私はまだ何をすべきか知りたいので、これを答えとしてマークしていません(答えですが)-これは確かに機能する方法ではありません

4

1 に答える 1

0

これを行う最も簡単な方法は、関連するプロセスの PID ファイルを探すことであることが判明しました (pid ファイルの説明については、この記事を参照してください - .pid ファイルとは何ですか? )

NGINX_PID=/var/run/nginx.pid

...

## set up nginx configuration using .config from shared directory
if [ ! -f $NGINX_PID ]; then
    echo "---> Waiting for for Nginx process to spin up"
    while [ ! -f $NGINX_PID ]; do
        echo .
        sleep 1
    done
fi
于 2013-01-18T17:57:42.243 に答える