class Puppet::Agent
A general class for triggering a run of another class.
Attributes
client[R]
client_class[R]
should_fork[R]
Public Class Methods
new(client_class, should_fork=true)
click to toggle source
# File lib/puppet/agent.rb 25 def initialize(client_class, should_fork=true) 26 @should_fork = can_fork? && should_fork 27 @client_class = client_class 28 end
Public Instance Methods
can_fork?()
click to toggle source
# File lib/puppet/agent.rb 30 def can_fork? 31 Puppet.features.posix? && RUBY_PLATFORM != 'java' 32 end
needing_restart?()
click to toggle source
# File lib/puppet/agent.rb 34 def needing_restart? 35 Puppet::Application.restart_requested? 36 end
run(client_options = {})
click to toggle source
Perform a run with our client.
# File lib/puppet/agent.rb 39 def run(client_options = {}) 40 if disabled? 41 Puppet.notice _("Skipping run of %{client_class}; administratively disabled (Reason: '%{disable_message}');\nUse 'puppet agent --enable' to re-enable.") % { client_class: client_class, disable_message: disable_message } 42 return 43 end 44 45 result = nil 46 wait_for_lock_deadline = nil 47 block_run = Puppet::Application.controlled_run do 48 splay client_options.fetch :splay, Puppet[:splay] 49 result = run_in_fork(should_fork) do 50 with_client(client_options[:transaction_uuid], client_options[:job_id]) do |client| 51 client_args = client_options.merge(:pluginsync => Puppet::Configurer.should_pluginsync?) 52 begin 53 lock do 54 # NOTE: Timeout is pretty heinous as the location in which it 55 # throws an error is entirely unpredictable, which means that 56 # it can interrupt code blocks that perform cleanup or enforce 57 # sanity. The only thing a Puppet agent should do after this 58 # error is thrown is die with as much dignity as possible. 59 Timeout.timeout(Puppet[:runtimeout], RunTimeoutError) do 60 client.run(client_args) 61 end 62 end 63 rescue Puppet::LockError 64 now = Time.now.to_i 65 wait_for_lock_deadline ||= now + Puppet[:maxwaitforlock] 66 67 if Puppet[:waitforlock] < 1 68 Puppet.notice _("Run of %{client_class} already in progress; skipping (%{lockfile_path} exists)") % { client_class: client_class, lockfile_path: lockfile_path } 69 nil 70 elsif now >= wait_for_lock_deadline 71 Puppet.notice _("Exiting now because the maxwaitforlock timeout has been exceeded.") 72 nil 73 else 74 Puppet.info _("Another puppet instance is already running; --waitforlock flag used, waiting for running instance to finish.") 75 Puppet.info _("Will try again in %{time} seconds.") % {time: Puppet[:waitforlock]} 76 sleep Puppet[:waitforlock] 77 retry 78 end 79 rescue RunTimeoutError => detail 80 Puppet.log_exception(detail, _("Execution of %{client_class} did not complete within %{runtimeout} seconds and was terminated.") % 81 {client_class: client_class, 82 runtimeout: Puppet[:runtimeout]}) 83 nil 84 rescue StandardError => detail 85 Puppet.log_exception(detail, _("Could not run %{client_class}: %{detail}") % { client_class: client_class, detail: detail }) 86 nil 87 end 88 end 89 end 90 true 91 end 92 Puppet.notice _("Shutdown/restart in progress (%{status}); skipping run") % { status: Puppet::Application.run_status.inspect } unless block_run 93 result 94 end
run_in_fork(forking = true) { || ... }
click to toggle source
# File lib/puppet/agent.rb 100 def run_in_fork(forking = true) 101 return yield unless forking or Puppet.features.windows? 102 103 atForkHandler = Puppet::Util::AtFork.get_handler 104 105 atForkHandler.prepare 106 107 begin 108 child_pid = Kernel.fork do 109 atForkHandler.child 110 $0 = _("puppet agent: applying configuration") 111 begin 112 exit(yield || 1) 113 rescue NoMemoryError 114 exit(254) 115 end 116 end 117 ensure 118 atForkHandler.parent 119 end 120 121 exit_code = Process.waitpid2(child_pid) 122 exit_code[1].exitstatus 123 end
stopping?()
click to toggle source
# File lib/puppet/agent.rb 96 def stopping? 97 Puppet::Application.stop_requested? 98 end
Private Instance Methods
with_client(transaction_uuid, job_id = nil) { |client| ... }
click to toggle source
Create and yield a client instance, keeping a reference to it during the yield.
# File lib/puppet/agent.rb 129 def with_client(transaction_uuid, job_id = nil) 130 begin 131 @client = client_class.new(transaction_uuid, job_id) 132 rescue StandardError => detail 133 Puppet.log_exception(detail, _("Could not create instance of %{client_class}: %{detail}") % { client_class: client_class, detail: detail }) 134 return 135 end 136 yield @client 137 ensure 138 @client = nil 139 end