diff options
| author | Nick Lewis <nick@puppetlabs.com> | 2011-06-08 18:41:16 -0700 |
|---|---|---|
| committer | Nick Lewis <nick@puppetlabs.com> | 2011-06-08 18:41:16 -0700 |
| commit | 8ccd00963d91f168438eaec4b29a18cd4a1ac583 (patch) | |
| tree | 85e15c5ef9390454438fb300c5baa38a7f2f5f3e /lib/puppet/indirector | |
| parent | 376e0f04af01810d00eede4de52744bb8c8e1681 (diff) | |
| parent | d4c499dfdbd94f5272278e1ba87a75915607c3d7 (diff) | |
| download | puppet-8ccd00963d91f168438eaec4b29a18cd4a1ac583.tar.gz puppet-8ccd00963d91f168438eaec4b29a18cd4a1ac583.tar.xz puppet-8ccd00963d91f168438eaec4b29a18cd4a1ac583.zip | |
Merge branch '2.7rc' into 2.7.x
Diffstat (limited to 'lib/puppet/indirector')
| -rw-r--r-- | lib/puppet/indirector/catalog/static_compiler.rb | 137 | ||||
| -rw-r--r-- | lib/puppet/indirector/face.rb | 14 |
2 files changed, 145 insertions, 6 deletions
diff --git a/lib/puppet/indirector/catalog/static_compiler.rb b/lib/puppet/indirector/catalog/static_compiler.rb new file mode 100644 index 000000000..1d92121ed --- /dev/null +++ b/lib/puppet/indirector/catalog/static_compiler.rb @@ -0,0 +1,137 @@ +require 'puppet/node' +require 'puppet/resource/catalog' +require 'puppet/indirector/code' + +class Puppet::Resource::Catalog::StaticCompiler < Puppet::Indirector::Code + def compiler + @compiler ||= indirection.terminus(:compiler) + end + + def find(request) + return nil unless catalog = compiler.find(request) + + raise "Did not get catalog back" unless catalog.is_a?(model) + + catalog.resources.find_all { |res| res.type == "File" }.each do |resource| + next unless source = resource[:source] + next unless source =~ /^puppet:/ + + file = resource.to_ral + if file.recurse? + add_children(request.key, catalog, resource, file) + else + find_and_replace_metadata(request.key, resource, file) + end + end + + catalog + end + + def find_and_replace_metadata(host, resource, file) + # We remove URL info from it, so it forces a local copy + # rather than routing through the network. + # Weird, but true. + newsource = file[:source][0].sub("puppet:///", "") + file[:source][0] = newsource + + raise "Could not get metadata for #{resource[:source]}" unless metadata = file.parameter(:source).metadata + + replace_metadata(host, resource, metadata) + end + + def replace_metadata(host, resource, metadata) + [:mode, :owner, :group].each do |param| + resource[param] ||= metadata.send(param) + end + + resource[:ensure] = metadata.ftype + if metadata.ftype == "file" + unless resource[:content] + resource[:content] = metadata.checksum + resource[:checksum] = metadata.checksum_type + end + end + + store_content(resource) if resource[:ensure] == "file" + old_source = resource.delete(:source) + Puppet.info "Metadata for #{resource} in catalog for '#{host}' added from '#{old_source}'" + end + + def add_children(host, catalog, resource, file) + file = resource.to_ral + + children = get_child_resources(host, catalog, resource, file) + + remove_existing_resources(children, catalog) + + children.each do |name, res| + catalog.add_resource res + catalog.add_edge(resource, res) + end + end + + def get_child_resources(host, catalog, resource, file) + sourceselect = file[:sourceselect] + children = {} + + source = resource[:source] + + # This is largely a copy of recurse_remote in File + total = file[:source].collect do |source| + next unless result = file.perform_recursion(source) + return if top = result.find { |r| r.relative_path == "." } and top.ftype != "directory" + result.each { |data| data.source = "#{source}/#{data.relative_path}" } + break result if result and ! result.empty? and sourceselect == :first + result + end.flatten + + # This only happens if we have sourceselect == :all + unless sourceselect == :first + found = [] + total.reject! do |data| + result = found.include?(data.relative_path) + found << data.relative_path unless found.include?(data.relative_path) + result + end + end + + total.each do |meta| + # This is the top-level parent directory + if meta.relative_path == "." + replace_metadata(host, resource, meta) + next + end + children[meta.relative_path] ||= Puppet::Resource.new(:file, File.join(file[:path], meta.relative_path)) + + # I think this is safe since it's a URL, not an actual file + children[meta.relative_path][:source] = source + "/" + meta.relative_path + replace_metadata(host, children[meta.relative_path], meta) + end + + children + end + + def remove_existing_resources(children, catalog) + existing_names = catalog.resources.collect { |r| r.to_s } + + both = (existing_names & children.keys).inject({}) { |hash, name| hash[name] = true; hash } + + both.each { |name| children.delete(name) } + end + + def store_content(resource) + @summer ||= Object.new + @summer.extend(Puppet::Util::Checksums) + + type = @summer.sumtype(resource[:content]) + sum = @summer.sumdata(resource[:content]) + + if Puppet::FileBucket::File.indirection.find("#{type}/#{sum}") + Puppet.info "Content for '#{resource[:source]}' already exists" + else + Puppet.info "Storing content for source '#{resource[:source]}'" + content = Puppet::FileServing::Content.find(resource[:source]) + Puppet::FileBucket::File.new(content.content).save + end + end +end diff --git a/lib/puppet/indirector/face.rb b/lib/puppet/indirector/face.rb index 756306a2f..ead3f4b46 100644 --- a/lib/puppet/indirector/face.rb +++ b/lib/puppet/indirector/face.rb @@ -2,7 +2,7 @@ require 'puppet/face' class Puppet::Indirector::Face < Puppet::Face option "--terminus TERMINUS" do - summary "The indirector terminus to use for this action." + summary "The indirector terminus to use." description <<-EOT Indirector faces expose indirected subsystems of Puppet. These subsystems are each able to retrieve and alter a specific type of data @@ -61,11 +61,12 @@ class Puppet::Indirector::Face < Puppet::Face end action :save do - summary "Create or overwrite an object." + summary "API only: create or overwrite an object." arguments "<object>" description <<-EOT - Create or overwrite an object. Save actions cannot currently be - invoked from the command line, and are for API use only. + API only: create or overwrite an object. As the Faces framework does not + currently accept data from STDIN, save actions cannot currently be invoked + from the command line. EOT when_invoked { |key, options| call_indirection_method(:save, key, options) } end @@ -80,8 +81,9 @@ class Puppet::Indirector::Face < Puppet::Face action :info do summary "Print the default terminus class for this face." description <<-EOT - Prints the default terminus class for this face. Note that - different run modes may have different default terminuses. + Prints the default terminus class for this subcommand. Note that different + run modes may have different default termini; when in doubt, specify the + run mode with the '--mode' option. EOT when_invoked do |*args| |
