识字DevOps

2020-08-30 16:52:32

最近,我一直在玩弄使第一阶段更接近第二阶段。因为找不到更好的词,我把它叫做“识字的德沃普斯”。

我已经谈到过使用组织模式的识字编程模型来研究新想法和明确思想,由于我缺乏那些深奥的系统管理技能,这种方法似乎对我很有效。

曾几何时,我的任务是修补RPM,它不在我的舒适区,所以我最初的攻击计划是:

当然,一旦我找到了解决方案,我就需要为我团队中的其他人记录下来,也许还需要创建一个可重复的脚本。

第一步在其他地方有很好的文档记录,但是今天我了解到(直到)您可以使用这个小魔术直接ssh到您的基于Vagant的虚拟机(注意:Client是我在Vagrant文件中指定的虚拟机的名称):

我没有向我的虚拟机打开终端,而是弹出Emacs并加载这个Sprint的备注文件1,创建一个新的头文件,然后在这个文本文件中输入shell和ruby命令。

这有什么用呢?与传统的终端不同,它允许我记录、记录和执行每条命令。

作为一只头脑贫乏的老熊,我的散文可以解释每一个命令的背景和目的。点击超链接使我对以前的发现记忆犹新。键弦执行代码块…

按下C-c C-c(Control-C键两次)运行代码(基于语言)。此示例在shell中运行。结果被放回文件中,其他代码块(和许多其他选项)可以使用该文件。

例如,下面是从存储库下载GPG密钥的部分的前半部分(URL放在他的部分中的所有代码块共享的属性中):

Shell脚本块(在屏幕截图的中心)使用wget下载HTML索引文件,并解析和提取密钥文件URL。我们将使用Ruby脚本进行解析,由于TheScript可能有点麻烦,我们将在另一个代码块中定义它。

识字编程的一种技术是可以将一个码块插入到另一个块中(引用的是双尖括号内的名称,<;<;...>;>;)。唐纳德·努斯称这是特写网站。因为它可能意外地与某些语言(如Ruby)冲突,所以我默认将其关闭,但在此块中使用noweb参数将其打开。

以下是Ruby脚本。将其放在单独的特定于Ruby的代码块中,使我可以启用Emacs可以实现的所有Ruby魔力。

最后一步是将第一个脚本生成的URL提供给另一个Shell脚本,该脚本将调用wget来下载每个URL:

键列表是我们的原始代码块的名称,也是其结果的名称。我们将结果列表分配给可用列表,shell脚本将以$LIST形式访问该列表。

通常,将sh指定为代码块的语言会告诉Emacs在本地系统的shell中运行代码,但在本例中,我希望它在我的虚拟机上(或在我实验室的开发服务器上)运行。我将描述执行此操作的两个选项,使用Tramp和Babel Sessions。

Tramp是Emacs的一项功能,允许用户使用ssh和其他协议在远程机器上编辑文件。例如,运行find-file函数(绑定到C-x C-f)允许您键入类似以下内容:

并更新~/.ssh/config文件以了解主机名对应的用户帐户,则可以将上面的文件引用缩短为:

Emacs查找:字符以确定是否应该调用Tramp。Tramp使用SSH密钥(如果可用),或者在需要时提示您输入密码。

每个组织模式代码块都可以指定一个:dir选项,该选项指定代码段应该运行的位置,例如,以下块是等效的:

:dir选项允许完整的Tramp功能,使我可以在不同的机器上运行块。还记得我是如何将Client Vagant虚拟机添加到~/.ssh/config文件的吗?

我的工作是处理在高度受保护的数据中心运行的虚拟机,在那里我需要首先登录跳箱和堡垒机器。流浪汉处理这类跳跃。例如:

使用我的帐户名称登录堡垒计算机,然后使用我的帐户名称ssh到在私有云中运行的虚拟机。然后使用sudo命令让我编辑root拥有的文件。

除最后一跳之外的所有跃点都使用竖线字符|,而不是冒号字符:

如果使用管道字符,则需要指定所有协议,如ssh,即使它是默认协议。

如果您的本地计算机的操作系统与您连接的计算机不同,您需要在组织模式下修复一个错误,我可以向您展示如何修复2。

另一种方法是创建将不同代码块连接在一起的会话。下面的每个屏幕截图,下面的每个代码块都有相同的会话值client(方便地说,它与我的虚拟机的主机名client相同):

如果我执行第一个块,就会在后台启动一个shell,然后它就会进入机器。注意,要使其正常工作,您需要通过将SSH的公钥放入远程系统的.ssh/Authorized_keysfile中或使用ssh Emacs包来启用无密码访问。3个。

从现在开始,我使用clientsession值执行的每个代码块都使用这个连接,并且代码在远程机器(本例中是虚拟机,但这无关紧要)上执行。

这两种方法都工作得很好,但是第二种方法允许我设置变量来创建其他块可能期望的特定状态。但是,这需要按顺序执行每个块。

我有第三个更具交互性的方法4,使用Screen,但是它不允许将变量传递给代码,正如您将在下面看到的,这对我非常重要。

无论如何,我继续学习如何实现我的目标,同时记录和验证我的步骤。最终结果可以导出到网页或维基页面。

是的,执行一些命令可能相当耗时和冗长,但我经常需要搜索结果,将结果放在Emacs缓冲区中可以更好地搜索。

我经常使用可折叠的“抽屉”(这只是一种识别输出开始和结束的方式):

将光标放在此抽屉上,然后按Tab键隐藏或显示输出:

下一个命令通常需要一些命令的结果,我相信您一定很喜欢用鼠标复制和粘贴输出的一部分,但是我有一个更好的方法。

请注意,我将该源代码块命名为。还要注意Emacs如何自动将结果分解到一个表中。默认情况下,shell命令的输出按换行符和空格拆分。

我可以将这些执行的结果提供给另一个代码块,下面的源代码块创建一个名为Dependents的变量,该变量使用第一列的第2到10行作为数组。

重用DEVOP程序(如Chefcookbook)的一个关键方面是将代码与代码使用的值分离(…。这是您重用的任何程序的一个关键方面。

在我的世界里,我为每个Sprint创建一个新的组织模式文件,每个任务或问题都有自己的标题和部分。每一节可以有一个属性抽屉,包括该节中所有代码块共享的变量。

要创建一个SECTION变量,只需点击:c-c C-xp,并将属性设置为var,将值设置为变量=value,如下所示:

此抽屉可以包含您想要的任何代码块值,如Session或Results。然后,可以在代码块上覆盖这些值的资产,如您在此屏幕截图中所见:

虽然运营和管理方面的调查(正如我已经描述过的)在理解问题领域时对自己很有用,但我需要与我的团队伙伴交流结果。由于我的Emacs配置允许我发送邮件消息,因此我启动了函数org-mime-org-buffer-htmlize,该函数将组织模式文件导出为HTML邮件消息(此函数是最新的org-plus-contrib包的一部分)。

例如,一些块可能会产生一些JSON数据,由于HTML输出可以使语法着色,如果我可以指定输出结果是JavaScript,那么JSON数据会漂亮得多。只需使用WRAP参数,如下所示:

再举一个例子,我当前的项目涉及使用OpenStack,它的nova命令行实用程序尝试将数据格式化为atable:

+--+。-+|ID|名称|状态|任务状态|电源状态|网络|+--+。-+|f9e7aed8-e425-4808-aace-8758dadd91bf|chefserver|active|-|运行|wpc-private=10.0.1.73||0432f8b1-7e6d-4fc1-b181-02fa768c38ac|ha-culte1|active|--|运行|wpc-private=10.0.1.104|。--|运行中|wpc-private=10.0.1.99||89a89d1f-7be5-4c4f-82db-64b751f15f3b|ha-Controller 3|active|-|运行中|wpc-private=10.0.1.100||b740095a-3f89-45d0-a2a1-9cfcadfb4ca3|ha-监控|active|-|运行中|wpc-private=10.0.1.95。-控制器2|ACTIVE|-|正在运行|wpc-private=10.0.1.102||7aab184c-5fb4-4996-8ab2-8a65ea7668cb|ha-sdn-Controler3|ACTIVE|-|正在运行|wpc-private=10.0.1.103||0c90d7b0-dab4-4af8-a970-e2e90dd8b9e4|ha-storage-1|active|-|正在运行|。-b3d4-6014d242403a|ha-storage-3|ACTIVE|-|正在运行|wpc-PRIVATE=10.0.1.96||bc5ad0fe-9ef2-4966-8d2b-99892f3f94cd|yum-server|ACTIVE|-|正在运行|wpc-PRIVATE=10.0.1.74|+--+-+。-+----+。

如果手动更改输出,则导出文件时不会执行这些更改(因为在导出过程中会重做这些更改)。

实现这一点的方法是使用一个小小的Emacs Lisp代码块,您只需将其放在文件中的某个位置,如下所示:

使用名为nova-conv的代码块,我可以使用它对结果进行后处理,如下所示:

在我特定情况下,我还想去掉第一行破折号,使其更像组织模式:

要实现真正的可重用,请将此代码放入您的巴别塔库中,然后它就可以从任何文件中使用。

虽然我识字的devops方法不应该取代真正的devops(OpsDev?)。自动化,我发现这种方法很有用,原因有两个:

关于最后一点,我经常用过去式编写识字文件,甚至在我编写和执行代码之前也是如此,如下所示:

然后,如果我遵循的命令或过程失败,我可以简单地突出显示文档的一部分,按C-xM将导出的HTML版本通过电子邮件发送给团队其他成员(否则,我会花费数小时从终端复制/粘贴回来,以便为电子邮件提供有效的上下文)。

需要完整的示例吗?查看我关于设置IP表的注释(和原始的组织模式文件),其中文件的一部分可以在编辑器中执行,以查看我的机器是如何配置的,另一部分是一个脚本,它可以纠缠到机器上并执行以重置为防火墙规则。

1对于每个新的Sprint,我创建一个组织模式格式的文件来跟踪任务、笔记和其他细节。这使得它非常理想地嵌入了一些识字的devop。

2每个操作系统在不同的目录位置创建临时文件。大多数Unix系统使用/tmp/,但Mac使用/var/Folders/。当前的组织模式代码在远程系统上使用与在本地系统上相同的目录名。在MyCase中,我使用工作中的Mac笔记本电脑连接到数据中心的Linux系统,出现以下错误:

Tramp:使用`base64-d-i>;%s&39;解码远程文件`/ssh:x.y.z:/var/folders/0s/pcrc3rq5075gj4tm90pbh76c36sl1h/T/ob-input-32379ujY';失败...失败的字节代码:无法使用`base64-d-i>;%s&39;将区域写入`/ssh:x.y.z:/var/folders/0s/pcrc3rq5075gj4tm90pbh76c36sl1h/T/ob-input-32379ujY';,解码失败。

正如我在这篇邮件列表帖子中发现的那样,该bug是在组织模式版本8.2.10(可能更早)中发现的(它可能会在一段时间内无法修复,因为还不清楚最好的解决方案是什么)。要自己修复它,请将org-babel-temp-filefunction中的ob-core.el文件编辑为:

(deFun org-babel-temp-file(前缀&;可选后缀)";在`org-babel-Temporary-directory';目录中创建一个临时文件。将前缀和后缀直接传递给`make-temp-file';,值为`临时文件目录';临时设置为`org-babel-临时-directory';.";(if(file-remote-p default-directory)(let((前缀;;我们不能将`临时文件目录';用作本地部分;;,因为远程主机上可能是另一个OS;;所以不能使用`临时文件目录';作为本地部分;。因此,我们假设";/tmp";,它应该存在于;;相关的体系结构上。(CONCAT(file-remote-p default-directory);;将临时文件目录替换为/tmp:(扩展文件名前缀";/tmp/";)(make-temp-file前缀为零后缀))(let((临时文件目录(或(和(绑定';Org-Babel-Temporary-directory)(FILE-EXISTS-P org-Babel-Temporary-directory)org-Babel-Temporary-directory)(make-temp-file前缀无后缀)。

3如果安装ssh.el项目,则最初将使用m-x ssh连接到远程系统。

然后输入主机连接信息,包括密码(如果需要)等。例如,如果我连接到我的主机:goblin.howardism.org,那么我的代码块将引用如下会话:

这允许您监视您的代码在远程系统上执行,但仍然允许功能齐全的代码块可以从组织模式文件的其他部分读取值。

注意:SESSION参数的值用*字符括起来(缓冲区名称的一部分),但是要传递的变量用引号括起来(否则,它们会被解释为对文档中其他地方的表的命名引用)。

4我还有第三种执行远程命令的方法,它使用ob-screen扩展(位于org-mode ContribCollection中)。它同时使用Gnu Screen和xTerm,因此在我的Mac上,iStart XQuartz(内置的X Windows模拟器),并将以下内容添加到我的.emacs初始化(基于这些说明),以设置我的xTerm程序的完整路径:

代码块现在被指定为Screen,我通常通过设置:session参数来指定使用哪个xterm窗口:

结果不会放到我的Emacs文件缓冲区中,而只是简单地保留在xterm窗口中。

使用Screen的另一个缺点是它不传递不变变量。例如,以下内容不起作用:

在xterm窗口中看到来回的结果很不错,但是不能将结果带回文件进行进一步处理是有限的。此外,您必须抵制通过在xterm窗口中键入来修复命令的诱惑。如果你沿着这条路走下去,你可能会忘记把这些信息放回你的组织模式文件中,以后可能会后悔。