我正在为我们的系统编写部署引擎,其中每个项目都指定了他的自定义部署指令。
节点在EC2上运行。
其中一个项目取决于第三方应用程序的源版本。
具体做法是:
cd /tmp
wget s3://.../tools/x264_20_12_2010.zip
unzip x264_20_12_2010.zip
cd x264_20_12_2010
./configure
make
checkinstall --pkgname=x264 --pkgversion "2:0.HEAD" --backup=no --deldoc=yes --fstrans=no --default
目前我正在使用boto的ShellCommand(内部使用subprocess.Popen),这看起来像这样:
def deploy():
ShellCommand("apt-get remove ffmpeg x264 libx264-dev")
ShellCommand("apt-get update")
ShellCommand("apt-get install -y build-essential checkinstall yasm texi2html libfuse-dev fuse-utils libcurl4-openssl-dev libxml2-dev mime-support libfaac-dev libjack-jackd2-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libsdl1.2-dev libtheora-dev libvorbis-dev libvpx-dev libx11-dev libxfixes-dev libxvidcore-dev zlib1g-dev")
ShellCommand("cd /tmp")
s3cmd_sync("s3://.../tools/x264_20_12_2010.zip", "/tmp/x264_20_12_2010.zip")
ShellCommand("unzip x264_20_12_2010.zip")
ShellCommand("cd x264_20_12_2010")
ShellCommand("./configure")
ShellCommand("make")
ShellCommand(r'checkinstall --pkgname=x264 --pkgversion "2:0.HEAD" --backup=no --deldoc=yes --fstrans=no --default')
遗憾的是,这失败了,因为cd /tmp
适用于子进程,这意味着一旦我返回父进程并发出第二个ShellCommand,exeenv就会从父进程继承,这让我觉得我需要一些执行shell命令的框架,它将在同一个子进程中应用所有命令而不会丢失上下文。
这个问题的推荐解决方案是什么?请注意,命令行执行app的记录非常重要(如何在没有它的情况下进行调试?),这就是我喜欢ShellCommand的原因...(如果感兴趣,请参阅boto logging)。
谢谢你,
格言。
答案 0 :(得分:0)
想想os.chdir(“DIRECTORY”)而不是Popen(“cd DIRECTORY”)
也许这里最好不要为每个命令执行一个新的shell:只写一个多行shell skript
deploy_commands =“”“apt-get foo apt-get酒吧 cd baz;嘘蝙蝠“”“
通过Popen结束执行(deploy_commands,shell = True)。
但请阅读Popen文档中关于不转义不受信任参数的安全警告。
答案 1 :(得分:0)
我最终做了这个
def shell_script(appname, *commands):
workspace = tempfile.mkdtemp(prefix=appname + '-')
installer = open(workspace + "/installer.sh", 'w')
installer.write("#!/bin/bash\n")
installer.write("cd " + workspace + "\n")
for line in commands:
installer.write(line + "\n")
ShellCommand("chmod u+x " + installer.name)
installer.close()
ShellCommand(installer.name)