7

我正在尝试在 Python 3 中创建一个构造,它可以让我轻松地在远程机器上执行一个函数。假设我已经有了一个 python tcp 服务器,它将运行它接收到的函数,在远程服务器上运行,我目前正在考虑使用像这样的装饰器

@execute_on(address, port)

这将创建执行它正在装饰的函数所需的必要上下文,然后将函数和上下文发送到远程机器上的 tcp 服务器,然后执行它。首先,这有点理智吗?如果没有,你能推荐一个更好的方法吗?我做了一些谷歌搜索,但没有找到任何满足这些需求的东西。

我已经为 tcp 服务器和客户端提供了一个快速而肮脏的实现,因此相当确定它会起作用。我可以得到一个字符串表示的函数(例如func)被传递给装饰器

import inspect
string = inspect.getsource(func)

然后可以将其发送到可以执行的服务器。问题是,如何获取函数执行所需的所有上下文信息?例如,如果 func 定义如下,

import MyModule
def func():
    result = MyModule.my_func()

MyModule 需要可用于在全局上下文中运行或在远程服务器上运行本地上下文。在这种情况下,这是相对微不足道的,但根据何时以及如何使用 import 语句,它可能会变得更加复杂。在 Python 中是否有一种简单而优雅的方法来做到这一点?目前我想出的最好的方法是使用 ast 库提取所有导入语句,使用检查模块获取这些模块的字符串表示,然后在远程服务器上重建整个上下文。不是特别优雅,我可以看到很多错误的空间。

谢谢你的时间

4

5 回答 5

3

您概述的方法非常危险,除非远程服务器受到某种非常强大的保护或“极度沙盒”(例如 BSD“监狱”)——任何可以向它发送函数的人都可以在那里运行任意代码。

假设您有一个完全信任的身份验证系统,就会出现您意识到的“脆弱性”问题——该函数可以依赖于执行时在其模块中定义的任何全局变量(这可能与您可以通过检查检测到的不同) :在执行时确定导入模块的集合,更一般地说是全局变量,是一个图灵完备的问题)。

您可以通过序列化函数的全局变量以及函数本身来处理全局变量问题,在您将其发送到远程执行时(无论您是否以可读字符串形式序列化所有这些内容,或者以其他方式,都是一个小问题) . 但这仍然会给您留下函数内部执行的导入问题。

除非您愿意对“远程”函数施加一些限制,例如“函数内部没有导入(以及从中调用的函数)”,否则我认为您可以让服务器覆盖__import__(内置函数被所有 import 语句使用,并被设计为满足特殊需求,例如您的需求;-) 从发送客户端请求额外的模块(当然,这要求所述客户端也具有“类似服务器”的功能,因为它必须能够响应来自服务器的此类“模块请求”)。

你不能对远程功能施加一些限制,以使这项任务回到理智的领域......?

于 2010-06-03T00:30:51.320 回答
3

您可能对execnet项目感兴趣。

execnet 提供了经过仔细测试的方法,可以跨版本、平台和网络障碍轻松地与 Python 解释器交互。它具有针对以下用途的最小且快速的 API:

  • 将任务分发到本地或远程 CPU
  • 编写和部署混合多进程应用程序
  • 编写脚本来管理一堆 exec 环境

http://codespeak.net/execnet/example/test_info.html#get-information-from-remote-ssh-account

我看过它的演示。但我自己从来没有用过。

于 2010-06-03T04:49:22.160 回答
1

从您的问题中不清楚是否存在一些系统限制/要求以这种方式解决您的问题。如果不是这样,使用某种消息传递基础设施可能会更容易和更快地做到这一点。

例如,您可能会考虑是否 [Celery][1]

[1]:http ://ask.github.com/celery/getting-started/introduction.html 将满足您的需求。

于 2010-06-03T08:06:05.900 回答
0

你的最终目标是什么?从您的描述中,我看不出为什么您不能创建一个简单的消息传递类并发送该类的实例来命令远程机器执行“工作”..?

无论你做什么,你的远程机器都需要 Python 源代码来执行,那么为什么不在那里分发代码然后运行它呢?您可以创建一个简单的服务器来接受一些 python 源文件,提取它们导入相关模块,然后运行命令?

于 2010-06-03T00:28:08.063 回答
0

这可能很难做到,并且您会遇到安全性、参数等问题。也许您可以远程运行 Python 解释器,可以使用套接字或 HTTP 服务给定代码,而不是逐个函数地执行等级?

于 2010-06-03T05:16:01.060 回答