puppet 2.6.8 → 2.6.9

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (60) hide show
  1. data/CHANGELOG +41 -0
  2. data/{README.rst → README.md} +17 -10
  3. data/conf/redhat/puppet.spec +93 -22
  4. data/ext/vim/README +2 -1
  5. data/ext/vim/ftplugin/puppet.vim +94 -0
  6. data/ext/vim/indent/puppet.vim +76 -0
  7. data/lib/puppet.rb +2 -3
  8. data/lib/puppet/application/agent.rb +3 -3
  9. data/lib/puppet/application/apply.rb +16 -5
  10. data/lib/puppet/configurer.rb +60 -56
  11. data/lib/puppet/configurer/fact_handler.rb +6 -1
  12. data/lib/puppet/defaults.rb +19 -0
  13. data/lib/puppet/file_serving/fileset.rb +1 -1
  14. data/lib/puppet/indirector/exec.rb +3 -3
  15. data/lib/puppet/indirector/queue.rb +1 -1
  16. data/lib/puppet/metatype/manager.rb +7 -20
  17. data/lib/puppet/parser/compiler.rb +17 -16
  18. data/lib/puppet/parser/resource.rb +18 -1
  19. data/lib/puppet/parser/scope.rb +2 -2
  20. data/lib/puppet/provider/mount/parsed.rb +1 -1
  21. data/lib/puppet/provider/naginator.rb +9 -1
  22. data/lib/puppet/provider/nameservice/directoryservice.rb +11 -8
  23. data/lib/puppet/provider/package/aptitude.rb +1 -0
  24. data/lib/puppet/rails/host.rb +7 -0
  25. data/lib/puppet/resource/catalog.rb +9 -3
  26. data/lib/puppet/transaction.rb +15 -26
  27. data/lib/puppet/transaction/report.rb +3 -3
  28. data/lib/puppet/type.rb +13 -24
  29. data/lib/puppet/util/queue.rb +1 -1
  30. data/lib/puppet/util/queue/stomp.rb +2 -2
  31. data/lib/puppet/util/settings/file_setting.rb +1 -0
  32. data/spec/integration/defaults_spec.rb +22 -0
  33. data/spec/integration/indirector/catalog/queue_spec.rb +2 -2
  34. data/spec/integration/type_spec.rb +11 -0
  35. data/spec/unit/application/agent_spec.rb +2 -2
  36. data/spec/unit/application/apply_spec.rb +62 -50
  37. data/spec/unit/configurer/fact_handler_spec.rb +43 -37
  38. data/spec/unit/configurer_spec.rb +404 -327
  39. data/spec/unit/file_serving/fileset_spec.rb +7 -0
  40. data/spec/unit/indirector/exec_spec.rb +4 -4
  41. data/spec/unit/indirector/node/exec_spec.rb +1 -1
  42. data/spec/unit/indirector/queue_spec.rb +4 -4
  43. data/spec/unit/node_spec.rb +1 -0
  44. data/spec/unit/parser/compiler_spec.rb +8 -46
  45. data/spec/unit/parser/resource_spec.rb +61 -3
  46. data/spec/unit/parser/scope_spec.rb +9 -3
  47. data/spec/unit/provider/nameservice/directoryservice_spec.rb +60 -0
  48. data/spec/unit/rails/host_spec.rb +8 -0
  49. data/spec/unit/resource/catalog_spec.rb +1 -1
  50. data/spec/unit/transaction/report_spec.rb +3 -3
  51. data/spec/unit/transaction_spec.rb +8 -2
  52. data/spec/unit/type_spec.rb +66 -0
  53. data/spec/unit/util/queue/stomp_spec.rb +10 -10
  54. data/spec/unit/util/settings/file_setting_spec.rb +4 -0
  55. metadata +1229 -1232
  56. data/README +0 -31
  57. data/lib/puppet/provider/nameservice/#directoryservice.rb# +0 -519
  58. data/lib/puppet/reference/#providers.rb# +0 -123
  59. data/spec/unit/indirector/certificate_status/#file_spec.rb# +0 -188
  60. data/spec/unit/resource/#type_collection_spec.rb# +0 -463
@@ -62,13 +62,30 @@ class Puppet::Parser::Resource < Puppet::Resource
62
62
  scope.environment
63
63
  end
64
64
 
65
+ # Process the stage metaparameter for a class. A containment edge
66
+ # is drawn from the class to the stage. The stage for containment
67
+ # defaults to main, if none is specified.
68
+ def add_edge_to_stage
69
+ return unless self.type.to_s.downcase == "class"
70
+
71
+ unless stage = catalog.resource(:stage, self[:stage] || (scope && scope.resource && scope.resource[:stage]) || :main)
72
+ raise ArgumentError, "Could not find stage #{self[:stage] || :main} specified by #{self}"
73
+ end
74
+
75
+ self[:stage] ||= stage.title unless stage.title == :main
76
+ catalog.add_edge(stage, self)
77
+ end
78
+
65
79
  # Retrieve the associated definition and evaluate it.
66
80
  def evaluate
67
81
  return if evaluated?
68
82
  @evaluated = true
69
83
  if klass = resource_type and ! builtin_type?
70
84
  finish
71
- return klass.evaluate_code(self)
85
+ evaluated_code = klass.evaluate_code(self)
86
+ add_edge_to_stage
87
+
88
+ return evaluated_code
72
89
  elsif builtin?
73
90
  devfail "Cannot evaluate a builtin type (#{type})"
74
91
  else
@@ -101,7 +101,7 @@ class Puppet::Parser::Scope
101
101
 
102
102
  # Remove this when rebasing
103
103
  def environment
104
- compiler.environment
104
+ compiler ? compiler.environment : nil
105
105
  end
106
106
 
107
107
  # Are we the top scope?
@@ -513,6 +513,6 @@ class Puppet::Parser::Scope
513
513
 
514
514
  def extend_with_functions_module
515
515
  extend Puppet::Parser::Functions.environment_module(Puppet::Node::Environment.root)
516
- extend Puppet::Parser::Functions.environment_module(compiler ? environment : nil)
516
+ extend Puppet::Parser::Functions.environment_module(environment)
517
517
  end
518
518
  end
@@ -18,7 +18,7 @@ Puppet::Type.type(:mount).provide(
18
18
 
19
19
  commands :mountcmd => "mount", :umount => "umount"
20
20
 
21
- case Facter["operatingsystem"]
21
+ case Facter.value(:operatingsystem)
22
22
  when "Solaris"
23
23
  @fields = [:device, :blockdevice, :name, :fstype, :pass, :atboot, :options]
24
24
  else
@@ -30,7 +30,15 @@ class Puppet::Provider::Naginator < Puppet::Provider::ParsedFile
30
30
  end
31
31
 
32
32
  def self.to_file(records)
33
- header + records.collect { |record| record.to_s }.join("\n").gsub("_naginator_name", NAME_STRING)
33
+ header + records.collect { |record|
34
+ # Remap the TYPE_name or _naginator_name params to the
35
+ # name if the record is a template (register == 0)
36
+ if record.to_s =~ /register\s+0/
37
+ record.to_s.sub("_naginator_name", "name").sub(record.type.to_s + "_name", "name")
38
+ else
39
+ record.to_s.sub("_naginator_name", NAME_STRING)
40
+ end
41
+ }.join("\n")
34
42
  end
35
43
 
36
44
  def self.skip_record?(record)
@@ -235,11 +235,12 @@ class DirectoryService < Puppet::Provider::NameService
235
235
  # have a lot of choice. Ultimately this should all be done using Ruby
236
236
  # to access the DirectoryService APIs directly, but that's simply not
237
237
  # feasible for a while yet.
238
- case self.get_macosx_version_major
239
- when "10.4"
240
- dscl_plist = self.parse_dscl_url_data(dscl_output)
241
- when "10.5", "10.6"
238
+ if self.get_macosx_version_major > "10.4"
242
239
  dscl_plist = self.parse_dscl_plist_data(dscl_output)
240
+ elsif self.get_macosx_version_major == "10.4"
241
+ dscl_plist = self.parse_dscl_url_data(dscl_output)
242
+ else
243
+ fail("Puppet does not support OS X versions < 10.4")
243
244
  end
244
245
 
245
246
  self.generate_attribute_hash(dscl_plist, *type_properties)
@@ -257,12 +258,14 @@ class DirectoryService < Puppet::Provider::NameService
257
258
  # different format for the -url output with objects with spaces in
258
259
  # their values. *sigh*. Use -url for 10.4 in the hope this can be
259
260
  # deprecated one day, and use -plist for 10.5 and higher.
260
- case self.get_macosx_version_major
261
- when "10.4"
262
- command_vector = [ command(:dscl), "-url", "." ]
263
- when "10.5", "10.6"
261
+ if self.get_macosx_version_major > "10.4"
264
262
  command_vector = [ command(:dscl), "-plist", "." ]
263
+ elsif self.get_macosx_version_major == "10.4"
264
+ command_vector = [ command(:dscl), "-url", "." ]
265
+ else
266
+ fail("Puppet does not support OS X versions < 10.4")
265
267
  end
268
+
266
269
  # JJM: The actual action to perform. See "man dscl"
267
270
  # Common actiosn: -create, -delete, -merge, -append, -passwd
268
271
  command_vector << ds_action
@@ -12,6 +12,7 @@ Puppet::Type.type(:package).provide :aptitude, :parent => :apt, :source => :dpkg
12
12
  args.flatten!
13
13
  # Apparently aptitude hasn't always supported a -q flag.
14
14
  args.delete("-q") if args.include?("-q")
15
+ args.delete("--force-yes") if args.include?("--force-yes")
15
16
  output = aptitude(*args)
16
17
 
17
18
  # Yay, stupid aptitude doesn't throw an error when the package is missing.
@@ -1,3 +1,4 @@
1
+ require 'puppet/node/environment'
1
2
  require 'puppet/rails'
2
3
  require 'puppet/rails/resource'
3
4
  require 'puppet/rails/fact_name'
@@ -28,6 +29,12 @@ class Puppet::Rails::Host < ActiveRecord::Base
28
29
  host
29
30
  end
30
31
 
32
+ # Override the setter for environment to force it to be a string, lest it
33
+ # be YAML encoded. See #4487.
34
+ def environment=(value)
35
+ super value.to_s
36
+ end
37
+
31
38
  # returns a hash of fact_names.name => [ fact_values ] for this host.
32
39
  # Note that 'fact_values' is actually a list of the value instances, not
33
40
  # just actual values.
@@ -132,16 +132,22 @@ class Puppet::Resource::Catalog < Puppet::SimpleGraph
132
132
  expire
133
133
 
134
134
  Puppet::Util::Storage.load if host_config?
135
- transaction = Puppet::Transaction.new(self)
136
135
 
137
- transaction.report = options[:report] if options[:report]
136
+ transaction = Puppet::Transaction.new(self, options[:report])
137
+ register_report = options[:report].nil?
138
+
138
139
  transaction.tags = options[:tags] if options[:tags]
139
140
  transaction.ignoreschedules = true if options[:ignoreschedules]
140
141
 
141
142
  transaction.add_times :config_retrieval => self.retrieval_duration || 0
142
143
 
143
144
  begin
144
- transaction.evaluate
145
+ Puppet::Util::Log.newdestination(transaction.report) if register_report
146
+ begin
147
+ transaction.evaluate
148
+ ensure
149
+ Puppet::Util::Log.close(transaction.report) if register_report
150
+ end
145
151
  rescue Puppet::Error => detail
146
152
  puts detail.backtrace if Puppet[:trace]
147
153
  Puppet.err "Could not apply complete catalog: #{detail}"
@@ -15,7 +15,7 @@ class Puppet::Transaction
15
15
  attr_accessor :sorted_resources, :configurator
16
16
 
17
17
  # The report, once generated.
18
- attr_accessor :report
18
+ attr_reader :report
19
19
 
20
20
  # Routes and stores any events and subscriptions.
21
21
  attr_reader :event_manager
@@ -123,31 +123,23 @@ class Puppet::Transaction
123
123
  # collects all of the changes, executes them, and responds to any
124
124
  # necessary events.
125
125
  def evaluate
126
- # Start logging.
127
- Puppet::Util::Log.newdestination(@report)
128
-
129
126
  prepare
130
127
 
131
128
  Puppet.info "Applying configuration version '#{catalog.version}'" if catalog.version
132
129
 
133
- begin
134
- @sorted_resources.each do |resource|
135
- next if stop_processing?
136
- if resource.is_a?(Puppet::Type::Component)
137
- Puppet.warning "Somehow left a component in the relationship graph"
138
- next
139
- end
140
- ret = nil
141
- seconds = thinmark do
142
- ret = eval_resource(resource)
143
- end
144
-
145
- resource.info "Evaluated in %0.2f seconds" % seconds if Puppet[:evaltrace] and @catalog.host_config?
146
- ret
130
+ @sorted_resources.each do |resource|
131
+ next if stop_processing?
132
+ if resource.is_a?(Puppet::Type::Component)
133
+ Puppet.warning "Somehow left a component in the relationship graph"
134
+ next
147
135
  end
148
- ensure
149
- # And then close the transaction log.
150
- Puppet::Util::Log.close(@report)
136
+ ret = nil
137
+ seconds = thinmark do
138
+ ret = eval_resource(resource)
139
+ end
140
+
141
+ resource.info "valuated in %0.2f seconds" % seconds if Puppet[:evaltrace] and @catalog.host_config?
142
+ ret
151
143
  end
152
144
 
153
145
  Puppet.debug "Finishing transaction #{object_id}"
@@ -228,13 +220,10 @@ class Puppet::Transaction
228
220
 
229
221
  # this should only be called by a Puppet::Type::Component resource now
230
222
  # and it should only receive an array
231
- def initialize(catalog)
223
+ def initialize(catalog, report = nil)
232
224
  @catalog = catalog
233
-
234
- @report = Report.new("apply", catalog.version)
235
-
225
+ @report = report || Report.new("apply", catalog.version)
236
226
  @event_manager = Puppet::Transaction::EventManager.new(self)
237
-
238
227
  @resource_harness = Puppet::Transaction::ResourceHarness.new(self)
239
228
  end
240
229
 
@@ -10,8 +10,8 @@ class Puppet::Transaction::Report
10
10
 
11
11
  indirects :report, :terminus_class => :processor
12
12
 
13
- attr_accessor :configuration_version
14
- attr_reader :resource_statuses, :logs, :metrics, :host, :time, :kind, :status
13
+ attr_accessor :configuration_version, :host
14
+ attr_reader :resource_statuses, :logs, :metrics, :time, :kind, :status
15
15
 
16
16
  # This is necessary since Marshall doesn't know how to
17
17
  # dump hash with default proc (see below @records)
@@ -67,7 +67,7 @@ class Puppet::Transaction::Report
67
67
  @logs = []
68
68
  @resource_statuses = {}
69
69
  @external_times ||= {}
70
- @host = Puppet[:certname]
70
+ @host = Puppet[:node_name_value]
71
71
  @time = Time.now
72
72
  @kind = kind
73
73
  @report_format = 2
@@ -1416,9 +1416,8 @@ class Type
1416
1416
  def self.provide(name, options = {}, &block)
1417
1417
  name = Puppet::Util.symbolize(name)
1418
1418
 
1419
- if obj = provider_hash[name]
1419
+ if unprovide(name)
1420
1420
  Puppet.debug "Reloading #{name} #{self.name} provider"
1421
- unprovide(name)
1422
1421
  end
1423
1422
 
1424
1423
  parent = if pname = options[:parent]
@@ -1441,16 +1440,14 @@ class Type
1441
1440
 
1442
1441
  self.providify
1443
1442
 
1444
-
1445
- provider = genclass(
1446
- name,
1447
- :parent => parent,
1448
- :hash => provider_hash,
1449
- :prefix => "Provider",
1450
- :block => block,
1451
- :include => feature_module,
1452
- :extend => feature_module,
1453
-
1443
+ provider = genclass(
1444
+ name,
1445
+ :parent => parent,
1446
+ :hash => provider_hash,
1447
+ :prefix => "Provider",
1448
+ :block => block,
1449
+ :include => feature_module,
1450
+ :extend => feature_module,
1454
1451
  :attributes => options
1455
1452
  )
1456
1453
 
@@ -1510,18 +1507,11 @@ class Type
1510
1507
  end
1511
1508
 
1512
1509
  def self.unprovide(name)
1513
- if provider_hash.has_key? name
1514
-
1515
- rmclass(
1516
- name,
1517
- :hash => provider_hash,
1518
-
1519
- :prefix => "Provider"
1520
- )
1521
- if @defaultprovider and @defaultprovider.name == name
1522
- @defaultprovider = nil
1523
- end
1510
+ if @defaultprovider and @defaultprovider.name == name
1511
+ @defaultprovider = nil
1524
1512
  end
1513
+
1514
+ rmclass(name, :hash => provider_hash, :prefix => "Provider")
1525
1515
  end
1526
1516
 
1527
1517
  # Return an array of all of the suitable providers.
@@ -1581,7 +1571,6 @@ class Type
1581
1571
 
1582
1572
  # Collect the current prereqs
1583
1573
  list.each { |dep|
1584
- obj = nil
1585
1574
  # Support them passing objects directly, to save some effort.
1586
1575
  unless dep.is_a? Puppet::Type
1587
1576
  # Skip autorequires that we aren't managing
@@ -30,7 +30,7 @@ require 'puppet/util/instance_loader'
30
30
  #
31
31
  # The client plugins are expected to implement an interface similar to that of Stomp::Client:
32
32
  # * <tt>new</tt> should return a connected, ready-to-go client instance. Note that no arguments are passed in.
33
- # * <tt>send_message(queue, message)</tt> should send the _message_ to the specified _queue_.
33
+ # * <tt>publish_message(queue, message)</tt> should publish the _message_ to the specified _queue_.
34
34
  # * <tt>subscribe(queue)</tt> _block_ subscribes to _queue_ and executes _block_ upon receiving a message.
35
35
  # * _queue_ names are simple names independent of the message broker or client library. No "/queue/" prefixes like in Stomp::Client.
36
36
  module Puppet::Util::Queue
@@ -28,8 +28,8 @@ class Puppet::Util::Queue::Stomp
28
28
  end
29
29
  end
30
30
 
31
- def send_message(target, msg)
32
- stomp_client.send(stompify_target(target), msg, :persistent => true)
31
+ def publish_message(target, msg)
32
+ stomp_client.publish(stompify_target(target), msg, :persistent => true)
33
33
  end
34
34
 
35
35
  def subscribe(target)
@@ -101,6 +101,7 @@ class Puppet::Util::Settings::FileSetting < Puppet::Util::Settings::Setting
101
101
 
102
102
  resource[:ensure] = type
103
103
  resource[:loglevel] = :debug
104
+ resource[:links] = :follow
104
105
  resource[:backup] = false
105
106
 
106
107
  resource.tag(self.section, self.name, "settings")
@@ -23,6 +23,28 @@ describe "Puppet defaults" do
23
23
  end
24
24
  end
25
25
 
26
+ describe "when setting :node_name_value" do
27
+ it "should default to the value of :certname" do
28
+ Puppet.settings[:certname] = 'blargle'
29
+ Puppet.settings[:node_name_value].should == 'blargle'
30
+ end
31
+ end
32
+
33
+ describe "when setting the :node_name_fact" do
34
+ it "should fail when also setting :node_name_value" do
35
+ lambda do
36
+ Puppet.settings[:node_name_value] = "some value"
37
+ Puppet.settings[:node_name_fact] = "some_fact"
38
+ end.should raise_error("Cannot specify both the node_name_value and node_name_fact settings")
39
+ end
40
+
41
+ it "should not fail when using the default for :node_name_value" do
42
+ lambda do
43
+ Puppet.settings[:node_name_fact] = "some_fact"
44
+ end.should_not raise_error
45
+ end
46
+ end
47
+
26
48
  describe "when configuring the :crl" do
27
49
  it "should warn if :cacrl is set to false" do
28
50
  Puppet.expects(:warning)
@@ -20,13 +20,13 @@ describe "Puppet::Resource::Catalog::Queue", :if => Puppet.features.pson? do
20
20
 
21
21
  after { Puppet.settings.clear }
22
22
 
23
- it "should render catalogs to pson and send them via the queue client when catalogs are saved" do
23
+ it "should render catalogs to pson and publish them via the queue client when catalogs are saved" do
24
24
  terminus = Puppet::Resource::Catalog.indirection.terminus(:queue)
25
25
 
26
26
  client = mock 'client'
27
27
  terminus.stubs(:client).returns client
28
28
 
29
- client.expects(:send_message).with(:catalog, @catalog.to_pson)
29
+ client.expects(:publish_message).with(:catalog, @catalog.to_pson)
30
30
 
31
31
  request = Puppet::Indirector::Request.new(:catalog, :save, "foo", :instance => @catalog)
32
32
 
@@ -19,4 +19,15 @@ describe Puppet::Type do
19
19
 
20
20
  type.provider(:myprovider).should equal(provider)
21
21
  end
22
+
23
+ it "should not lose its provider parameter when it is reloaded" do
24
+ type = Puppet::Type.newtype(:reload_test_type)
25
+
26
+ provider = type.provide(:test_provider)
27
+
28
+ # reload it
29
+ type = Puppet::Type.newtype(:reload_test_type)
30
+
31
+ type.parameters.should include(:provider)
32
+ end
22
33
  end
@@ -411,7 +411,7 @@ describe Puppet::Application::Agent do
411
411
 
412
412
  describe "when setting up listen" do
413
413
  before :each do
414
- Puppet.stubs(:[]).with(:authconfig).returns('auth')
414
+ Puppet.stubs(:[]).with(:rest_authconfig).returns('auth')
415
415
  FileTest.stubs(:exists?).with('auth').returns(true)
416
416
  File.stubs(:exist?).returns(true)
417
417
  @puppetd.options.stubs(:[]).with(:serve).returns([])
@@ -570,7 +570,7 @@ describe Puppet::Application::Agent do
570
570
  @host.stubs(:certificate).returns(@cert)
571
571
  @cert.stubs(:fingerprint).with(:MD5).returns("DIGEST")
572
572
 
573
- Puppet.expects(:notice).with("DIGEST")
573
+ @puppetd.expects(:puts).with "DIGEST"
574
574
 
575
575
  @puppetd.fingerprint
576
576
  end
@@ -5,6 +5,7 @@ require File.dirname(__FILE__) + '/../../spec_helper'
5
5
  require 'puppet/application/apply'
6
6
  require 'puppet/file_bucket/dipper'
7
7
  require 'puppet/configurer'
8
+ require 'fileutils'
8
9
 
9
10
  describe Puppet::Application::Apply do
10
11
  before :each do
@@ -182,38 +183,39 @@ describe Puppet::Application::Apply do
182
183
  end
183
184
 
184
185
  describe "the main command" do
186
+ include PuppetSpec::Files
187
+
185
188
  before :each do
186
- Puppet.stubs(:[])
187
- Puppet.settings.stubs(:use)
188
- Puppet.stubs(:[]).with(:prerun_command).returns ""
189
- Puppet.stubs(:[]).with(:postrun_command).returns ""
190
- Puppet.stubs(:[]).with(:trace).returns(true)
189
+ Puppet[:prerun_command] = ''
190
+ Puppet[:postrun_command] = ''
191
191
 
192
- @apply.options.stubs(:[])
192
+ Puppet::Node::Facts.terminus_class = :memory
193
+ Puppet::Node.terminus_class = :memory
193
194
 
194
- @facts = stub_everything 'facts'
195
- Puppet::Node::Facts.stubs(:find).returns(@facts)
195
+ @facts = Puppet::Node::Facts.new(Puppet[:node_name_value])
196
+ @facts.save
196
197
 
197
- @node = stub_everything 'node'
198
- Puppet::Node.stubs(:find).returns(@node)
198
+ @node = Puppet::Node.new(Puppet[:node_name_value])
199
+ @node.save
199
200
 
200
- @catalog = stub_everything 'catalog'
201
+ @catalog = Puppet::Resource::Catalog.new
201
202
  @catalog.stubs(:to_ral).returns(@catalog)
203
+
202
204
  Puppet::Resource::Catalog.stubs(:find).returns(@catalog)
203
205
 
204
206
  STDIN.stubs(:read)
205
207
 
206
- @transaction = stub_everything 'transaction'
207
- @catalog.stubs(:apply).returns(@transaction)
208
-
209
208
  @apply.stubs(:exit)
210
209
 
210
+ @transaction = Puppet::Transaction.new(@catalog)
211
+ @catalog.stubs(:apply).returns(@transaction)
212
+
211
213
  Puppet::Util::Storage.stubs(:load)
212
214
  Puppet::Configurer.any_instance.stubs(:save_last_run_summary) # to prevent it from trying to write files
213
215
  end
214
216
 
215
217
  it "should set the code to run from --code" do
216
- @apply.options.stubs(:[]).with(:code).returns("code to run")
218
+ @apply.options[:code] = "code to run"
217
219
  Puppet.expects(:[]=).with(:code,"code to run")
218
220
 
219
221
  @apply.main
@@ -229,47 +231,58 @@ describe Puppet::Application::Apply do
229
231
  end
230
232
 
231
233
  it "should set the manifest if a file is passed on command line and the file exists" do
232
- File.stubs(:exist?).with('site.pp').returns true
233
- @apply.command_line.stubs(:args).returns(['site.pp'])
234
+ manifest = tmpfile('site.pp')
235
+ FileUtils.touch(manifest)
236
+ @apply.command_line.stubs(:args).returns([manifest])
234
237
 
235
- Puppet.expects(:[]=).with(:manifest,"site.pp")
238
+ Puppet.expects(:[]=).with(:manifest,manifest)
236
239
 
237
240
  @apply.main
238
241
  end
239
242
 
240
243
  it "should raise an error if a file is passed on command line and the file does not exist" do
241
- File.stubs(:exist?).with('noexist.pp').returns false
242
- @apply.command_line.stubs(:args).returns(['noexist.pp'])
243
- lambda { @apply.main }.should raise_error(RuntimeError, 'Could not find file noexist.pp')
244
+ noexist = tmpfile('noexist.pp')
245
+ @apply.command_line.stubs(:args).returns([noexist])
246
+ lambda { @apply.main }.should raise_error(RuntimeError, "Could not find file #{noexist}")
244
247
  end
245
248
 
246
249
  it "should set the manifest to the first file and warn other files will be skipped" do
247
- File.stubs(:exist?).with('starwarsIV').returns true
248
- File.expects(:exist?).with('starwarsI').never
249
- @apply.command_line.stubs(:args).returns(['starwarsIV', 'starwarsI', 'starwarsII'])
250
+ manifest = tmpfile('starwarsIV')
251
+ FileUtils.touch(manifest)
252
+
253
+ @apply.command_line.stubs(:args).returns([manifest, 'starwarsI', 'starwarsII'])
250
254
 
251
- Puppet.expects(:[]=).with(:manifest,"starwarsIV")
255
+ Puppet.expects(:[]=).with(:manifest,manifest)
252
256
  Puppet.expects(:warning).with('Only one file can be applied per run. Skipping starwarsI, starwarsII')
253
257
 
254
258
  @apply.main
255
259
  end
256
260
 
257
- it "should collect the node facts" do
258
- Puppet::Node::Facts.expects(:find).returns(@facts)
261
+ it "should set the facts name based on the node_name_fact" do
262
+ @facts = Puppet::Node::Facts.new(Puppet[:node_name_value], 'my_name_fact' => 'other_node_name')
263
+ @facts.save
264
+ Puppet::Node.new('other_node_name').save
265
+ Puppet[:node_name_fact] = 'my_name_fact'
259
266
 
260
267
  @apply.main
268
+
269
+ @facts.name.should == 'other_node_name'
261
270
  end
262
271
 
263
- it "should raise an error if we can't find the node" do
264
- Puppet::Node::Facts.expects(:find).returns(nil)
272
+ it "should set the node_name_value based on the node_name_fact" do
273
+ Puppet::Node::Facts.new(Puppet[:node_name_value], 'my_name_fact' => 'other_node_name').save
274
+ Puppet::Node.new('other_node_name').save
275
+ Puppet[:node_name_fact] = 'my_name_fact'
265
276
 
266
- lambda { @apply.main }.should raise_error
277
+ @apply.main
278
+
279
+ Puppet[:node_name_value].should == 'other_node_name'
267
280
  end
268
281
 
269
- it "should look for the node" do
270
- Puppet::Node.expects(:find).returns(@node)
282
+ it "should raise an error if we can't find the facts" do
283
+ Puppet::Node::Facts.expects(:find).returns(nil)
271
284
 
272
- @apply.main
285
+ lambda { @apply.main }.should raise_error
273
286
  end
274
287
 
275
288
  it "should raise an error if we can't find the node" do
@@ -279,21 +292,20 @@ describe Puppet::Application::Apply do
279
292
  end
280
293
 
281
294
  it "should merge in our node the loaded facts" do
282
- @facts.stubs(:values).returns("values")
283
-
284
- @node.expects(:merge).with("values")
295
+ @facts.values = {'key' => 'value'}
285
296
 
286
297
  @apply.main
298
+
299
+ @node.parameters['key'].should == 'value'
287
300
  end
288
301
 
289
302
  it "should load custom classes if loadclasses" do
290
- @apply.options.stubs(:[]).with(:loadclasses).returns(true)
291
- Puppet.stubs(:[]).with(:classfile).returns("/etc/puppet/classes.txt")
292
- FileTest.stubs(:exists?).with("/etc/puppet/classes.txt").returns(true)
293
- FileTest.stubs(:readable?).with("/etc/puppet/classes.txt").returns(true)
294
- File.stubs(:read).with("/etc/puppet/classes.txt").returns("class")
303
+ @apply.options[:loadclasses] = true
304
+ classfile = tmpfile('classfile')
305
+ File.open(classfile, 'w') { |c| c.puts 'class' }
306
+ Puppet[:classfile] = classfile
295
307
 
296
- @node.expects(:classes=)
308
+ @node.expects(:classes=).with(['class'])
297
309
 
298
310
  @apply.main
299
311
  end
@@ -331,9 +343,12 @@ describe Puppet::Application::Apply do
331
343
  end
332
344
 
333
345
  describe "with detailed_exitcodes" do
346
+ before :each do
347
+ @apply.options[:detailed_exitcodes] = true
348
+ end
349
+
334
350
  it "should exit with report's computed exit status" do
335
- Puppet.stubs(:[]).with(:noop).returns(false)
336
- @apply.options.stubs(:[]).with(:detailed_exitcodes).returns(true)
351
+ Puppet[:noop] = false
337
352
  Puppet::Transaction::Report.any_instance.stubs(:exit_status).returns(666)
338
353
  @apply.expects(:exit).with(666)
339
354
 
@@ -341,8 +356,7 @@ describe Puppet::Application::Apply do
341
356
  end
342
357
 
343
358
  it "should exit with report's computed exit status, even if --noop is set" do
344
- Puppet.stubs(:[]).with(:noop).returns(true)
345
- @apply.options.stubs(:[]).with(:detailed_exitcodes).returns(true)
359
+ Puppet[:noop] = true
346
360
  Puppet::Transaction::Report.any_instance.stubs(:exit_status).returns(666)
347
361
  @apply.expects(:exit).with(666)
348
362
 
@@ -350,8 +364,7 @@ describe Puppet::Application::Apply do
350
364
  end
351
365
 
352
366
  it "should always exit with 0 if option is disabled" do
353
- Puppet.stubs(:[]).with(:noop).returns(false)
354
- @apply.options.stubs(:[]).with(:detailed_exitcodes).returns(false)
367
+ Puppet[:noop] = false
355
368
  report = stub 'report', :exit_status => 666
356
369
  @transaction.stubs(:report).returns(report)
357
370
  @apply.expects(:exit).with(0)
@@ -360,8 +373,7 @@ describe Puppet::Application::Apply do
360
373
  end
361
374
 
362
375
  it "should always exit with 0 if --noop" do
363
- Puppet.stubs(:[]).with(:noop).returns(true)
364
- @apply.options.stubs(:[]).with(:detailed_exitcodes).returns(true)
376
+ Puppet[:noop] = true
365
377
  report = stub 'report', :exit_status => 666
366
378
  @transaction.stubs(:report).returns(report)
367
379
  @apply.expects(:exit).with(0)