跳转到主要内容

执行远程命令或进程。

项目描述

remoto

使用远程主机(ssh、本地、容器等)和Python在远程端执行的一个非常简单的远程命令执行器。

所有繁重的工作都由execnet完成,而此最小API仅提供处理远程端简单日志记录和连接所需的最基本功能。

remoto有点主观,因为它是为了替代ceph-deploy的辅助程序和远程实用工具而构思的,ceph-deploy是一个用于配置和设置分布式文件系统Ceph的远程命令工具。ceph-medic也使用remoto来检查Ceph集群。

示例用法

使用目标是极其简单的,具有一组非常有限的远程进程和日志输出辅助工具和实用工具。

最基本的例子将使用 run 辅助函数在远程端执行命令。它确实需要一个日志对象,至少需要具有 errordebug 的对象。这些分别对应于 stderrstdout

这是传递基本记录器时的样子

>>> conn = remoto.Connection('hostname')
>>> run(conn, ['ls', '-a'])
INFO:hostname:Running command: ls -a
DEBUG:hostname:.
DEBUG:hostname:..
DEBUG:hostname:.bash_history
DEBUG:hostname:.bash_logout
DEBUG:hostname:.bash_profile
DEBUG:hostname:.bashrc
DEBUG:hostname:.lesshst
DEBUG:hostname:.pki
DEBUG:hostname:.ssh
DEBUG:hostname:.vim
DEBUG:hostname:.viminfo

run 辅助函数将分别以 ERRORDEBUG 显示 stderrstdout

对于其他类型的用法(如检查退出状态码,或在其上引发)remoto 也提供了这些。

远程命令

process.run

可以通过几种不同的方式调用远程命令。最简单的一种是使用 process.run

>>> from remoto.process import run
>>> from remoto import connection
>>> Connection = connection.get('ssh')
>>> conn = Connection('myhost')
>>> run(conn, ['whoami'])
INFO:myhost:Running command: whoami
DEBUG:myhost:root

但是请注意,您并没有捕获远程端的结果或信息。这里的目的是能够运行一个命令并记录其输出。这是一个 fire and forget 调用。

process.check

这个可调用函数允许调用者处理 stderrstdout 和退出码。它以 3 项元组的形式返回。

>>> from remoto.process import check
>>> check(conn, ['ls', '/nonexistent/path'])
([], ['ls: cannot access /nonexistent/path: No such file or directory'], 2)

请注意,stdoutstderr 项作为移除了 \n 字符的列表返回。

如果您需要本地处理信息(而不仅仅是触发并忘记,如 process.run 中那样记录),这将非常有用。

远程函数

执行远程函数有两种支持的方式。remoto 用于连接的库(execnet)仅原生支持少数后端,而 remoto 已经扩展了与其他后端连接(如 kubernetes)的能力。

远程功能由 LegacyModuleExecuteJsonModuleExecute 提供。默认情况下,sshlocal 连接将使用旧版执行类,而其他所有内容都将使用 legacy 类。可以通过设置来强制 sshlocal 连接使用新的模块执行

conn.remote_import_system = 'json'

json

dockerkubernetespodmanopenshift 的默认模块。它不需要对要执行的模块进行任何魔术操作,但值得注意的是,当将模块发送到远程端执行时,库 添加以下部分魔术

if __name__ == '__main__':
    import json, traceback
    obj = {'return': None, 'exception': None}
    try:
        obj['return'] = function_name(*a)
    except Exception:
        obj['exception'] = traceback.format_exc()
    try:
        print(json.dumps(obj).decode('utf-8'))
    except AttributeError:
        print(json.dumps(obj))

这允许系统执行 function_name(用要执行的函数及其参数替换),获取任何结果,用 json 序列化并将它们发送回本地处理。

如果您有一个名为 foo 的模块中的函数,看起来像这样

import os

def listdir(path):
    return os.listdir(path)

要能够远程执行该 listdir 函数,您需要将模块传递给连接对象,然后调用该函数

>>> import foo
>>> conn = Connection('hostname')
>>> remote_foo = conn.import_module(foo)
>>> remote_foo.listdir('.')
['.bash_logout',
 '.profile',
 '.veewee_version',
 '.lesshst',
 'python',
 '.vbox_version',
 'ceph',
 '.cache',
 '.ssh']

请注意,要远程执行的函数 不能 接收对象作为参数,只能接收常规 Python 数据结构,如元组、列表和字典。还可以安全使用整数和字符串。

legacy

在使用 legacy 执行模型(localssh 连接的默认值)时,模块需要将以下内容添加到该模块的末尾

if __name__ == '__channelexec__':
    for item in channel:
        channel.send(eval(item))

此代码段与 json 执行模型完全兼容,不会引起冲突。

自动检测 ssh 连接

存在自动检测,以确定是否需要远程连接(通过SSH)或不需要,这是通过当前主机的hostname(与连接的主机相比)推断出来的。

如果本地主机与远程主机名相同,将通过Popen打开本地连接,并将使用该连接而不是ssh,以避免能够SSH到同一主机的问题。

自动检测是否使用sudo

可以通过在Connection类中使用detect_sudo标志来启用这种神奇的检测。默认情况下是禁用的。

启用后,将任何命令都添加前缀为sudo。这对于需要超级用户权限的库很有用,并希望避免在所有地方传递sudo,这在处理通过SSH连接的root用户时可能很复杂。

项目详情


下载文件

下载适用于您平台文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分布

remoto-1.2.1.tar.gz (18.6 kB 查看哈希

上传时间

支持者

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面