diff options
| -rw-r--r-- | lib/puppet/application/puppet.rb | 50 | ||||
| -rw-r--r-- | lib/puppet/configurer.rb | 4 | ||||
| -rwxr-xr-x | spec/integration/application/puppet.rb | 30 | ||||
| -rw-r--r-- | spec/unit/application/puppet.rb | 130 | ||||
| -rwxr-xr-x | spec/unit/configurer.rb | 8 |
5 files changed, 187 insertions, 35 deletions
diff --git a/lib/puppet/application/puppet.rb b/lib/puppet/application/puppet.rb index ee848a503..dd752846c 100644 --- a/lib/puppet/application/puppet.rb +++ b/lib/puppet/application/puppet.rb @@ -16,6 +16,10 @@ Puppet::Application.new(:puppet) do option("--use-nodes") option("--detailed-exitcodes") + option("--apply catalog", "-a catalog") do |arg| + options[:catalog] = arg + end + option("--logdest LOGDEST", "-l") do |arg| begin Puppet::Util::Log.newdestination(arg) @@ -26,7 +30,37 @@ Puppet::Application.new(:puppet) do end dispatch do - return Puppet[:parseonly] ? :parseonly : :main + if options[:catalog] + :apply + elsif Puppet[:parseonly] + :parseonly + else + :main + end + end + + command(:apply) do + require 'puppet/configurer' + + if options[:catalog] == "-" + text = $stdin.read + else + text = File.read(options[:catalog]) + end + + begin + catalog = JSON.parse(text) + unless catalog.is_a?(Puppet::Resource::Catalog) + catalog = Puppet::Resource::Catalog.json_create(catalog) + end + rescue => detail + raise Puppet::Error, "Could not deserialize catalog from json: %s" % detail + end + + catalog = catalog.to_ral + + configurer = Puppet::Configurer.new + configurer.run :catalog => catalog end command(:parseonly) do @@ -40,6 +74,13 @@ Puppet::Application.new(:puppet) do end command(:main) do + # Set our code or file to use. + if options[:code] or ARGV.length == 0 + Puppet[:code] = options[:code] || STDIN.read + else + Puppet[:manifest] = ARGV.shift + end + # Collect our facts. facts = Puppet::Node::Facts.find(Puppet[:certname]) @@ -126,12 +167,5 @@ Puppet::Application.new(:puppet) do elsif options[:verbose] Puppet::Util::Log.level = :info end - - # Set our code or file to use. - if options[:code] or ARGV.length == 0 - Puppet[:code] = options[:code] || STDIN.read - else - Puppet[:manifest] = ARGV.shift - end end end diff --git a/lib/puppet/configurer.rb b/lib/puppet/configurer.rb index 8ec0b0055..81845f5cf 100644 --- a/lib/puppet/configurer.rb +++ b/lib/puppet/configurer.rb @@ -130,7 +130,9 @@ class Puppet::Configurer def run(options = {}) prepare() - unless catalog = retrieve_catalog + if catalog = options[:catalog] + options.delete(:catalog) + elsif ! catalog = retrieve_catalog Puppet.err "Could not retrieve catalog; skipping run" return end diff --git a/spec/integration/application/puppet.rb b/spec/integration/application/puppet.rb new file mode 100755 index 000000000..0047dd5a3 --- /dev/null +++ b/spec/integration/application/puppet.rb @@ -0,0 +1,30 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../spec_helper' + +require 'puppet_spec/files' + +require 'puppet/application/puppet' + +describe "Puppet" do + include PuppetSpec::Files + + it "should be able to apply catalogs provided in a file in json" do + file_to_create = tmpfile("json_catalog") + catalog = Puppet::Resource::Catalog.new + resource = Puppet::Resource.new(:file, file_to_create, :content => "my stuff") + catalog.add_resource resource + + manifest = tmpfile("manifest") + + File.open(manifest, "w") { |f| f.print catalog.to_json } + + puppet = Puppet::Application[:puppet] + puppet.options[:catalog] = manifest + + puppet.apply + + File.should be_exist(file_to_create) + File.read(file_to_create).should == "my stuff" + end +end diff --git a/spec/unit/application/puppet.rb b/spec/unit/application/puppet.rb index 9256b00dc..ca1203405 100644 --- a/spec/unit/application/puppet.rb +++ b/spec/unit/application/puppet.rb @@ -112,42 +112,25 @@ describe "Puppet" do lambda { @puppet.run_setup }.should raise_error(SystemExit) end - it "should set the code to run from --code" do - @puppet.options.stubs(:[]).with(:code).returns("code to run") - Puppet.expects(:[]=).with(:code,"code to run") - - @puppet.run_setup - end - - it "should set the code to run from STDIN if no arguments" do - ARGV.stubs(:length).returns(0) - STDIN.stubs(:read).returns("code to run") - - Puppet.expects(:[]=).with(:code,"code to run") - - @puppet.run_setup - end - - it "should set the manifest if some files are passed on command line" do - ARGV.stubs(:length).returns(1) - ARGV.stubs(:shift).returns("site.pp") - - Puppet.expects(:[]=).with(:manifest,"site.pp") - - @puppet.run_setup - end - end describe "when executing" do it "should dispatch to parseonly if parseonly is set" do + @puppet.stubs(:options).returns({}) Puppet.stubs(:[]).with(:parseonly).returns(true) @puppet.get_command.should == :parseonly end + it "should dispatch to 'apply' if it was called with 'apply'" do + @puppet.options[:catalog] = "foo" + + @puppet.get_command.should == :apply + end + it "should dispatch to main if parseonly is not set" do + @puppet.stubs(:options).returns({}) Puppet.stubs(:[]).with(:parseonly).returns(false) @puppet.get_command.should == :main @@ -203,12 +186,39 @@ describe "Puppet" do @catalog.stubs(:to_ral).returns(@catalog) Puppet::Resource::Catalog.stubs(:find).returns(@catalog) + STDIN.stubs(:read) + @transaction = stub_everything 'transaction' @catalog.stubs(:apply).returns(@transaction) @puppet.stubs(:exit) end + it "should set the code to run from --code" do + @puppet.options.stubs(:[]).with(:code).returns("code to run") + Puppet.expects(:[]=).with(:code,"code to run") + + @puppet.main + end + + it "should set the code to run from STDIN if no arguments" do + ARGV.stubs(:length).returns(0) + STDIN.stubs(:read).returns("code to run") + + Puppet.expects(:[]=).with(:code,"code to run") + + @puppet.main + end + + it "should set the manifest if some files are passed on command line" do + ARGV.stubs(:length).returns(1) + ARGV.stubs(:shift).returns("site.pp") + + Puppet.expects(:[]=).with(:manifest,"site.pp") + + @puppet.main + end + it "should collect the node facts" do Puppet::Node::Facts.expects(:find).returns(@facts) @@ -319,6 +329,74 @@ describe "Puppet" do end end - end + describe "the 'apply' command" do + before do + #Puppet::Resource::Catalog.stubs(:json_create).returns Puppet::Resource::Catalog.new + JSON.stubs(:parse).returns Puppet::Resource::Catalog.new + end + + it "should read the catalog in from disk if a file name is provided" do + @puppet.options[:catalog] = "/my/catalog.json" + + File.expects(:read).with("/my/catalog.json").returns "something" + + @puppet.apply + end + + it "should read the catalog in from stdin if '-' is provided" do + @puppet.options[:catalog] = "-" + + $stdin.expects(:read).returns "something" + + @puppet.apply + end + + it "should deserialize the catalog from json" do + @puppet.options[:catalog] = "/my/catalog.json" + + File.expects(:read).returns "something" + JSON.expects(:parse).with("something").returns Puppet::Resource::Catalog.new + + @puppet.apply + end + + it "should fail helpfully if deserializing fails" do + @puppet.options[:catalog] = "/my/catalog.json" + + File.expects(:read).returns "something" + JSON.expects(:parse).raises ArgumentError + + lambda { @puppet.apply }.should raise_error(Puppet::Error) + end + + it "should convert plain data structures into a catalog if deserialization does not do so" do + @puppet.options[:catalog] = "/my/catalog.json" + + File.expects(:read).returns "something" + JSON.expects(:parse).with("something").returns({:foo => "bar"}) + Puppet::Resource::Catalog.expects(:json_create).with({:foo => "bar"}).returns(Puppet::Resource::Catalog.new) + + @puppet.apply + end + + it "should convert the catalog to a RAL catalog and use a Configurer instance to apply it" do + @puppet.options[:catalog] = "/my/catalog.json" + + File.expects(:read).returns "something" + + catalog = Puppet::Resource::Catalog.new + JSON.expects(:parse).returns catalog + + catalog.expects(:to_ral).returns "mycatalog" + + configurer = stub 'configurer' + Puppet::Configurer.expects(:new).returns configurer + + configurer.expects(:run).with(:catalog => "mycatalog") + + @puppet.apply + end + end + end end diff --git a/spec/unit/configurer.rb b/spec/unit/configurer.rb index 9cf22c80c..85bdb9dac 100755 --- a/spec/unit/configurer.rb +++ b/spec/unit/configurer.rb @@ -57,6 +57,14 @@ describe Puppet::Configurer, "when executing a catalog run" do @agent.run :one => true end + it "should accept a catalog and use it instead of retrieving a different one" do + catalog = stub 'catalog', :retrieval_duration= => nil + @agent.expects(:retrieve_catalog).never + + catalog.expects(:apply).with(:one => true) + @agent.run :one => true, :catalog => catalog + end + it "should benchmark how long it takes to apply the catalog" do @agent.expects(:benchmark).with(:notice, "Finished catalog run") |
