在阿里巴巴实习期间,由于各种机缘巧合,我开始专注于研读配置自动化管理软件 Puppet 。这项工作持续了两个月,期间我在内网发布过多篇技术文章,详细地剖析 Puppet 的运行原理。业已实习完毕,所有的技术文档、演示幻灯以及部分实例源码,均已通过阿里巴巴对外数据披露备案,被允许向开源社区分享这些技术文档。社区曾给了我很多帮助,我想,现在是时候我向社区尽一些绵薄之力了。

虽然没有把 Puppet 多达 10 万行的源码彻底地分析清楚,但大致的脉络已经理清。整个系列文集将会以《Puppet Hacking Guide》为总标题(致敬《Ruby Hacking Guide》),解释 Puppet 3.X 版本的内部运行原理,为用户定制 Puppet 提供指导。整个系列以我在阿里巴巴内部发表的文章为草稿,重新组织整理,以期能以一种清晰的思路引导读者理解 Puppet 源码。

尽管本文几经修改,但笔者才疏学浅,难免有所纰漏,欢迎各位指正!另外,出于职业道德,我不能向各位透露以下信息,也请各位不要打听,见谅:

  1. Puppet 在阿里巴巴内部的使用场景;
  2. 阿里巴巴所使用的 Puppet 具体版本号;
  3. 阿里巴巴所采用的 Puppet 体系架构;

另外,如果读者所在公司有定制 Puppet 的需求,可以联系我,我可以在研究需求后,给出一些可行的方案。

Acknowledgment

本系列文集是在我受雇于阿里巴巴期间撰写的一系列技术文档重新整理而成,其版权属于阿里巴巴公司以及我本人。经雇主同意,现特许以技术交流为目的,在开源技术社区分享此文集。

因此您可以:在保留原作者 DeathKing 以及阿里巴巴-技术保障部署名的情况下,以学习交流为目的,以非盈的形式将本文以电子版或印刷版的形式分发给您的朋友,或者转载到任何一个开源社区;

以下行为是禁止的:

  1. 以盈利为目的,将文章转载到微信公众号等媒体平台;
  2. 去掉原作者 DeathKing 以及阿里巴巴-技术保障部的署名,以自己的名义发布本文集;

请在转载时,保留以下署名:

  1. 本系列文章作者 DeathKing
  2. 阿里巴巴技术保障部

Puppet 的启动:子命令

Puppet 的启动方式

Puppet Agent 通常通过命令行触发,而 Puppet Master 即可以通过命令行方式触发,以 WEBrick 服务器模式运行,也可以通过设置 config.ru 文件,以 Rack 中间件的形式运行。

下面的命令可以让 Puppet Master 以 WEBrick 服务器的模式启动,选项 --no-daemonize 可以阻止 Master 的后台化,在测试的时候,我们通常添加一个 --debug 选项用以设置日志等级,让 Puppet 显示更多有用的信息方便系统管理员进行调试:

$ puppet master --no-daemonize --debug

下面的命令可以启动 Agent 使之与 Master 进行通信并完成一次完整的工作流。与默认的 Agent 与 Master 每30分钟同步一次不同,选项 --onetime 使得 Agent 与 Master 只进行一次同步,完成后立即退出。

$ puppet agent --no-daemonize --debug --onetime

要了解 Master 和 Agent 的启动过程,就需要先知道 Puppet 中子命令的概念,使用 puppet help 可以查看 Puppet 的使用帮助:

$ puppet help Usage: puppet <subcommand> [options] <action> [options]Available subcommands:agent             The puppet agent daemonapply             Apply Puppet manifests locallyca                Local Puppet Certificate Authority management. # 有意省略了整个列表。

从使用帮助中,我们不难看出,跟在 puppet 命令后的参数被称作子命令(subcommand)。子命令通常对应了一个 Ruby 脚本文件或外部可执行文件。事实上,不单 agent 和 master 分别是一个 Puppet 子命令,连 help 也是 Puppet 的一个子命令,对应的是 lib/puppet/application/help.rb 文件。Puppet 将不同的功能模块抽象为子命令,并将这些子命令实现为不同的文件,这样实现和管理起来更为方便。

子命令分类

Puppet 子命令可以分为四类:

  • 空子命令:调用 Puppet 时,如果没有指定任何子命令,Puppet 则认为调用的是空子命令;
  • 应用子命令:存放在 puppet/application 文件夹中的脚本所对应的命令。需要注意的是,这是一个相对路径,Puppet 会在多个路径中搜索该相对路径下的文件。这类子命令的典型的代表是 agent、master 和 config 等;
  • 外部子命令:存放在环境变量 PATH 所指示的文件夹中、以 puppet- 开头的文件所对应的命令。例如,命令行调用 puppet foo 会使 Puppet 在环境变量 PATH 所指示的文件夹中搜寻名为 puppet-foo 的可执行文件;
  • 未知子命令:不是上述命令的其他子命令,Puppet 都将其视作未知子命令;

子命令的查找与加载

以命令行调用 Puppet 时,实际执行的是 bin\puppet 。作为整个系统的入口,这个文件却只有简单的几句代码:

  • 文件:bin\puppet
#!/usr/bin/env ruby # For security reasons, ensure that '.' is not on the load path # This is primarily for 1.8.7 since 1.9.2+ doesn't put '.' on the load path $LOAD_PATH.delete '.' require 'puppet/util/command_line' Puppet::Util::CommandLine.new.execute

bin\puppet 主要实例化了一个 Puppet::Util::CommandLine 对象,这个对象主要用于理清 Puppet 的调用信息:调用的是哪个命令、有哪些命令行选项等。在后面的章节中我们会发现,如果以 Rack 中间件的方式启动 Puppet Master ,会用到一些 trick ,这也是CommandLine 存在的原因。

CommandLine 对象实例化完毕后,execute 方法被执行。在这个方法中,最重要的是 find_subcommand.run 语句。

  • 文件:lib/puppet/util/command_line.rb
def execute Puppet::Util.exit_on_fail("initialize global default settings") do Puppet.initialize_settings(args) end setpriority(Puppet[:priority]) find_subcommand.run end

CommandLine 类的私有方法 find_command 是理解整个启动机制的关键点,Puppet 在这个方法中,通过一些规则确定子命令的分类,然后再调用子命令对应的类,加载对应的文件。

  • 文件:lib/puppet/util/command_line.rb
private def find_subcommand if subcommand_name.nil? NilSubcommand.new(self) elsif Puppet::Application.available_application_names.include?(subcommand_name) ApplicationSubcommand.new(subcommand_name, self) elsif path_to_subcommand = external_subcommand ExternalSubcommand.new(path_to_subcommand, self) else UnknownSubcommand.new(subcommand_name, self) end end

需要强调的是,Puppet 并不是根据命令的分类去查找文件,而是根据文件查找的结果,确定命令的分类,理解这一点很重要。在深入每句代码内部之前,我们应该对 find_subcommand 方法的模式有个大概认知:查找方法,然后实例化一个对应类的对象。比较令人疑惑的是,用于实例化的参数中有一个 self 。这里的 self 就是 CommandLine 对象,我们之前已经说过,CommandLine 对象已经理清了命令行调用的信息,因此我们可以在每个 Subcommand 对象中,通过 CommandLine 对象获得调用的命令行参数等信息。

Puppet 的命令分类我们已经在前面描述了,接下来,我们将详细地讨论查找的规则。由于空子命令和未知子命令的代码比较简单,我们先行介绍,接着我们将介绍外部子命令,我们最后再来分析最为复杂的内部子命令。

转载于:https://my.oschina.net/Qm3KQvXRq/blog/509116

【天赢金创】Puppet Hacking Guide —— Puppet 的启动:子命令相关推荐

  1. 【天赢金创】10 条真心有趣的 Linux 命令

    在终端工作是一件很有趣的事情.今天,我们将会列举一些有趣得为你带来欢笑的Linux命令. 1. rev 创建一个文件,在文件里面输入几个单词,rev命令会将你写的东西反转输出到控制台. # rev & ...

  2. 【天赢金创】前后分离架构的探索之路

    大约五年前,那时候我还是一个小小讲师(苹果 AATC 培训认证),完全不懂编程为何物的菜鸟,一个偶然的机会让我进入了公司的开发部门,任职什么呢?用户体验设计师,原因很操蛋--我以前干过广告设计,做过餐 ...

  3. 【天赢金创】Reflux学习指南

    这个是 simple Todo with React and2 的第二部 - Reflux 第一部可以看 simple Todo with React and Flux1 也可以看 学习flux的一些 ...

  4. 【天赢金创】探究Gulp的Stream

    来自Gulp的难题 描述Gulp的项目构建过程的代码,并不总是简单易懂的. 比如Gulp的这份recipe: var browserify = require('browserify'); var g ...

  5. 【天赢金创】Crystal 语言

    Beautiful Syntax, Faster Than Go 它和 Mirah, JRuby, Groovy 等等的区别是: 它不需要 JVM 这个平台, 没有字节码和解释器. 很容易在速度上超过 ...

  6. 【天赢金创】React flux九浅一深

    这个是 Facebook 官方学习 Flux 的 todo 例子 想用这个例子来总结一下怎么从零开始用 React 和 Flux 构建一个 App Structure App ├─ javascrip ...

  7. 【天赢金创】我是如何看待React 组件开发

    从 auto-ellipsis 看 React 组件开发 auto-ellipsis 是一个用于解决文本超长溢出截断并加 ... 的 React 组件. 关于 React 随着 React 的火热,随 ...

  8. 【天赢金创】算法复杂度分析

    原文:http://www.cnblogs.com/gaochundong/p/complexity_of_algorithms.html 为什么要进行算法分析? 预测算法所需的资源 计算时间(CPU ...

  9. 【天赢金创】面向对象的程序设计之创建对象

    对象的定义:无序属性的集合,属性的值可以是基本值.对象或者函数. 每个对象都是基于一个应用类型创建的,这个引用类型可以是内置的(例如Object Array Math),也可以是用户自定义的. 基于O ...

最新文章

  1. app微信支付的集成步骤
  2. wine运行exe程序只出现了一个黑色长方形
  3. CSS基础----元素分类
  4. AWS拓展中国合作伙伴生态 加速企业数字化转型进程
  5. CISCO PVST+配置和结果验证 per vlan spanning tree(51cto 实验10)
  6. linux中利用shell脚本条件执行linux命令
  7. STM32F103 mbed输出互补pwm
  8. 网络流量监测IP雷达 4.0
  9. python删除图片文字_ps去掉图片上的文字的6种方法
  10. 计算机硬件基础——第七章:存储系统
  11. 使用Eclipse编译运行MapReduce程序
  12. Java获取时间,将当前时间减一天、一月、一年,并加以格式化
  13. Elasticsearch6.8开发指南-第三章-设置Elasticsearch
  14. mysql 查询分析器_mysql查询分析工具|mysql查询分析器(MySQL Query Browser)下载v1.1.20 官方版_ IT猫扑网...
  15. python info函数的使用方法_sysinfo函数使用方法
  16. Python实现线性回归和梯度下降算法
  17. GLES2.0中文API-glGetUniformLocation
  18. JQuery DataGrid 中文文档
  19. 鸿蒙系统魅族,魅族宣布接入鸿蒙系统
  20. Win10回收站清空了怎么恢复?3个简单高效的方法

热门文章

  1. SaaS-IHRM 项目-Activiti7基础原理与使用 工作流引擎 工作流使用
  2. Ubuntu/linux下最强大的下载工具-aria2
  3. 前世我欠你一滴眼泪....
  4. 邮件列表的文化与礼节 (转)
  5. 开发一对一视频直播App需要哪些技术
  6. 学python人工智能电脑要什么配置_本人是大一人工智能专业,不打游戏,我们需要学习C++和Python。用什么配置的笔记本电脑比较好?...
  7. Swift 之添加点击事件
  8. JS获取鼠标光标位置并在光标位置添加内容
  9. python多线程爬取段子_python爬虫(爬取段子)
  10. 这几种游戏配音教程分享给你