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
@@ -24,7 +24,7 @@ require 'puppet/util/run_mode'
24
24
  # it's also a place to find top-level commands like 'debug'
25
25
 
26
26
  module Puppet
27
- PUPPETVERSION = '2.6.8'
27
+ PUPPETVERSION = '2.6.9'
28
28
 
29
29
  def Puppet.version
30
30
  PUPPETVERSION
@@ -59,8 +59,7 @@ module Puppet
59
59
 
60
60
  # configuration parameter access and stuff
61
61
  def self.[](param)
62
- case param
63
- when :debug
62
+ if param == :debug
64
63
  return Puppet::Util::Log.level == :debug
65
64
  else
66
65
  return @@settings[param]
@@ -98,7 +98,7 @@ class Puppet::Application::Agent < Puppet::Application
98
98
  unless fingerprint = cert.fingerprint(options[:digest])
99
99
  raise ArgumentError, "Could not get fingerprint for digest '#{options[:digest]}'"
100
100
  end
101
- Puppet.notice fingerprint
101
+ puts fingerprint
102
102
  end
103
103
 
104
104
  def onetime
@@ -168,8 +168,8 @@ class Puppet::Application::Agent < Puppet::Application
168
168
  end
169
169
 
170
170
  def setup_listen
171
- unless FileTest.exists?(Puppet[:authconfig])
172
- Puppet.err "Will not start without authorization file #{Puppet[:authconfig]}"
171
+ unless FileTest.exists?(Puppet[:rest_authconfig])
172
+ Puppet.err "Will not start without authorization file #{Puppet[:rest_authconfig]}"
173
173
  exit(14)
174
174
  end
175
175
 
@@ -85,13 +85,18 @@ class Puppet::Application::Apply < Puppet::Application
85
85
  end
86
86
 
87
87
  # Collect our facts.
88
- unless facts = Puppet::Node::Facts.find(Puppet[:certname])
89
- raise "Could not find facts for #{Puppet[:certname]}"
88
+ unless facts = Puppet::Node::Facts.find(Puppet[:node_name_value])
89
+ raise "Could not find facts for #{Puppet[:node_name_value]}"
90
+ end
91
+
92
+ unless Puppet[:node_name_fact].empty?
93
+ Puppet[:node_name_value] = facts.values[Puppet[:node_name_fact]]
94
+ facts.name = Puppet[:node_name_value]
90
95
  end
91
96
 
92
97
  # Find our Node
93
- unless node = Puppet::Node.find(Puppet[:certname])
94
- raise "Could not find node #{Puppet[:certname]}"
98
+ unless node = Puppet::Node.find(Puppet[:node_name_value])
99
+ raise "Could not find node #{Puppet[:node_name_value]}"
95
100
  end
96
101
 
97
102
  # Merge in the facts.
@@ -125,7 +130,13 @@ class Puppet::Application::Apply < Puppet::Application
125
130
  configurer = Puppet::Configurer.new
126
131
  report = configurer.run(:skip_plugin_download => true, :catalog => catalog)
127
132
 
128
- exit( options[:detailed_exitcodes] ? report.exit_status : 0 )
133
+ if not report
134
+ exit(1)
135
+ elsif options[:detailed_exitcodes] then
136
+ exit(report.exit_status)
137
+ else
138
+ exit(0)
139
+ end
129
140
  rescue => detail
130
141
  puts detail.backtrace if Puppet[:trace]
131
142
  $stderr.puts detail.message
@@ -5,8 +5,6 @@ require 'puppet/network/http_pool'
5
5
  require 'puppet/util'
6
6
 
7
7
  class Puppet::Configurer
8
- class CommandHookError < RuntimeError; end
9
-
10
8
  require 'puppet/configurer/fact_handler'
11
9
  require 'puppet/configurer/plugin_handler'
12
10
 
@@ -79,21 +77,11 @@ class Puppet::Configurer
79
77
  download_plugins unless options[:skip_plugin_download]
80
78
 
81
79
  download_fact_plugins unless options[:skip_plugin_download]
82
-
83
- execute_prerun_command
84
80
  end
85
81
 
86
82
  # Get the remote catalog, yo. Returns nil if no catalog can be found.
87
- def retrieve_catalog
88
- if Puppet::Resource::Catalog.indirection.terminus_class == :rest
89
- # This is a bit complicated. We need the serialized and escaped facts,
90
- # and we need to know which format they're encoded in. Thus, we
91
- # get a hash with both of these pieces of information.
92
- fact_options = facts_for_uploading
93
- else
94
- fact_options = {}
95
- end
96
-
83
+ def retrieve_catalog(fact_options)
84
+ fact_options ||= {}
97
85
  # First try it with no cache, then with the cache.
98
86
  unless (Puppet[:use_cached_catalog] and result = retrieve_catalog_from_cache(fact_options)) or result = retrieve_new_catalog(fact_options)
99
87
  if ! Puppet[:usecacheonfailure]
@@ -117,60 +105,73 @@ class Puppet::Configurer
117
105
  catalog
118
106
  end
119
107
 
108
+ # Retrieve (optionally) and apply a catalog. If a catalog is passed in
109
+ # the options, then apply that one, otherwise retrieve it.
110
+ def retrieve_and_apply_catalog(options, fact_options)
111
+ unless catalog = (options.delete(:catalog) || retrieve_catalog(fact_options))
112
+ Puppet.err "Could not retrieve catalog; skipping run"
113
+ return
114
+ end
115
+
116
+ report = options[:report]
117
+ report.configuration_version = catalog.version
118
+
119
+ benchmark(:notice, "Finished catalog run") do
120
+ catalog.apply(options)
121
+ end
122
+
123
+ report.finalize_report
124
+ report
125
+ end
126
+
120
127
  # The code that actually runs the catalog.
121
128
  # This just passes any options on to the catalog,
122
129
  # which accepts :tags and :ignoreschedules.
123
130
  def run(options = {})
124
- begin
125
- prepare(options)
126
- rescue SystemExit,NoMemoryError
127
- raise
128
- rescue Exception => detail
129
- puts detail.backtrace if Puppet[:trace]
130
- Puppet.err "Failed to prepare catalog: #{detail}"
131
- end
132
-
133
131
  options[:report] ||= Puppet::Transaction::Report.new("apply")
134
132
  report = options[:report]
135
- Puppet::Util::Log.newdestination(report)
136
133
 
137
- if catalog = options[:catalog]
138
- options.delete(:catalog)
139
- elsif ! catalog = retrieve_catalog
140
- Puppet.err "Could not retrieve catalog; skipping run"
141
- return
142
- end
134
+ Puppet::Util::Log.newdestination(report)
135
+ begin
136
+ prepare(options)
143
137
 
144
- report.configuration_version = catalog.version
138
+ if Puppet::Resource::Catalog.indirection.terminus_class == :rest
139
+ # This is a bit complicated. We need the serialized and escaped facts,
140
+ # and we need to know which format they're encoded in. Thus, we
141
+ # get a hash with both of these pieces of information.
142
+ fact_options = facts_for_uploading
143
+ end
145
144
 
146
- transaction = nil
145
+ # set report host name now that we have the fact
146
+ report.host = Puppet[:node_name_value]
147
147
 
148
- begin
149
- benchmark(:notice, "Finished catalog run") do
150
- transaction = catalog.apply(options)
148
+ begin
149
+ execute_prerun_command or return nil
150
+ retrieve_and_apply_catalog(options, fact_options)
151
+ rescue SystemExit,NoMemoryError
152
+ raise
153
+ rescue => detail
154
+ puts detail.backtrace if Puppet[:trace]
155
+ Puppet.err "Failed to apply catalog: #{detail}"
156
+ return nil
157
+ ensure
158
+ execute_postrun_command or return nil
151
159
  end
152
- report
153
- rescue => detail
154
- puts detail.backtrace if Puppet[:trace]
155
- Puppet.err "Failed to apply catalog: #{detail}"
156
- return
160
+ ensure
161
+ # Make sure we forget the retained module_directories of any autoload
162
+ # we might have used.
163
+ Thread.current[:env_module_directories] = nil
164
+
165
+ # Now close all of our existing http connections, since there's no
166
+ # reason to leave them lying open.
167
+ Puppet::Network::HttpPool.clear_http_instances
157
168
  end
158
169
  ensure
159
- # Make sure we forget the retained module_directories of any autoload
160
- # we might have used.
161
- Thread.current[:env_module_directories] = nil
162
-
163
- # Now close all of our existing http connections, since there's no
164
- # reason to leave them lying open.
165
- Puppet::Network::HttpPool.clear_http_instances
166
- execute_postrun_command
167
-
168
170
  Puppet::Util::Log.close(report)
169
- send_report(report, transaction)
171
+ send_report(report)
170
172
  end
171
173
 
172
- def send_report(report, trans)
173
- report.finalize_report if trans
174
+ def send_report(report)
174
175
  puts report.summary if Puppet[:summarize]
175
176
  save_last_run_summary(report)
176
177
  report.save if Puppet[:report]
@@ -208,19 +209,22 @@ class Puppet::Configurer
208
209
  end
209
210
 
210
211
  def execute_from_setting(setting)
211
- return if (command = Puppet[setting]) == ""
212
+ return true if (command = Puppet[setting]) == ""
212
213
 
213
214
  begin
214
215
  Puppet::Util.execute([command])
216
+ true
215
217
  rescue => detail
216
- raise CommandHookError, "Could not run command from #{setting}: #{detail}"
218
+ puts detail.backtrace if Puppet[:trace]
219
+ Puppet.err "Could not run command from #{setting}: #{detail}"
220
+ false
217
221
  end
218
222
  end
219
223
 
220
224
  def retrieve_catalog_from_cache(fact_options)
221
225
  result = nil
222
226
  @duration = thinmark do
223
- result = Puppet::Resource::Catalog.find(Puppet[:certname], fact_options.merge(:ignore_terminus => true))
227
+ result = Puppet::Resource::Catalog.find(Puppet[:node_name_value], fact_options.merge(:ignore_terminus => true))
224
228
  end
225
229
  Puppet.notice "Using cached catalog"
226
230
  result
@@ -233,7 +237,7 @@ class Puppet::Configurer
233
237
  def retrieve_new_catalog(fact_options)
234
238
  result = nil
235
239
  @duration = thinmark do
236
- result = Puppet::Resource::Catalog.find(Puppet[:certname], fact_options.merge(:ignore_cache => true))
240
+ result = Puppet::Resource::Catalog.find(Puppet[:node_name_value], fact_options.merge(:ignore_cache => true))
237
241
  end
238
242
  result
239
243
  rescue SystemExit,NoMemoryError
@@ -16,7 +16,12 @@ module Puppet::Configurer::FactHandler
16
16
  # compile them and then "cache" them on the server.
17
17
  begin
18
18
  reload_facter
19
- Puppet::Node::Facts.find(Puppet[:certname])
19
+ facts = Puppet::Node::Facts.find(Puppet[:node_name_value])
20
+ unless Puppet[:node_name_fact].empty?
21
+ Puppet[:node_name_value] = facts.values[Puppet[:node_name_fact]]
22
+ facts.name = Puppet[:node_name_value]
23
+ end
24
+ facts
20
25
  rescue SystemExit,NoMemoryError
21
26
  raise
22
27
  rescue Exception => detail
@@ -486,6 +486,25 @@ module Puppet
486
486
  )
487
487
 
488
488
  setdefaults(:agent,
489
+ :node_name_value => { :default => "$certname",
490
+ :desc => "The explicit value used for the node name for all requests the agent
491
+ makes to the master. WARNING: This setting is mutually exclusive with
492
+ node_name_fact. Changing this setting also requires changes to the default
493
+ auth.conf configuration on the Puppet Master. Please see
494
+ http://links.puppetlabs.com/node_name_value for more information."
495
+ },
496
+ :node_name_fact => { :default => "",
497
+ :desc => "The fact name used to determine the node name used for all requests the agent
498
+ makes to the master. WARNING: This setting is mutually exclusive with
499
+ node_name_value. Changing this setting also requires changes to the default
500
+ auth.conf configuration on the Puppet Master. Please see
501
+ http://links.puppetlabs.com/node_name_fact for more information.",
502
+ :hook => proc do |value|
503
+ if !value.empty? and Puppet[:node_name_value] != Puppet[:certname]
504
+ raise "Cannot specify both the node_name_value and node_name_fact settings"
505
+ end
506
+ end
507
+ },
489
508
  :localconfig => { :default => "$statedir/localconfig",
490
509
  :owner => "root",
491
510
  :mode => 0660,
@@ -59,7 +59,7 @@ class Puppet::FileServing::Fileset
59
59
  end
60
60
 
61
61
  def initialize(path, options = {})
62
- path = path.chomp(File::SEPARATOR)
62
+ path = path.chomp(File::SEPARATOR) unless path == File::SEPARATOR
63
63
  raise ArgumentError.new("Fileset paths must be fully qualified") unless File.expand_path(path) == path
64
64
 
65
65
  @path = path
@@ -16,8 +16,8 @@ class Puppet::Indirector::Exec < Puppet::Indirector::Terminus
16
16
  private
17
17
 
18
18
  # Proxy the execution, so it's easier to test.
19
- def execute(command)
20
- Puppet::Util.execute(command)
19
+ def execute(command, arguments)
20
+ Puppet::Util.execute(command,arguments)
21
21
  end
22
22
 
23
23
  # Call the external command and see if it returns our output.
@@ -33,7 +33,7 @@ class Puppet::Indirector::Exec < Puppet::Indirector::Terminus
33
33
  # Add our name to it.
34
34
  external_command << name
35
35
  begin
36
- output = execute(external_command)
36
+ output = execute(external_command, :combine => false)
37
37
  rescue Puppet::ExecutionFailure => detail
38
38
  raise Puppet::Error, "Failed to find #{name} via exec: #{detail}"
39
39
  end
@@ -36,7 +36,7 @@ class Puppet::Indirector::Queue < Puppet::Indirector::Terminus
36
36
  def save(request)
37
37
  result = nil
38
38
  benchmark :info, "Queued #{indirection.name} for #{request.key}" do
39
- result = client.send_message(queue, request.instance.render(:pson))
39
+ result = client.publish_message(queue, request.instance.render(:pson))
40
40
  end
41
41
  result
42
42
  rescue => detail
@@ -61,10 +61,9 @@ module Manager
61
61
 
62
62
  # Then create the class.
63
63
 
64
- klass = genclass(
65
- name,
64
+ klass = genclass(
65
+ name,
66
66
  :parent => (parent || Puppet::Type),
67
-
68
67
  :overwrite => true,
69
68
  :hash => @types,
70
69
  :attributes => options,
@@ -87,14 +86,11 @@ module Manager
87
86
 
88
87
  # Now set up autoload any providers that might exist for this type.
89
88
 
90
- klass.providerloader = Puppet::Util::Autoload.new(
91
- klass,
92
-
93
- "puppet/provider/#{klass.name.to_s}"
94
- )
89
+ klass.providerloader = Puppet::Util::Autoload.new(klass, "puppet/provider/#{klass.name.to_s}")
95
90
 
96
- # We have to load everything so that we can figure out the default type.
91
+ # We have to load everything so that we can figure out the default provider.
97
92
  klass.providerloader.loadall
93
+ klass.providify unless klass.providers.empty?
98
94
 
99
95
  klass
100
96
  end
@@ -103,11 +99,7 @@ module Manager
103
99
  def rmtype(name)
104
100
  # Then create the class.
105
101
 
106
- klass = rmclass(
107
- name,
108
-
109
- :hash => @types
110
- )
102
+ klass = rmclass(name, :hash => @types)
111
103
 
112
104
  singleton_class.send(:remove_method, "new#{name}") if respond_to?("new#{name}")
113
105
  end
@@ -132,12 +124,7 @@ module Manager
132
124
  # Create a loader for Puppet types.
133
125
  def typeloader
134
126
  unless defined?(@typeloader)
135
-
136
- @typeloader = Puppet::Util::Autoload.new(
137
- self,
138
-
139
- "puppet/type", :wrap => false
140
- )
127
+ @typeloader = Puppet::Util::Autoload.new(self, "puppet/type", :wrap => false)
141
128
  end
142
129
 
143
130
  @typeloader
@@ -15,15 +15,19 @@ class Puppet::Parser::Compiler
15
15
  include Puppet::Resource::TypeCollectionHelper
16
16
 
17
17
  def self.compile(node)
18
+ # We get these from the environment and only cache them in a thread
19
+ # variable for the duration of the compilation. If nothing else is using
20
+ # the thread, though, we can leave 'em hanging round with no ill effects,
21
+ # and this is safer than cleaning them at the end and assuming that will
22
+ # stick until the next entry to this function.
23
+ Thread.current[:known_resource_types] = nil
24
+ Thread.current[:env_module_directories] = nil
25
+
26
+ # ...and we actually do the compile now we have caching ready.
18
27
  new(node).compile.to_resource
19
28
  rescue => detail
20
29
  puts detail.backtrace if Puppet[:trace]
21
30
  raise Puppet::Error, "#{detail} on node #{node.name}"
22
- ensure
23
- # We get these from the environment and only cache them in a thread
24
- # variable for the duration of the compilation.
25
- Thread.current[:known_resource_types] = nil
26
- Thread.current[:env_module_directories] = nil
27
31
  end
28
32
 
29
33
  attr_reader :node, :facts, :collections, :catalog, :node_scope, :resources, :relationships
@@ -56,23 +60,20 @@ class Puppet::Parser::Compiler
56
60
  # Note that this will fail if the resource is not unique.
57
61
  @catalog.add_resource(resource)
58
62
 
63
+ if resource.type.to_s.downcase != "class" && resource[:stage]
64
+ raise ArgumentError, "Only classes can set 'stage'; normal resources like #{resource} cannot change run stage"
65
+ end
59
66
 
60
- # Add our container edge. If we're a class, then we get treated specially - we can
61
- # control the stage that the class is applied in. Otherwise, we just
62
- # get added to our parent container.
67
+ # Stages should not be inside of classes. They are always a
68
+ # top-level container, regardless of where they appear in the
69
+ # manifest.
63
70
  return if resource.type.to_s.downcase == "stage"
64
71
 
72
+ # This adds a resource to the class it lexically appears in in the
73
+ # manifest.
65
74
  if resource.type.to_s.downcase != "class"
66
- raise ArgumentError, "Only classes can set 'stage'; normal resources like #{resource} cannot change run stage" if resource[:stage]
67
75
  return @catalog.add_edge(scope.resource, resource)
68
76
  end
69
-
70
- unless stage = @catalog.resource(:stage, resource[:stage] || (scope && scope.resource && scope.resource[:stage]) || :main)
71
- raise ArgumentError, "Could not find stage #{resource[:stage] || :main} specified by #{resource}"
72
- end
73
-
74
- resource[:stage] ||= stage.title unless stage.title == :main
75
- @catalog.add_edge(stage, resource)
76
77
  end
77
78
 
78
79
  # Do we use nodes found in the code, vs. the external node sources?