Class: Puppet::Transaction Private
- Includes:
- Util, Util::Tagging
- Defined in:
- lib/puppet/transaction.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
the class that actually walks our resource/property tree, collects the changes, and performs them
Defined Under Namespace
Classes: AdditionalResourceGenerator, Event, EventManager, Persistence, Report, ResourceHarness
Constant Summary
Constants included from Util::Tagging
Constants included from Util
Util::AbsolutePathPosix, Util::AbsolutePathWindows, Util::DEFAULT_POSIX_MODE, Util::DEFAULT_WINDOWS_MODE
Constants included from Util::POSIX
Util::POSIX::LOCALE_ENV_VARS, Util::POSIX::USER_ENV_VARS
Constants included from Util::SymbolicFileMode
Util::SymbolicFileMode::SetGIDBit, Util::SymbolicFileMode::SetUIDBit, Util::SymbolicFileMode::StickyBit, Util::SymbolicFileMode::SymbolicMode, Util::SymbolicFileMode::SymbolicSpecialToBit
Instance Attribute Summary collapse
- #catalog ⇒ Object private
-
#event_manager ⇒ Object
readonly
private
Routes and stores any events and subscriptions.
- #for_network_device ⇒ Object private
- #ignoreschedules ⇒ Object private
- #persistence ⇒ Object readonly private
- #prefetched_providers ⇒ Object readonly private
-
#report ⇒ Object
readonly
private
The report, once generated.
-
#resource_harness ⇒ Object
readonly
private
Handles most of the actual interacting with resources.
Instance Method Summary collapse
-
#any_failed? ⇒ Boolean
private
Are there any failed resources in this transaction?.
-
#changed? ⇒ Boolean
private
Find all of the changed resources.
-
#evaluate(&block) ⇒ Object
private
This method does all the actual work of running a transaction.
-
#initialize(catalog, report, prioritizer) ⇒ Transaction
constructor
private
A new instance of Transaction.
-
#missing_tags?(resource) ⇒ Boolean
private
Is this resource tagged appropriately?.
-
#perform_pre_run_checks ⇒ void
private
Invoke the pre_run_check hook in every resource in the catalog.
- #prefetch_if_necessary(resource) ⇒ Object private
- #relationship_graph ⇒ Object private
- #resource_status(resource) ⇒ Object private
-
#skip?(resource) ⇒ Boolean
private
Should this resource be skipped?.
- #skip_tags ⇒ Object private
-
#stop_processing? ⇒ Boolean
private
Wraps application run state check to flag need to interrupt processing.
-
#tags ⇒ Object
private
The tags we should be checking.
Methods included from Util::Tagging
#merge_into, #merge_tags, #raw_tagged?, #set_tags, #tag, #tag_if_valid, #tagged?, #tags=
Methods included from Util
absolute_path?, benchmark, chuser, clear_environment, default_env, deterministic_rand, deterministic_rand_int, exit_on_fail, get_env, get_environment, logmethods, merge_environment, path_to_uri, pretty_backtrace, replace_file, safe_posix_fork, set_env, symbolizehash, thinmark, uri_encode, uri_query_encode, uri_to_path, which, withenv, withumask
Methods included from Util::POSIX
#get_posix_field, #gid, #idfield, #methodbyid, #methodbyname, #search_posix_field, #uid
Methods included from Util::SymbolicFileMode
#normalize_symbolic_mode, #symbolic_mode_to_int, #valid_symbolic_mode?
Constructor Details
#initialize(catalog, report, prioritizer) ⇒ Transaction
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of Transaction.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/puppet/transaction.rb', line 41 def initialize(catalog, report, prioritizer) @catalog = catalog @persistence = Puppet::Transaction::Persistence.new @report = report || Puppet::Transaction::Report.new(catalog.version, catalog.environment) @prioritizer = prioritizer @report.add_times(:config_retrieval, @catalog.retrieval_duration || 0) @event_manager = Puppet::Transaction::EventManager.new(self) @resource_harness = Puppet::Transaction::ResourceHarness.new(self) @prefetched_providers = Hash.new { |h,k| h[k] = {} } end |
Instance Attribute Details
#catalog ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
20 21 22 |
# File 'lib/puppet/transaction.rb', line 20 def catalog @catalog end |
#event_manager ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Routes and stores any events and subscriptions.
26 27 28 |
# File 'lib/puppet/transaction.rb', line 26 def event_manager @event_manager end |
#for_network_device ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
20 21 22 |
# File 'lib/puppet/transaction.rb', line 20 def for_network_device @for_network_device end |
#ignoreschedules ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
20 21 22 |
# File 'lib/puppet/transaction.rb', line 20 def ignoreschedules @ignoreschedules end |
#persistence ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
36 37 38 |
# File 'lib/puppet/transaction.rb', line 36 def persistence @persistence end |
#prefetched_providers ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
31 32 33 |
# File 'lib/puppet/transaction.rb', line 31 def prefetched_providers @prefetched_providers end |
#report ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The report, once generated.
23 24 25 |
# File 'lib/puppet/transaction.rb', line 23 def report @report end |
#resource_harness ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Handles most of the actual interacting with resources
29 30 31 |
# File 'lib/puppet/transaction.rb', line 29 def resource_harness @resource_harness end |
Instance Method Details
#any_failed? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Are there any failed resources in this transaction?
199 200 201 202 203 |
# File 'lib/puppet/transaction.rb', line 199 def any_failed? report.resource_statuses.values.detect { |status| status.failed? || status.failed_to_restart? } end |
#changed? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Find all of the changed resources.
206 207 208 |
# File 'lib/puppet/transaction.rb', line 206 def changed? report.resource_statuses.values.find_all { |status| status.changed }.collect { |status| catalog.resource(status.resource) } end |
#evaluate(&block) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method does all the actual work of running a transaction. It collects all of the changes, executes them, and responds to any necessary events.
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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/puppet/transaction.rb', line 89 def evaluate(&block) block ||= method(:eval_resource) generator = AdditionalResourceGenerator.new(@catalog, nil, @prioritizer) @catalog.vertices.each { |resource| generator.generate_additional_resources(resource) } perform_pre_run_checks persistence.load if catalog.host_config? Puppet.info _("Applying configuration version '%{version}'") % { version: catalog.version } if catalog.version continue_while = lambda { !stop_processing? } post_evalable_providers = Set.new pre_process = lambda do |resource| prov_class = resource.provider.class post_evalable_providers << prov_class if prov_class.respond_to?(:post_resource_eval) prefetch_if_necessary(resource) # If we generated resources, we don't know what they are now # blocking, so we opt to recompute it, rather than try to track every # change that would affect the number. relationship_graph.clear_blockers if generator.eval_generate(resource) end providerless_types = [] overly_deferred_resource_handler = lambda do |resource| # We don't automatically assign unsuitable providers, so if there # is one, it must have been selected by the user. return if (resource) if resource.provider resource.err _("Provider %{name} is not functional on this host") % { name: resource.provider.class.name } else providerless_types << resource.type end resource_status(resource).failed = true end canceled_resource_handler = lambda do |resource| resource_status(resource).skipped = true resource.debug "Transaction canceled, skipping" end teardown = lambda do # Just once per type. No need to punish the user. providerless_types.uniq.each do |type| Puppet.err _("Could not find a suitable provider for %{type}") % { type: type } end post_evalable_providers.each do |provider| begin provider.post_resource_eval rescue => detail Puppet.log_exception(detail, _("post_resource_eval failed for provider %{provider}") % { provider: provider }) end end persistence.save if catalog.host_config? end # Graph cycles are returned as an array of arrays # - outer array is an array of cycles # - each inner array is an array of resources involved in a cycle # Short circuit resource evaluation if we detect cycle(s) in the graph. Mark # each corresponding resource as failed in the report before we fail to # ensure accurate reporting. graph_cycle_handler = lambda do |cycles| cycles.flatten.uniq.each do |resource| # We add a failed resource event to the status to ensure accurate # reporting through the event manager. resource_status(resource).fail_with_event(_('resource is part of a dependency cycle')) end raise Puppet::Error, _('One or more resource dependency cycles detected in graph') end # Generate the relationship graph, set up our generator to use it # for eval_generate, then kick off our traversal. generator.relationship_graph = relationship_graph relationship_graph.traverse(:while => continue_while, :pre_process => pre_process, :overly_deferred_resource_handler => overly_deferred_resource_handler, :canceled_resource_handler => canceled_resource_handler, :graph_cycle_handler => graph_cycle_handler, :teardown => teardown) do |resource| if resource.is_a?(Puppet::Type::Component) Puppet.warning _("Somehow left a component in the relationship graph") else resource.info _("Starting to evaluate the resource") if Puppet[:evaltrace] and @catalog.host_config? seconds = thinmark { block.call(resource) } resource.info _("Evaluated in %0.2f seconds") % seconds if Puppet[:evaltrace] and @catalog.host_config? end end # if one or more resources has attempted and failed to generate resources, # report it if generator.resources_failed_to_generate report.resources_failed_to_generate = true end Puppet.debug "Finishing transaction #{object_id}" end |
#missing_tags?(resource) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Is this resource tagged appropriately?
390 391 392 393 394 395 |
# File 'lib/puppet/transaction.rb', line 390 def (resource) return false if return false if .empty? not resource.tagged?(*) end |
#perform_pre_run_checks ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Invoke the pre_run_check hook in every resource in the catalog. This should (only) be called by Transaction#evaluate before applying the catalog.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/puppet/transaction.rb', line 67 def perform_pre_run_checks prerun_errors = {} @catalog.vertices.each do |res| begin res.pre_run_check rescue Puppet::Error => detail prerun_errors[res] = detail end end unless prerun_errors.empty? prerun_errors.each do |res, detail| res.log_exception(detail) end raise Puppet::Error, _("Some pre-run checks failed") end end |
#prefetch_if_necessary(resource) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/puppet/transaction.rb', line 229 def prefetch_if_necessary(resource) provider_class = resource.provider.class return unless provider_class.respond_to?(:prefetch) and !prefetched_providers[resource.type][provider_class.name] resources = resources_by_provider(resource.type, provider_class.name) if provider_class == resource.class.defaultprovider providerless_resources = resources_by_provider(resource.type, nil) providerless_resources.values.each {|res| res.provider = provider_class.name} resources.merge! providerless_resources end prefetch(provider_class, resources) end |
#relationship_graph ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
210 211 212 |
# File 'lib/puppet/transaction.rb', line 210 def relationship_graph catalog.relationship_graph(@prioritizer) end |
#resource_status(resource) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
214 215 216 |
# File 'lib/puppet/transaction.rb', line 214 def resource_status(resource) report.resource_statuses[resource.to_s] || add_resource_status(Puppet::Resource::Status.new(resource)) end |
#skip?(resource) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Should this resource be skipped?
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 |
# File 'lib/puppet/transaction.rb', line 358 def skip?(resource) if (resource) resource.debug "Skipping with skip tags #{.join(", ")}" elsif (resource) resource.debug "Not tagged with #{.join(", ")}" elsif ! scheduled?(resource) resource.debug "Not scheduled" elsif failed_dependencies?(resource) # When we introduced the :whit into the graph, to reduce the combinatorial # explosion of edges, we also ended up reporting failures for containers # like class and stage. This is undesirable; while just skipping the # output isn't perfect, it is RC-safe. --daniel 2011-06-07 unless resource.class == Puppet::Type.type(:whit) then resource.warning _("Skipping because of failed dependencies") end elsif resource.virtual? resource.debug "Skipping because virtual" elsif !host_and_device_resource?(resource) && resource.appliable_to_host? && for_network_device resource.debug "Skipping host resources because running on a device" elsif !host_and_device_resource?(resource) && resource.appliable_to_device? && !for_network_device resource.debug "Skipping device resources because running on a posix host" else return false end true end |
#skip_tags ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
225 226 227 |
# File 'lib/puppet/transaction.rb', line 225 def @skip_tags ||= Puppet::Util::SkipTags.new(Puppet[:skip_tags]). end |
#stop_processing? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Wraps application run state check to flag need to interrupt processing
194 195 196 |
# File 'lib/puppet/transaction.rb', line 194 def stop_processing? Puppet::Application.stop_requested? && catalog.host_config? end |
#tags ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The tags we should be checking.
219 220 221 222 223 |
# File 'lib/puppet/transaction.rb', line 219 def self. = Puppet[:tags] unless defined?(@tags) super end |