Class: Puppet::Agent
- Includes:
- Disabler, Locker, Util::Splayer
- Defined in:
- lib/puppet/agent.rb
Overview
A general class for triggering a run of another class.
Defined Under Namespace
Modules: Disabler, Locker Classes: RunTimeoutError
Constant Summary
Constants included from Disabler
Disabler::DISABLED_MESSAGE_JSON_KEY
Instance Attribute Summary collapse
-
#client ⇒ Object
readonly
Returns the value of attribute client.
-
#client_class ⇒ Object
readonly
Returns the value of attribute client_class.
-
#should_fork ⇒ Object
readonly
Returns the value of attribute should_fork.
Instance Method Summary collapse
- #can_fork? ⇒ Boolean
-
#initialize(client_class, should_fork = true) ⇒ Agent
constructor
A new instance of Agent.
- #needing_restart? ⇒ Boolean
-
#run(client_options = {}) ⇒ Object
Perform a run with our client.
- #run_in_fork(forking = true) ⇒ Object
- #stopping? ⇒ Boolean
Methods included from Util::Splayer
Methods included from Disabler
#disable, #disable_message, #disabled?, #enable
Methods included from Locker
#lock, #lockfile_path, #running?
Constructor Details
#initialize(client_class, should_fork = true) ⇒ Agent
Returns a new instance of Agent.
27 28 29 30 |
# File 'lib/puppet/agent.rb', line 27 def initialize(client_class, should_fork = true) @should_fork = can_fork? && should_fork @client_class = client_class end |
Instance Attribute Details
#client ⇒ Object (readonly)
Returns the value of attribute client.
25 26 27 |
# File 'lib/puppet/agent.rb', line 25 def client @client end |
#client_class ⇒ Object (readonly)
Returns the value of attribute client_class.
25 26 27 |
# File 'lib/puppet/agent.rb', line 25 def client_class @client_class end |
#should_fork ⇒ Object (readonly)
Returns the value of attribute should_fork.
25 26 27 |
# File 'lib/puppet/agent.rb', line 25 def should_fork @should_fork end |
Instance Method Details
#can_fork? ⇒ Boolean
32 33 34 |
# File 'lib/puppet/agent.rb', line 32 def can_fork? Puppet.features.posix? && RUBY_PLATFORM != 'java' end |
#needing_restart? ⇒ Boolean
36 37 38 |
# File 'lib/puppet/agent.rb', line 36 def needing_restart? Puppet::Application.restart_requested? end |
#run(client_options = {}) ⇒ Object
Perform a run with our client.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/puppet/agent.rb', line 41 def run( = {}) if disabled? return end result = nil wait_for_lock_deadline = nil block_run = Puppet::Application.controlled_run do # splay may sleep for awhile when running onetime! If not onetime, then # the job scheduler splays (only once) so that agents assign themselves a # slot within the splay interval. do_splay = .fetch(:splay, Puppet[:splay]) if do_splay splay(do_splay) if disabled? break end end # waiting for certs may sleep for awhile depending on onetime, waitforcert and maxwaitforcert! # this needs to happen before forking so that if we fail to obtain certs and try to exit, then # we exit the main process and not the forked child. ssl_context = wait_for_certificates() result = run_in_fork(should_fork) do with_client([:transaction_uuid], [:job_id]) do |client| client_args = .merge(:pluginsync => Puppet::Configurer.should_pluginsync?) begin # lock may sleep for awhile depending on waitforlock and maxwaitforlock! lock do if disabled? nil else # NOTE: Timeout is pretty heinous as the location in which it # throws an error is entirely unpredictable, which means that # it can interrupt code blocks that perform cleanup or enforce # sanity. The only thing a Puppet agent should do after this # error is thrown is die with as much dignity as possible. Timeout.timeout(Puppet[:runtimeout], RunTimeoutError) do Puppet.override(ssl_context: ssl_context) do client.run(client_args) end end end end rescue Puppet::LockError now = Time.now.to_i wait_for_lock_deadline ||= now + Puppet[:maxwaitforlock] if Puppet[:waitforlock] < 1 Puppet.notice _("Run of %{client_class} already in progress; skipping (%{lockfile_path} exists)") % { client_class: client_class, lockfile_path: lockfile_path } nil elsif now >= wait_for_lock_deadline Puppet.notice _("Exiting now because the maxwaitforlock timeout has been exceeded.") nil else Puppet.info _("Another puppet instance is already running; --waitforlock flag used, waiting for running instance to finish.") Puppet.info _("Will try again in %{time} seconds.") % { time: Puppet[:waitforlock] } sleep Puppet[:waitforlock] retry end rescue RunTimeoutError => detail Puppet.log_exception(detail, _("Execution of %{client_class} did not complete within %{runtimeout} seconds and was terminated.") % { client_class: client_class, runtimeout: Puppet[:runtimeout] }) nil rescue StandardError => detail Puppet.log_exception(detail, _("Could not run %{client_class}: %{detail}") % { client_class: client_class, detail: detail }) nil ensure Puppet.runtime[:http].close end end end true end Puppet.notice _("Shutdown/restart in progress (%{status}); skipping run") % { status: Puppet::Application.run_status.inspect } unless block_run result end |
#run_in_fork(forking = true) ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/puppet/agent.rb', line 128 def run_in_fork(forking = true) return yield unless forking or Puppet.features.windows? atForkHandler = Puppet::Util::AtFork.get_handler atForkHandler.prepare begin child_pid = Kernel.fork do atForkHandler.child $0 = _("puppet agent: applying configuration") begin exit(yield || 1) rescue NoMemoryError exit(254) end end ensure atForkHandler.parent end exit_code = Process.waitpid2(child_pid) exit_code[1].exitstatus end |
#stopping? ⇒ Boolean
124 125 126 |
# File 'lib/puppet/agent.rb', line 124 def stopping? Puppet::Application.stop_requested? end |