Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

switch to different user using fabric

I recently started looking at fabric for remote deployment. I need to switch to a diff user (from the one that I login as) and am not able to figure it out. Is it even possible, if so how? My current user doesnt have sudo permissions.

I tried changing following environment variables

env.sudo_prefix = "su newUser -c "
env.sudo_prompt = "Password:"

But fabric does not wait for password input for 'newUser' and fails.

out: Password: 
[[email protected]] out: su: incorrect password

Fatal error: sudo() received nonzero return code 1 while executing!

Requested: touch x
Executed: su newUser -c  -u "root"  /bin/bash -l -c "cd /home/oldUser/upgrade && touch x"

Aborting.
Disconnecting from [email protected]... done.

Update:

As J.F. Sebastian suggested, su newUser -c works, but it prompts password for every command for every server, which kind of defeats the purpose of automation. Is there any way in Fabric to pass in same value based on prompt (in this case, its always Password:)

like image 539
shailesh mangal Avatar asked Sep 28 '12 14:09

shailesh mangal


2 Answers

Thanks J F Sebastian, There were couple of catches.

  1. Fabric makes connections lazily, so I had to make a dummy connection before invoking su to avoid context switch.
  2. Pwd need to be stored in global scope and so that it can be reused. Fabric doesnt put it in cache for overridden su command.

Here is what ended up doing. Its working.

pwd = None
@hosts('myhost.com')
def test():
    with cd('/home/oldUser/upgrade'):
        run('ls')  #This is to connect aggressively (instead of lazily)
        global pwd  #Change the scope of pwd
        if pwd is None:
            pwd = getpass.getpass('enter password for newUser')

        execute(su, pwd, 'newUser', 'touch x')  
        run ('ls')
        execute(su, pwd, 'newUser', 'rm x') 
        run ('ls')

def su(pwd, user, command):
    with settings(
        password= "%s" % pwd,
        sudo_prefix="su %s -c " % user,
        sudo_prompt="Password:"
        ):
        sudo(command)
like image 56
shailesh mangal Avatar answered Oct 16 '22 03:10

shailesh mangal


If you can't ssh as newuser and can't use sudo(command, user='newuser'):

import getpass # just for demonstration
from fabric.api import sudo, settings

def su(user, command):
    with settings(password=getpass.getpass('enter password for %s: ' % user),
                  sudo_prefix="su %s -c " % user,
                  sudo_prompt="Password:"):
        sudo(command)
like image 37
jfs Avatar answered Oct 16 '22 04:10

jfs