跳转到主要内容

可插拔分布式SSH命令执行器。

项目描述

描述

GSH是Python编写的一个可插拔版本DSH(分布式Shell)。包括一个模块和命令行工具,用于在多台机器上运行shell命令。GSH可以通过添加新的主机加载器和挂钩到运行时各个阶段来扩展。

虽然我计划保持命令行API的稳定性,但模块的接口和插件接口仍在不断发展,我无法保证所有更改都将向后兼容。

安装

新版本将定期更新到PyPI,因此应该像这样简单:

pip install gsh

在Debian/Ubuntu系统上,您需要安装“python-dev”和“libevent-dev”包。

示例

# Run uptime across all nginx machines
gsh -g nginx uptime

# Restart nginx serially
gsh -wg nginx sudo /etc/init.d/nginx restart

# Run w across three manual machines.
gsh -m host1,host2 -m host3 w

配置

大多数默认配置选项都可以通过配置文件覆盖。配置目前指定为YAML文档。以下是一个默认配置的示例:

forklimit: 64
print_machines: true
print_output: true
show_percent: false
concurrent: true
timeout: null
plugin_dirs: []
hooks: []
executor: "ssh"

配置文件从以下位置读取,按读取顺序覆盖:

  • /etc/gsh/gsh.yaml

  • ~/.gsh/gsh.yaml

组文件

默认主机加载器之一(-g)允许您通过名称指定组文件。组文件包含以换行符分隔的主机列表,可选的用户@指定。此加载器将在以下位置搜索这些文件

  • ~/.gsh/group

  • ~/.dsh/group

  • /etc/gsh/group

  • /etc/dsh/group

找到的第一个组文件将生效。加载器将不会继续在所有路径中搜索。当用户输入命令 gsh -g test_hosts uptime 时可能访问的组示例为

/etc/gsh/group/test_hosts bash test_host1.example.com test_host2.example.com # 用户可以指定。注释将被忽略。roleaccount@test_host2.example.com

此相同的文件格式可用于文件加载器(-f),尽管您必须指定完整路径。此加载器更适合操作临时构建的机器列表。

插件

插件是我开始创建GSH的主要原因。在我上一份工作中,我们创建了一个专门与我们的机器数据库工作的DSH替代品。现在,我面临着同样的决定,即直接查询我们的机器数据库。除了主机加载器之外,我还希望能够记录命令。这正是钩子发挥作用的地方。

加载器

加载器是插件,允许您从任意参数构建主机列表。它们应存储在指定的插件目录位置或默认位置/etc/gsh/plugins/loaders。基类BaseHostLoader位于gsh.plugin中,以及位于包本身的gsh/plugins/loaders中的内置插件,是了解如何添加新加载器的好方法。

例如,我目前使用一个提供良好集合算术语法的机器数据库。以下示例显示了将其添加到GSH是多么简单

from mdbset import mdbset

class MdbSetLoader(BaseHostLoader):
    opt_short = "-q"

    def __call__(self, *args):
        return mdbset(*args)

现在,我们可以简单地执行以下操作来获取所有不提供移动服务的nginx机器列表

gsh -q "nginx -nginx-mobile"

虽然加载器的代码确实包含了错误处理,但扩展GSH以提供额外的主机加载机制实际上非常简单。

钩子

钩子的初始概念是在我想将DSH的各种方面记录到我的实时事件日志框架时产生的。对于DSH来说,这很困难,因为我必须解析输出中的各个方面,并不是所有数据都容易暴露。

与加载器一样,它们应存储在指定的插件目录位置或默认位置/etc/gsh/plugins/hooks。基类BaseExecutionHook位于gsh.plugin中,以及位于包本身的gsh/plugins/hooks中的内置插件,是了解如何添加新钩子的好方法。

执行器

执行器允许您更改命令的执行方式。默认的执行系统是通过ssh发送您的命令,这对于大多数人来说应该足够了。

执行器被添加以支持使用密码登录机器或对于需要通过交互式shell发送命令的某些网络设备。

与加载器一样,它们应存储在指定的插件目录位置或默认位置/etc/gsh/plugins/executors。基类BaseExecutor位于gsh.plugin中,以及位于包本身的gsh/plugins/executors中的内置插件,是了解如何添加新执行器的好方法。

理由

在过去的几年里,DSH对我的系统管理员职业生涯来说是无价的,但它有一些随着时间的推移而出现的问题。我总是想以特定于我的环境的方式扩展DSH,通常最终会使用各种包装脚本从库存数据库中加载主机。

我特意选择了Python来完成这个项目,因为我最常使用的语言就是Python,这样我可以将其作为一个模块使用而无需额外安装。虽然基准测试显示GSH的速度较慢,但开销似乎接近恒定。考虑到可扩展性和大部分时间都在等待网络I/O,我认为这是一个合理的权衡。

改进

除了在其他部分提到的加载器和钩子外,GSH相对于DSH提供了一些通用优势。

不指定命令而指定加载器选项(-m/-g等)将列出主机。

很多时候,我只是想看看哪些主机在某个组中。随着我为动态构建主机列表添加了新的主机加载器,这种需求变得更加普遍。在DSH中,如果您未指定命令,它将仅通过SSH连接到您的机器并退出。GSH将在未指定命令的情况下打印出将要使用的主机列表。

可以通过百分比指定fork限制(-F)。

通常,您会在各种主机组上编写服务滚动重启的脚本。您可能指定了一个fork限制为24,却忘记了您的一个较小的Web池比这个限制小,导致它们一次性全部重启,造成故障。您以前的选择是降低限制到最低公倍数或编写令人烦恼的包装脚本。GSH允许您以百分比指定fork限制。例如,gsh -g mobileweb -F 20% “/etc/init.d/nginx restart”

ps输出更清晰/更少分叉混乱。

虽然这听起来像是一个微不足道的好处,但它确实极大地提高了我的生活质量。在DSH中,您会看到与您连接的每个主机相关的3个分叉。这使得在进程挂起时很难找到应该杀死的进程。它还利用了更多的进程,但效果并不明显。以下是一个DSH输出的示例

bash
 \_ dsh -Mcg test_hosts uptime
     \_ dsh -Mcg test_host1 uptime
     |   \_ dsh -Mcg test_host1 uptime
     |       \_ rsh test_host1 uptime
     \_ dsh -Mcg test_host2 uptime
         \_ dsh -Mcg test_host2 uptime
             \_ rsh test_host2 uptime

这是GSH输出的对比

bash
 \_ python gsh -g test_hosts uptime
     \_ ssh test_host1 uptime
     \_ ssh test_host2 uptime

超时!

说到在进程挂起时需要知道要杀死的进程……GSH提供了一个超时选项。虽然设置SSH连接超时很好,但有时命令会无限期地挂起,您想恢复shell。gsh的-t选项将在指定的时间内超时长时间运行进程。不过请注意,这将不优雅地杀死您的命令(-9)。

并发改进。

DSH有一个奇怪的问题,它无法执行fork限制为1的操作。它总是比您指定的主机多一个。我没有复制这种行为。fork限制为1现在等同于串行执行模式。除了这个变化外,我还建立了默认的fork限制为64。DSH默认会通过大量分叉进程来杀死您的机器。这个限制可以通过命令行或个人或系统配置文件覆盖,但是没有选项可以消除这个限制。

常见问题解答

那么GSH代表什么意思?

GSH代表Gary的Shell。主要是因为我不知道该叫什么名字,而且它与DSH相似。而且谁不想拥有一款以自己的名字命名的软件呢。

如何发音GSH?

您可以逐个发音每个字符,或者我们工作中的有些人喜欢叫它“geesh”。geesh中的G发音像gum中的G,而不是J。

项目详情


下载文件

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

源分发

gsh-0.12.4.tar.gz (19.3 kB 查看哈希值)

上传时间

由以下支持

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