Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
diff --git a/lib/puppet/provider/package/yum.rb b/lib/puppet/provider/package/yum.rb index 581a446..d78a705 100755 --- a/lib/puppet/provider/package/yum.rb +++ b/lib/puppet/provider/package/yum.rb @@ -104,5 +104,14 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do def purge yum "-y", :erase, @resource[:name] end + + # Static function that enable multiple package to be install at the same time + def self.combine(resource_names) + + # TODO Add lots of test and error handling + + output = yum "-d", "0", "-e", "0", "-y", :install, resource_names + + end end diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb index 37f51b2..4ba0ecc 100644 --- a/lib/puppet/transaction.rb +++ b/lib/puppet/transaction.rb @@ -219,7 +219,11 @@ class Transaction # Perform the actual changes seconds = thinmark do - events += apply(resource) + if combineable?(resource) + events += combine(resource) + else + events += apply(resource) + end end if children and ! resource.depthfirst? @@ -473,7 +477,101 @@ class Transaction end end end + + # Test if a specific resource can be combined, only package resources can be combined so far + # + # Retrun true if it can be combined false otherwise + # * its provider should support combine + # * it should not be skiped + # * the combine attribute should be set to true + # * puppet is not running on noop mode + # * the packet is ensure (present, latest or installed), version is not supported for multiple install yet. + def combineable?(resource) + if resource.provider.class.respond_to?(:combine) and + ! resource.noop and + ! skip?(resource) and + resource[:combine] == :true and + [:present,:latest,:installed].include?(resource[:ensure]) and + changes = resource.evaluate and + allow_processing?(resource,changes) and + ! changes.empty? + puts resource.to_yaml + return true + else + return false + end + end + + # Function that install all the package available of the same class in a single package manager call if it is possible to combine them. + def combine(resource) + + provider_class = resource.provider.class + + @multiple_install_events ||= {} + @multiple_install_events[provider_class] ||= {} + + if events = @multiple_install_events[provider_class][resource.name] + return events + end + + # Find all resources matching the provider class that set combining + resources = catalog.vertices.reject { |r| + + !r.provider.class.equal?(provider_class) or !combineable?(r) + + # All the resource that will be installed + }.collect { |r| + + changes = r.evaluate + changes = [changes] unless changes.is_a?(Array) + + if changes.length > 0 + @resourcemetrics[:out_of_sync] += 1 + end + + changes.each { |c| + @changes << c + @count += 1 + } + + resourceevents = [Puppet::Transaction::Event.new(r.name, r)] + + # Record when we last synced + r.cache(:synced, Time.now) + # Flush, if appropriate + if r.respond_to?(:flush) + r.flush + end + + # And set a trigger for refreshing this resource if it's a + # self-refresher + if r.self_refresh? and ! r.deleting? + # Create an edge with this resource as both the source and + # target. The triggering method treats these specially for + # logging. + events = resourceevents.collect { |e| e.name } + set_trigger(Puppet::Relationship.new(r,r, :callback => :refresh, :event => events)) + end + + @multiple_install_events[provider_class][r.name] = resourceevents + + r + } + + # collecting their names in an array + resource_names = resources.collect { |r| + r[:name] + } + + # Add error handling ... + if resource_names.length > 0 + output = provider_class.combine(resource_names) + end + + @multiple_install_events[provider_class][resource.name] + end + # Prepare to evaluate the resources in a transaction. def prepare # Now add any dynamically generated resources diff --git a/lib/puppet/type/package.rb b/lib/puppet/type/package.rb index 655f9e0..2c507ed 100644 --- a/lib/puppet/type/package.rb +++ b/lib/puppet/type/package.rb @@ -277,6 +277,14 @@ module Puppet newvalues(:true, :false) end + newparam(:combine) do + desc "Tells package provider if the packet installation have to be + perform in a single call by the packet manager or if it has to + be executed alone." + defaultto :false + newvalues(:true, :false) + end + autorequire(:file) do autos = [] [:responsefile, :adminfile].each { |param|
This paste will be private.
From the Design Piracy series on my blog: