Fabric 2.5: Trouble supplying sudo password to target host

Viewed 693

I am trying to learn fabric 2.5 and I am struggling. I have read many pages, trying to ignore the ones referring to older fabric versions.

I run the following and I get The password submitted to prompt '[sudo] password: ' was rejected.

Can someone suggest what am doing wrong?

(f5) albe@vamp398:/srv/file/f5$ fab tt --prompt-for-login-password --prompt-for-sudo-password
Desired 'sudo.password' config value:
Enter login password for use with SSH auth:
Linux vamp398 4.4.0-116-generic #140-Ubuntu SMP Mon Feb 12 21:23:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
albe
[sudo] password: Sorry, try again.
[sudo] password: Traceback (most recent call last):
  File "/srv/file/f5/bin/fab", line 8, in <module>
    sys.exit(program.run())
  File "/srv/file/f5/lib/python3.5/site-packages/invoke/program.py", line 384, in run
    self.execute()
  File "/srv/file/f5/lib/python3.5/site-packages/invoke/program.py", line 566, in execute
    executor.execute(*self.tasks)
  File "/srv/file/f5/lib/python3.5/site-packages/invoke/executor.py", line 129, in execute
    result = call.task(*args, **call.kwargs)
  File "/srv/file/f5/lib/python3.5/site-packages/invoke/tasks.py", line 127, in __call__
    result = self.body(*args, **kwargs)
  File "/srv/file/f5/fabfile.py", line 33, in tt
    c.sudo('whoami')
  File "/srv/file/f5/lib/python3.5/site-packages/invoke/context.py", line 173, in sudo
    return self._sudo(runner, command, **kwargs)
  File "/srv/file/f5/lib/python3.5/site-packages/invoke/context.py", line 226, in _sudo
    raise_from(error, None)
  File "<string>", line 2, in raise_from
invoke.exceptions.AuthFailure: The password submitted to prompt '[sudo] password: ' was rejected.
(f5) albe@vamp398:/srv/file/f5$ a
a: command not found
(f5) albe@vamp398:/srv/file/f5$

My fabfile.py is:

# import getpass
# from fabric import Connection, Config
# from invocations.console import confirm
from fabric import Connection
from invoke import Exit
from fabric import task


# noworky

# env.user = "albe"
# env.password = "a"
# sudo_pass = getpass.getpass("What's your sudo password?")
# config = Config(overrides={'sudo': {'password': sudo_pass}})
# c = Connection(host='192.168.88.64', user='albe', config=config)
# c = Connection(host='192.168.88.64', user='albe')
# c = Connection(host="albe@192.168.88.64")
    # c.sudo('whoami', hide='stderr')
# c = Connection(host="192.168.88.64",user="albe" , connect_kwargs={"password":"a", "sudo.password":"a"})

# maybe works

# c = Connection(host="192.168.88.64",user='albe', connect_kwargs={"password": "a"})

# fab tt --prompt-for-login-password --prompt-for-sudo-password
c = Connection(host='192.168.88.64', user='albe')

@task
def tt(c):
    c.run('uname -a')
    c.run('whoami')
    c.sudo('whoami')

On Ubuntu 16.04 I setup fabric 2.5 like so..

cd /srv/file
sudo apt-get install python3-venv
    python3 -m venv f5
    cd f5
    source bin/activate
echo fabric>>requirements.txt
sudo chown -R albe:  /home/albe/.cache
pip3 install --upgrade pip
pip3 install -r requirements.txt
pip3 list

My pip list is:

(f5) albe@vamp398:/srv/file/f5$ pip3 list
Package       Version
------------- -------
bcrypt        3.1.7
cffi          1.14.1
cryptography  3.0
fabric        2.5.0
invoke        1.4.1
paramiko      2.7.1
pip           20.2.1
pkg-resources 0.0.0
pycparser     2.20
PyNaCl        1.4.0
setuptools    20.7.0
six           1.15.0

These pages seemed the most relevant.

https://docs.fabfile.org/en/2.5/getting-started.html

https://www.fabfile.org/upgrading.html#the-whole-thing

1 Answers

Examples in documentation show how to use Connection() but they always show it without @task because when you use @task then it creates automatically own context with connection using values which you use in command line.

If you put some random values in your c = Connection(...) and use print(c) inside task then you see it doesn't use your c = Connection(...)

kwargs = {
    "password": 'random_password',
}
ctx = Connection(host='random_host', user='random_user', connect_kwargs=kwargs)    

@task
def one(ctx):
    
    print(ctx)
    
    print('connect_kwargs:', ctx['connect_kwargs'])
    print('user:', ctx['user'])
    
    print('sudo user:', ctx['sudo']['user'])
    print('sudo password:', ctx['sudo']['password'])
        
    #ctx.run('uname -a')
    #ctx.run('whoami')
    #ctx.sudo('whoami')

You can eventually create own ctx inside task to replace existing one

def create_ctx():
    password = getpass.getpass("password: ")

    kwargs = {
        "password": password,
    }

    ctx = Connection(host='192.168.88.64', user='albe', connect_kwargs=kwargs)

    return ctx

@task
def two(ctx):
    
    ctx = create_ctx() # replace original `ctx` with own `ctx`

    print(ctx)
    
    print('connect_kwargs:', ctx['connect_kwargs'])
    print('user:', ctx['user'])
    
    print('sudo user:', ctx['sudo']['user'])
    print('sudo password:', ctx['sudo']['password'])
          
    #ctx.run('uname -a')
    #ctx.run('whoami')
    #ctx.sudo('whoami')

You can also replace values in existing ctx

@task
def three(ctx0): #, password='xxx', sudo='yyy'):
    
    password = getpass.getpass("password: ")
    sudo = getpass.getpass("sudo: ")

    ctx['user'] = 'pi'
    ctx['connect_kwargs']['password'] = password
    ctx['sudo']['password'] = sudo
    
    print(ctx)
    
    print('connect_kwargs:', ctx['connect_kwargs'])
    print('user:', ctx['user'])
    
    print('sudo user:', ctx['sudo']['user'])
    print('sudo password:', ctx['sudo']['password'])
          
    #ctx.run('uname -a')
    #ctx.run('whoami')
    #ctx.sudo('whoami')

Code works for me if I use

 fab tt --prompt-for-login-password --prompt-for-sudo-password

or with parameters as first (which should set global values)

 fab --prompt-for-login-password --prompt-for-sudo-password  tt

so I can only guest you wrote wrong password.

Related