执行远程命令或进程。
项目描述
remoto
使用远程主机(ssh、本地、容器等)和Python在远程端执行的一个非常简单的远程命令执行器。
所有繁重的工作都由execnet完成,而此最小API仅提供处理远程端简单日志记录和连接所需的最基本功能。
remoto有点主观,因为它是为了替代ceph-deploy的辅助程序和远程实用工具而构思的,ceph-deploy是一个用于配置和设置分布式文件系统Ceph的远程命令工具。ceph-medic也使用remoto来检查Ceph集群。
示例用法
使用目标是极其简单的,具有一组非常有限的远程进程和日志输出辅助工具和实用工具。
最基本的例子将使用 run 辅助函数在远程端执行命令。它确实需要一个日志对象,至少需要具有 error 和 debug 的对象。这些分别对应于 stderr 和 stdout。
这是传递基本记录器时的样子
>>> 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 辅助函数将分别以 ERROR 和 DEBUG 显示 stderr 和 stdout。
对于其他类型的用法(如检查退出状态码,或在其上引发)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
这个可调用函数允许调用者处理 stderr、stdout 和退出码。它以 3 项元组的形式返回。
>>> from remoto.process import check >>> check(conn, ['ls', '/nonexistent/path']) ([], ['ls: cannot access /nonexistent/path: No such file or directory'], 2)
请注意,stdout 和 stderr 项作为移除了 \n 字符的列表返回。
如果您需要本地处理信息(而不仅仅是触发并忘记,如 process.run 中那样记录),这将非常有用。
远程函数
执行远程函数有两种支持的方式。remoto 用于连接的库(execnet)仅原生支持少数后端,而 remoto 已经扩展了与其他后端连接(如 kubernetes)的能力。
远程功能由 LegacyModuleExecute 和 JsonModuleExecute 提供。默认情况下,ssh 和 local 连接将使用旧版执行类,而其他所有内容都将使用 legacy 类。可以通过设置来强制 ssh 和 local 连接使用新的模块执行
conn.remote_import_system = 'json'
json
docker、kubernetes、podman 和 openshift 的默认模块。它不需要对要执行的模块进行任何魔术操作,但值得注意的是,当将模块发送到远程端执行时,库 将 添加以下部分魔术
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 执行模型(local 和 ssh 连接的默认值)时,模块需要将以下内容添加到该模块的末尾
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的哈希
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 3bad101711b28bb6d339b8e04f835b3645d81735c1f3d496bad8004cd667ade8 |
|
MD5 | d0c7859d690e52eb695091054db8530c |
|
BLAKE2b-256 | 4202a9e5b25538bd12d98c7ea6d277c33e472d1d1d4ec50a4d42be3ca73f6023 |