Switching user in Fabric
Asked Answered
E

3

20

I have a problem when using Fabric to mimic my SSH workflow to deploy my web application.

Here's my usual flow of commands when I SSH to a server:

  1. SSH using root user. ssh [email protected]
  2. Switch to web user: su - web
  3. Change directory: cd /srv/web/prod/abc_project
  4. Start virtualenv: workon abc_env
  5. Perform git pull: git pull origin master
  6. Run a script: build_stuff -m build
  7. Run another script: ./run

I tried to write this as a deploy script in Fabric and I get a shell output when su - web is entered. I have to hit Ctrl-D to continue the script. I am also unable to activate my virtualenv....because: su - web successfully switches the user to web but because of the Ctrl-d (so that I can continue the Fabric script), it logs out of that user and back to root.

Here's my script:

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)

...there's one more thing: No, I can't login as web initially, I have to login as root. It is the web user that has the virtualenv not the root user.

Electrolier answered 26/10, 2012 at 4:16 Comment(0)
A
16

First of all, you should use sudo when executing commands under another user. Second, workon sets environment variables for current shell. Since fabric invokes new shell for every command, you should run workon rhino_env in every command, where you need virtualenv (i.e. as prefix). With this edits yor code should look like this:

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)
Anion answered 26/10, 2012 at 18:56 Comment(1)
Thanks so much! I never thought of running git commands using the web user. I kept trying to use su - web in front of the git commands instead. Thanks a million mechmind!Electrolier
R
4

The way I achieve this is with

from fabric.api import settings

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

You will be prompted for the password of otheruser, though only once. So it is not equivalent so sudo su otheruser, where root logs in to the user account without a password, but is is a simple way to switch between users in your script, only typing each password once

Rowden answered 16/2, 2016 at 13:21 Comment(1)
I swear this worked once! My provisioning task is now broken.Scrofula
B
3

One possible solution is to use the sudo operation instead of changing the remote user with su.

Byplay answered 26/10, 2012 at 8:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.