Python Fabric Sudo su - user
Asked Answered
W

4

9

I currently do the following from the command line:

$ ssh myuser@remote-server 
password:
[myuser@remote-server ~]$ sudo su - dev_user
[dev_user@remote-server ~]$ whoami
dev_user
[dev_user@remote-server ~]$

No permission issue.

The myuser has enough permission to do what typed above, but it does not have permission to do sudo su -c whoami dev_user

I tried the following code

from fabric import Connection, task
 
@task
def abcd(ctx):
    sudo_pass = getpass.getpass("What's your sudo password?")
    config = Config(overrides={'sudo': {'password': sudo_pass}})
    with Connection('dev-server', user='myuser', connect_kwargs={"password": sudo_pass}, config=config) as c:
        c.sudo('/bin/bash -l -c whoami', user='dev_user')

I get the following output:

fab abcd
What's your sudo password?
[sudo] password: Sorry, user myuser is not allowed to execute '/bin/bash -l -c whoami' as dev_user on dev-server.

Is there a way to get Fabric to do what I did from the command line?

Editing the sudoers file is not an option.

The remote server is Linux RH 7.6.

Wafer answered 11/2, 2019 at 20:15 Comment(0)
I
7

Yes, you can use sudo with a user= argument, to use sudo to switch to another user, just like you are doing in the shell:

from  fabric import Connection

c = Connection('host')
c.sudo('/bin/bash -l -c whoami', user='dev_user')

sudo accepts additional user and group arguments, which are passed to sudo and allow you to run as some user and/or group other than root. On most systems, the sudo program can take a string username/group or an integer userid/groupid (uid/gid); user and group may likewise be strings or integers.

http://docs.fabfile.org/en/1.14/api/core/operations.html?highlight=sudo#fabric.operations.sudo

The above solution will only work if you can run sudo without entering your password. If your account, myuser requires a password to run sudo, then you can prompt for that password, and pass it to fabric's config:

import getpass
from fabric import Connection, Config

sudo_pass = getpass.getpass("What's your sudo password?")
config = Config(overrides={'sudo': {'password': sudo_pass}})
c = Connection('host', config=config)

c.sudo('/bin/bash -l -c whoami', user='dev_user')

http://docs.fabfile.org/en/2.3/getting-started.html#the-sudo-helper

One final idea:

from  fabric import Connection, Config

config = Config(overrides={'sudo': {'user': 'sudo_user'}})
c = Connection('host', config=config)

c.sudo('whoami')

Note that no sudo password is provided in this case, but a user is, in the Config setup. And c.sudo is changed back to a simple c.sudo('whoami'). This should be interpreted as sudo su - sudo_user by Fabric.

Institutional answered 14/2, 2019 at 2:6 Comment(3)
Comments are not for extended discussion; this conversation has been moved to chat. Please edit any relevant information into the answer.Primeval
@CodyGray Thanks, I didn't know about chat.Institutional
OK @CodyGray. Sorry about that. One last comment. doing the follow seems to have worked, but it looks very limited. c.run('echo "whoami" | sudo su - dev_user')Wafer
W
2

The following works:

c.run("echo 'whoami' | sudo su - dev_user")
c.run("echo 'cd /some/directory && ./somescript.sh' | sudo su - dev_user")
Wafer answered 15/2, 2019 at 15:50 Comment(0)
O
0

you can try like this :

conn.run("sudo su root -c 'cd /some/directory && ls -la && ./somescript.sh'")
Ommatophore answered 29/9, 2021 at 8:38 Comment(0)
M
-2

With paython 3x and fabric 2.4.0 you could use it like this

install fabric using pip pip3 install fabric>=2.4.0

from fabric import Connection as connection, task

@task
def executeTask(ctx):
    with connection(host=dev_server, user=myuser) as c:
         c.run('sudo su - dev_user')

Place this code in a file called fabfile.py and run it by executing this command from your command-line fab executeTask.

Muscadel answered 12/2, 2019 at 15:0 Comment(1)
I tried your suggestion but after executing, it just hangs there waiting for me to type in further commands. My goal was to do more c.run calls after the c.run('sudo su - dev_user'), such as c.run('whoami') and it would show the dev_user. i.e. I would like to run the c.run function as a dev_user after sudo-ing to it. Would that be possible?Wafer

© 2022 - 2024 — McMap. All rights reserved.