Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to context.put a file with sudo. #1750

Closed
TimotheeJeannin opened this issue May 14, 2018 · 3 comments
Closed

Unable to context.put a file with sudo. #1750

TimotheeJeannin opened this issue May 14, 2018 · 3 comments

Comments

@TimotheeJeannin
Copy link

In v2, the use_sudo=True parameter doesn't exist anymore.
If I try to copy a file on the remote host, here is what I get:

Traceback (most recent call last):
  File "env/bin/fab", line 9, in <module>
    load_entry_point('fabric==2.0.0', 'console_scripts', 'fab')()
  File "/home/tim/Workspace/wintest/env/lib/python3.5/site-packages/invoke/program.py", line 332, in run
    self.execute()
  File "/home/tim/Workspace/wintest/env/lib/python3.5/site-packages/invoke/program.py", line 480, in execute
    executor.execute(*self.tasks)
  File "/home/tim/Workspace/wintest/env/lib/python3.5/site-packages/invoke/executor.py", line 133, in execute
    result = call.task(*args, **call.kwargs)
  File "/home/tim/Workspace/wintest/env/lib/python3.5/site-packages/invoke/tasks.py", line 127, in __call__
    result = self.body(*args, **kwargs)
  File "/home/tim/Workspace/wintest/fabfile.py", line 131, in nginx
    context.put(StringIO(nginx_conf), remote='/etc/nginx/sites-enabled/website')
  File "/home/tim/Workspace/wintest/env/lib/python3.5/site-packages/fabric/connection.py", line 639, in put
    return Transfer(self).put(*args, **kwargs)
  File "/home/tim/Workspace/wintest/env/lib/python3.5/site-packages/fabric/transfer.py", line 213, in put
    sftp.putfo(fl=local, remotepath=remote)
  File "/home/tim/Workspace/wintest/env/lib/python3.5/site-packages/paramiko/sftp_client.py", line 683, in putfo
    with self.file(remotepath, 'wb') as fr:
  File "/home/tim/Workspace/wintest/env/lib/python3.5/site-packages/paramiko/sftp_client.py", line 341, in open
    t, msg = self._request(CMD_OPEN, filename, imode, attrblock)
  File "/home/tim/Workspace/wintest/env/lib/python3.5/site-packages/paramiko/sftp_client.py", line 780, in _request
    return self._read_response(num)
  File "/home/tim/Workspace/wintest/env/lib/python3.5/site-packages/paramiko/sftp_client.py", line 832, in _read_response
    self._convert_status(msg)
  File "/home/tim/Workspace/wintest/env/lib/python3.5/site-packages/paramiko/sftp_client.py", line 863, in _convert_status
    raise IOError(errno.EACCES, text)
PermissionError: [Errno 13] Permission denied
@acdha
Copy link
Contributor

acdha commented May 17, 2018

This is documented in http://docs.fabfile.org/en/latest/upgrading.html#id15. There appears to be no good single-command replacement for this – e.g. you can't use c.sudo("install … /dev/stdin /path/to/remote") – and there appears to be a bug in sudo() which prevents the use of tee (it never terminates and just leaves the command hanging waiting for input).

Here's what I've been using to do the temp-file dance, which is arguably what you should always be doing anyway to avoid leaving files with unintended permissions:

def sudo_install(connection, source, dest, *, owner='root', group='root', mode='0600'):
    """
    Helper which installs a file with arbitrary permissions and ownership

    This is a replacement for Fabric 1's `put(…, use_sudo=True)` and adds the
    ability to set the expected ownership and permissions in one operation.
    """

    mktemp_result = connection.run('mktemp', hide='out')
    assert mktemp_result.ok

    temp_file = mktemp_result.stdout.strip()

    try:
        connection.put(source, temp_file)
        connection.sudo(f'install -o {owner} -g {group} -m {mode} {temp_file} {dest}')
    finally:
        connection.run(f'rm {temp_file}')

Invoked as e.g.

@task
def install_mount_status_monitor(conn):
    sudo_install(conn, override_file, "/etc/systemd/system/mount_status_monitor.service.d/override.conf")

@geoffrey-eisenbarth
Copy link

geoffrey-eisenbarth commented Jul 17, 2018

Is this the expected route to use when trying to copy a local file to a remote server outside of the user's home directory?

What is the intended way to use Fabric and copy a file into, say, /etc/nginx/? I'm trying to find the fabric2 way of using upload_template etc.

@bitprophet
Copy link
Member

@geoffrey-eisenbarth At the moment there's no "blessed" approach for this - see the bit about sudo under http://www.fabfile.org/upgrading.html#file-transfer

For now, you'd want to do something basic like

c.put("path/to/local/nginx.conf") # implicit to remote $HOME
c.sudo("mv nginx.conf /etc/nginx/") # again implicitly with a CWD of $HOME

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants