Method: Puppet::Transaction#evaluate
- Defined in:
- lib/puppet/transaction.rb
#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.
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 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/puppet/transaction.rb', line 97 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 persistence.enabled?(catalog) Puppet.info _("Applying configuration version '%{version}'") % { version: catalog.version } if catalog.version continue_while = -> { !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| provider.post_resource_eval rescue => detail Puppet.log_exception(detail, _("post_resource_eval failed for provider %{provider}") % { provider: provider }) end persistence.save if persistence.enabled?(catalog) 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 progress = 0 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| progress += 1 if resource.is_a?(Puppet::Type::Component) Puppet.warning _("Somehow left a component in the relationship graph") else if Puppet[:evaltrace] && @catalog.host_config? resource.info _("Starting to evaluate the resource (%{progress} of %{total})") % { progress: progress, total: relationship_graph.size } end seconds = thinmark { block.call(resource) } resource.info _("Evaluated in %{seconds} seconds") % { seconds: "%0.2f" % seconds } if Puppet[:evaltrace] && @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 # mark the end of transaction evaluate. report.transaction_completed = true Puppet.debug { "Finishing transaction #{object_id}" } end |