0

我正在为我们的系统编写一个部署引擎,其中每个项目都指定了他的自定义部署说明。

节点在 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 命令的执行框架,它将应用所有同一个子进程中的命令,而不会丢失上下文。

这个问题的推荐解决方案是什么?请注意,命令行执行应用程序的日志记录非常重要(没有它你怎么调试?),这就是为什么我喜欢 ShellCommand...(如果有兴趣,请参阅 boto 日志记录)。

谢谢你,
马克西姆。

4

2 回答 2

0
  1. 想想 os.chdir("DIRECTORY") 而不是 Popen("cd DIRECTORY")

  2. 也许最好不要为每个命令执行一个新的 shell:只需编写一个多行 shell 脚本

deploy_commands = """apt-get foo apt-get bar cd baz ; boo bat"""

通过 Popen(deploy_commands, shell=True) 结束执行。

但是请阅读 Popen 文档中关于不转义不受信任的参数的安全警告。

于 2010-12-20T20:04:38.260 回答
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)
于 2010-12-21T07:31:30.703 回答