Puppet Agent源码分析之Agent启动和Run Rest-API的实现

1 分钟读完

Puppet Agent的启动

author: 燃烧 jacky.wucheng@gmail.com 本代码分析基于 puppet-2.7.19, 编写于2014-03-14 如下的讲解中可能尽量讲述较关键的地方,其他地方可能会省略。

sbin/puppetd脚本是agent启动入口,其中调用Puppet::Application[:agent].run 启动agent daemon。 其调用的是lib/puppet/application/agent.rb中的class Puppet::Application::Agent里的run方法。 class Puppet::Application::Agent的run方法是从Puppet::Application中继承的。

class Puppet::Application 中

```
# This is the main application entry point
def run
exit_on_fail("initialize") { hook('preinit') { preinit } }
exit_on_fail("parse options") { hook('parse_options') { parse_options } }
exit_on_fail("parse configuration file") { Puppet.settings.parse } if should_parse_config?
exit_on_fail("prepare for execution") { hook('setup') { setup } }
exit_on_fail("configure routes from
#{Puppet[:route_file]}") { configure_indirector_routes }
exit_on_fail("run") { hook('run_command') { run_command } }
end
```

显然代码了做了

  • 预初始化。
  • 解析配置文件。
  • 配置indirector,其用途可参考 indirection
  • 执行run_command,此run_command方法是在class Puppet::Application::Agent中定义的,其覆盖了父类Puppet::Application中的run_command方法。
  • run_command方法中调用main方法执行了@daemon.start来启动puppetd的客户端。

Puppet Agent Run Rest-API的实现

通过Puppet官方文档Rest_API,可知我们可以通过给Puppet Agent发送http请求来触发Agent进行更新,那么通过此run接口可以实现多少需求呢?是否可以实现noop更新noop参数的解释的呢?我们分析一下接口的实现。

lib/puppet/network/handler/runner.rb中定义了

```
class Puppet::Network::Handler
class MissingMasterError < RuntimeError; end # Cannot find the master client
# A simple server for triggering a new run on a Puppet client.
class Runner < Handler
desc "An interface for triggering client configuration runs."

@interface = XMLRPC::Service::Interface.new("puppetrunner") { |iface|
iface.add_method("string run(string, string)")
}

side :client

# Run the client configuration right now, optionally specifying
# tags and whether to ignore schedules
def run(tags = nil, ignoreschedules = false, fg = true, client = nil, clientip = nil)
options = {}
options[:tags] = tags if tags
options[:ignoreschedules] = ignoreschedules if ignoreschedules
options[:background] = !fg

runner = Puppet::Run.new(options)

runner.run

runner.status
end
end
end
```

从中可见,支持的参数只有tags,ignoreschedules,background。所以,此run接口目前的功能是非常若弱的,如果要实现我们的功能,我们需要考察下是否可以定制。 其中Puppet::Run定义在lib/puppet/run.rb中,

```
class Puppet::Run
...

def initialize(options = {})
if options.include?(:background)
@background = options[:background]
options.delete(:background)
end

valid_options = [:tags, :ignoreschedules]
options.each do |key, value|
raise ArgumentError, "Run does not accept
#{key}" unless valid_options.include?(key)
end

@options = options
end


def run
if agent.running?
@status = "running"
return self
end

log_run

if background?
Thread.new { agent.run(options) }
else
agent.run(options)
end

@status = "success"

self
end
...
end
```

其中进行了参数检查,只支持[:tags, :ignoreschedules]这几个参数。这就比较悲剧了,如果要实现更多的参数,没有合适的插件模式,而是需要改原生代码。从puppet-3.1中,依然没有看到改进。

```
from puppet-3.1

def initialize(options = {})
if options.include?(:background)
¦ @background = options[:background]
¦ options.delete(:background)
end

valid_options = [:tags, :ignoreschedules, :pluginsync]
options.each do |key, value|
¦ raise ArgumentError, "Run does not accept
#{key}" unless valid_options.include?(key)
end

@options = options
end
```

留下评论

您的电子邮箱地址并不会被展示。请填写标记为必须的字段。 *

正在加载...