Fabric: No se puede `context.put` un archivo con `sudo`.

Creado en 14 may. 2018  ·  3Comentarios  ·  Fuente: fabric/fabric

En v2, el parámetro use_sudo=True ya no existe.
Si trato de copiar un archivo en el host remoto, esto es lo que obtengo:

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

Comentario más útil

@geoffrey-eisenbarth Por el momento, no hay un enfoque "bendecido" para esto: vea un poco sobre sudo en http://www.fabfile.org/upgrading.html#file -transfer

Por ahora, querrás hacer algo básico como

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

Todos 3 comentarios

Esto está documentado en http://docs.fabfile.org/en/latest/upgrading.html#id15. Parece que no hay un buen reemplazo de comando único para esto, por ejemplo, no puede usar c.sudo("install … /dev/stdin /path/to/remote") , y parece haber un error en sudo() que impide el uso de tee (nunca termina y simplemente deja el comando colgando esperando la entrada).

Esto es lo que he estado usando para hacer el baile del archivo temporal, que posiblemente es lo que deberías hacer siempre de todos modos para evitar dejar archivos con permisos no deseados:

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}')

Invocado como por ejemplo

<strong i="14">@task</strong>
def install_mount_status_monitor(conn):
    sudo_install(conn, override_file, "/etc/systemd/system/mount_status_monitor.service.d/override.conf")

¿Es esta la ruta esperada para usar al intentar copiar un archivo local a un servidor remoto fuera del directorio de inicio del usuario?

¿Cuál es la forma prevista de usar Fabric y copiar un archivo en, por ejemplo, /etc/nginx/? Estoy tratando de encontrar la forma fabric2 de usar upload_template etc.

@geoffrey-eisenbarth Por el momento, no hay un enfoque "bendecido" para esto: vea un poco sobre sudo en http://www.fabfile.org/upgrading.html#file -transfer

Por ahora, querrás hacer algo básico como

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
¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

Grazfather picture Grazfather  ·  4Comentarios

SamuelMarks picture SamuelMarks  ·  3Comentarios

amezin picture amezin  ·  5Comentarios

26huitailang picture 26huitailang  ·  3Comentarios

supriyopaul picture supriyopaul  ·  4Comentarios