2012-12-31 109 views
3

我有一個我正在準備的Vagrant框,以及一個shell腳本作爲配置文件。我花了幾天的時間纔開始工作,現在看起來很穩定和完整。基礎盒子是Ubuntu 12.04(32位),在VM上運行Postgres,Redis和Memcached。配置腳本設置Nginx配置,創建一個空白數據庫,並進行一些基本的管理。Vagrant配置腳本在VM完全啓動之前運行?

當我開始打包虛擬機,並嘗試在家中的其他機器上重新運行虛擬機時,我在第一次運行時遇到了問題(vagrant up),因此沒有任何服務正在運行 - 所以我的試圖運行dropdbcreatedb失敗。

挖掘爲什麼發生這種情況(我是一個前Windows的傢伙,所以這需要做一些)我發現自己在運行水平和/etc/rc[0-6,S].d文件的腸子。

我有三個服務我感興趣的相關S(啓動)文件:

[email protected]:~$ 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 
... 

和K文件運行級別0(停機),所以一切似乎爲了:

[email protected]:~$ 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,因此爲了調試此問題,我創建了一個新的供應腳本來輸出。)供應時的運行級別,以及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 

看起來它只是採取一切一點時間上來,這是有道理的,hwoever提出了我一個巨大的問題,該配置腳本將總是失敗第一時間。

這是一個已知的情況,如果是這樣,解決方案是什麼?理想情況下,配置腳本會暫停,直到運行級別變爲2,即該框已準備好接受shell命令。

[更新:HACK]

我設法通過黑客在一起下面的腳本來解決此問題:

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

我已經保存了該爲「預規定。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運行,一切OK。

我沒有這個標記爲答案(雖然它是一個答案),因爲我還是想知道我應該做的 - 這絕不是它的工作原理,肯定的方式嗎?

回答

0

事實證明,這樣做最簡單的方法是尋找相關過程的PID文件(請參閱本文pid文件的解釋 - What is a .pid file and what does it contain?

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 
相關問題