我准备了一个Vagrant框,以及一个shell脚本作为配置文件。我花了几天时间让它工作,现在看起来稳定而且完整。基本框是Ubuntu 12.04(32位),在VM上运行Postgres,Redis和Memcached。配置脚本设置Nginx配置,创建空白数据库,并进行一些基本的内务管理。
当我打包VM并尝试在家中的另一台机器上重新运行它时,我在第一次运行时遇到问题(vagrant up
),因此没有任何服务正在运行 - 所以我尝试运行dropdb
或createdb
失败了。
深入研究为什么会发生这种情况(我是一个前Windows用户,所以这需要做一些事情)我发现自己处于运行级别和/etc/rc[0-6,S].d
文件的内容中。
我有三个我感兴趣的服务的相关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,因此为了调试此问题,我创建了一个新的配置脚本来输出。)配置时的运行级别,以及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,即该框已准备好接受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..."
我已将此保存为'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
运行,一切正常。
我没有将此标记为答案(虽然它是 答案)因为我仍然想知道我应该做什么 - 这当然不是它的工作方式吗?
答案 0 :(得分: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