20

我在使用 Fabric 模拟我的 SSH 工作流程来部署我的 Web 应用程序时遇到问题。

这是我通过 SSH 连接到服务器时的常用命令流程:

  1. SSH 使用 root 用户。ssh root@1.2.3.4
  2. 切换到网页用户:su - web
  3. 更改目录:cd /srv/web/prod/abc_project
  4. 启动 virtualenv:workon abc_env
  5. 执行 git pull:git pull origin master
  6. 运行脚本: build_stuff -m build
  7. 运行另一个脚本:./run

我尝试将其编写为 Fabric 中的部署脚本,并在输入 su - web 时得到 shell 输出。我必须按 Ctrl-D 才能继续脚本。我也无法激活我的 virtualenv ....因为:su - web 成功将用户切换到web但由于 Ctrl-d(以便我可以继续 Fabric 脚本),它会注销该用户并返回到 root .

这是我的脚本:

env.user = 'root'

@roles('web')
def deploy():
    dev_path = '/srv/web/prod'
    app_path = '/srv/web/prod/rhino'
    workon = 'workon rhino_env'
    with prefix('su - web'):
        puts('Switched to `web` user')
        with settings(warn_only=True):
            run('kill -9 `cat /srv/web/run/rhino/rhino.pid`')
            puts('Stopped rhino...')
        with cd(app_path):
            run('git reset --hard HEAD')
            puts('Discarded all untracked and modified files')
            run('git checkout master')
            run('git pull origin master')
            users = run('users')
            puts('Output from `users` command: %s' % users)
            run(workon)
            run('build_assets -m build')
        run('cd %(dev_path)s; chown -R web:ebalu rhino' % {'dev_path': dev_path})
        run('cd %(app_path)s; ./run' % {'app_path': app_path})
        pid = run('cat /srv/web/run/rhino/rhino.pid')
        puts('Rhino started again with pid: %s.' % pid)

...还有一件事:不,我最初无法以 Web 身份登录,我必须以 root 身份登录。拥有 virtualenv 而不是 root 用户的是 web 用户。

4

3 回答 3

16

首先,您应该sudo在另一个用户下执行命令时使用。其次,workon为当前 shell 设置环境变量。由于fabric 为每个命令调用新的shell,因此您应该workon rhino_env在需要virtualenv(即作为前缀)的每个命令中运行。通过此编辑,您的代码应如下所示:

env.user = 'root'

@roles('web')
def deploy():
    dev_path = '/srv/web/prod'
    app_path = '/srv/web/prod/rhino'
    workon = 'workon rhino_env; '
    with settings(warn_only=True):
        run('kill -9 `cat /srv/web/run/rhino/rhino.pid`')
        puts('Stopped rhino...')
    with cd(app_path):
        sudo('git reset --hard HEAD', user='web')
        puts('Discarded all untracked and modified files')
        sudo('git checkout master', user='web')
        sudo('git pull origin master', user='web')
        users = run('users')
        puts('Output from `users` command: %s' % users)

        with prefix(workon):
            sudo('build_assets -m build', user='web')
    with cd(dev_path):
        run('chown -R web:ebalu rhino')

    with cd(app_path):
        sudo('./run', user='web')

    pid = run('cat /srv/web/run/rhino/rhino.pid')
    puts('Rhino started again with pid: %s.' % pid)
于 2012-10-26T18:56:00.213 回答
4

我实现这一目标的方式是

from fabric.api import settings

with settings(user='otheruser'):
    ...

系统将提示您输入 的密码otheruser,但只有一次。所以它不是等价sudo su otheruser的,root登录到没有密码的用户帐户,而是一种在脚本中切换用户的简单方法,只需输入每个密码一次

于 2016-02-16T13:21:50.170 回答
3

一种可能的解决方案是使用sudo操作,而不是使用su.

于 2012-10-26T08:00:58.153 回答