puppet 0.24.3 → 0.24.4

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 (58) hide show
  1. data/CHANGELOG +66 -0
  2. data/Rakefile +8 -0
  3. data/bin/puppetd +20 -10
  4. data/bin/puppetmasterd +3 -0
  5. data/conf/redhat/puppet.spec +1 -1
  6. data/ext/emacs/puppet-mode.el +132 -70
  7. data/ext/puppet-test +2 -1
  8. data/install.rb +70 -0
  9. data/lib/puppet.rb +1 -1
  10. data/lib/puppet/defaults.rb +7 -8
  11. data/lib/puppet/file_serving/configuration/parser.rb +4 -2
  12. data/lib/puppet/indirector/facts/facter.rb +2 -1
  13. data/lib/puppet/indirector/node/ldap.rb +2 -1
  14. data/lib/puppet/indirector/node/plain.rb +7 -0
  15. data/lib/puppet/indirector/report/processor.rb +2 -1
  16. data/lib/puppet/indirector/yaml.rb +0 -5
  17. data/lib/puppet/metatype/evaluation.rb +13 -3
  18. data/lib/puppet/metatype/metaparams.rb +3 -3
  19. data/lib/puppet/metatype/providers.rb +2 -9
  20. data/lib/puppet/network/authstore.rb +2 -1
  21. data/lib/puppet/network/client.rb +3 -2
  22. data/lib/puppet/network/client/master.rb +4 -2
  23. data/lib/puppet/network/handler/fileserver.rb +0 -49
  24. data/lib/puppet/network/handler/master.rb +1 -1
  25. data/lib/puppet/network/handler/report.rb +2 -1
  26. data/lib/puppet/network/http/mongrel/rest.rb +4 -2
  27. data/lib/puppet/network/http/webrick/rest.rb +5 -3
  28. data/lib/puppet/network/http_pool.rb +18 -7
  29. data/lib/puppet/node.rb +1 -1
  30. data/lib/puppet/node/environment.rb +2 -1
  31. data/lib/puppet/parser/parser_support.rb +12 -9
  32. data/lib/puppet/provider/mailalias/aliases.rb +4 -1
  33. data/lib/puppet/provider/package/openbsd.rb +10 -2
  34. data/lib/puppet/provider/package/ports.rb +1 -2
  35. data/lib/puppet/provider/user/useradd.rb +1 -1
  36. data/lib/puppet/provider/zone/solaris.rb +2 -1
  37. data/lib/puppet/resource_reference.rb +2 -1
  38. data/lib/puppet/transportable.rb +28 -20
  39. data/lib/puppet/type/exec.rb +5 -0
  40. data/lib/puppet/type/host.rb +2 -1
  41. data/lib/puppet/type/service.rb +3 -1
  42. data/lib/puppet/util.rb +2 -1
  43. data/lib/puppet/util/constant_inflector.rb +2 -1
  44. data/lib/puppet/util/diff.rb +2 -2
  45. data/lib/puppet/util/fileparsing.rb +2 -1
  46. data/lib/puppet/util/settings.rb +26 -23
  47. data/lib/puppet/util/tagging.rb +2 -1
  48. data/test/language/parser.rb +1 -0
  49. data/test/lib/puppettest.rb +6 -1
  50. data/test/network/client/client.rb +0 -29
  51. data/test/network/client/master.rb +31 -0
  52. data/test/network/handler/master.rb +4 -0
  53. data/test/ral/manager/provider.rb +21 -5
  54. data/test/ral/providers/cron/crontab.rb +0 -1
  55. data/test/ral/providers/mailalias/aliases.rb +0 -1
  56. data/test/ral/providers/sshkey/parsed.rb +0 -1
  57. data/test/ral/type/tidy.rb +6 -7
  58. metadata +2 -2
@@ -25,7 +25,7 @@ require 'puppet/util/suidmanager'
25
25
  # it's also a place to find top-level commands like 'debug'
26
26
 
27
27
  module Puppet
28
- PUPPETVERSION = '0.24.3'
28
+ PUPPETVERSION = '0.24.4'
29
29
 
30
30
  def Puppet.version
31
31
  return PUPPETVERSION
@@ -346,11 +346,15 @@ module Puppet
346
346
  :ssl_client_header => ["HTTP_X_CLIENT_DN", "The header containing an authenticated
347
347
  client's SSL DN. Only used with Mongrel. This header must be set by the proxy
348
348
  to the authenticated client's SSL DN (e.g., ``/CN=puppet.reductivelabs.com``).
349
- See the `UsingMongrel`:trac: wiki page for more information."],
349
+ See http://reductivelabs.com/puppet/trac/wiki/UsingMongrel for more information."],
350
350
  :ssl_client_verify_header => ["HTTP_X_CLIENT_VERIFY", "The header containing the status
351
351
  message of the client verification. Only used with Mongrel. This header must be set by the proxy
352
352
  to 'SUCCESS' if the client successfully authenticated, and anything else otherwise.
353
- See the `UsingMongrel`:trac: wiki page for more information."]
353
+ See http://reductivelabs.com/puppet/trac/wiki/UsingMongrel for more information."],
354
+ # To make sure this directory is created before we try to use it on the server, we need
355
+ # it to be in the server section (#1138).
356
+ :yamldir => {:default => "$vardir/yaml", :owner => "$user", :group => "$user", :mode => "750",
357
+ :desc => "The directory in which YAML data is stored, usually in a subdirectory."}
354
358
  )
355
359
 
356
360
  self.setdefaults(:puppetd,
@@ -600,7 +604,7 @@ module Puppet
600
604
  setdefaults(:ldap,
601
605
  :ldapnodes => [false,
602
606
  "Whether to search for node configurations in LDAP. See
603
- `LdapNodes`:trac: for more information."],
607
+ http://reductivelabs.com/puppet/trac/wiki/LdapNodes/ for more information."],
604
608
  :ldapssl => [false,
605
609
  "Whether SSL should be used when searching for nodes.
606
610
  Defaults to false because SSL usually requires certificates
@@ -671,10 +675,5 @@ module Puppet
671
675
  :rrdinterval => ["$runinterval", "How often RRD should expect data.
672
676
  This should match how often the hosts report back to the server."]
673
677
  )
674
-
675
- Puppet.setdefaults(:yaml,
676
- :yamldir => {:default => "$vardir/yaml", :owner => "$user", :group => "$user", :mode => "750",
677
- :desc => "The directory in which YAML data is stored, usually in a subdirectory."}
678
- )
679
678
  end
680
679
 
@@ -62,7 +62,8 @@ class Puppet::FileServing::Configuration::Parser < Puppet::Util::LoadedFile
62
62
 
63
63
  # Allow a given pattern access to a mount.
64
64
  def allow(mount, value)
65
- value.split(/\s*,\s*/).each { |val|
65
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
66
+ x = value.split(/\s*,\s*/).each { |val|
66
67
  begin
67
68
  mount.info "allowing %s access" % val
68
69
  mount.allow(val)
@@ -75,7 +76,8 @@ class Puppet::FileServing::Configuration::Parser < Puppet::Util::LoadedFile
75
76
 
76
77
  # Deny a given pattern access to a mount.
77
78
  def deny(mount, value)
78
- value.split(/\s*,\s*/).each { |val|
79
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
80
+ x = value.split(/\s*,\s*/).each { |val|
79
81
  begin
80
82
  mount.info "denying %s access" % val
81
83
  mount.deny(val)
@@ -23,7 +23,8 @@ class Puppet::Node::Facts::Facter < Puppet::Indirector::Code
23
23
  end
24
24
 
25
25
  def self.loadfacts
26
- Puppet[:factpath].split(":").each do |dir|
26
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
27
+ x = Puppet[:factpath].split(":").each do |dir|
27
28
  loaddir(dir, "fact")
28
29
  end
29
30
  end
@@ -7,7 +7,8 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
7
7
 
8
8
  # The attributes that Puppet class information is stored in.
9
9
  def class_attributes
10
- Puppet[:ldapclassattrs].split(/\s*,\s*/)
10
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
11
+ x = Puppet[:ldapclassattrs].split(/\s*,\s*/)
11
12
  end
12
13
 
13
14
  # Look for our node in ldap.
@@ -16,4 +16,11 @@ class Puppet::Node::Plain < Puppet::Indirector::Plain
16
16
  node.fact_merge
17
17
  node
18
18
  end
19
+
20
+ # Use the version of the facts, since we assume that's the main thing
21
+ # that changes. If someone wants their own way of defining version,
22
+ # they can easily provide their own, um, version of this class.
23
+ def version(name)
24
+ Puppet::Node::Facts.version(name)
25
+ end
19
26
  end
@@ -45,6 +45,7 @@ class Puppet::Transaction::Report::Processor < Puppet::Indirector::Code
45
45
 
46
46
  # Handle the parsing of the reports attribute.
47
47
  def reports
48
- Puppet[:reports].gsub(/(^\s+)|(\s+$)/, '').split(/\s*,\s*/)
48
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
49
+ x = Puppet[:reports].gsub(/(^\s+)|(\s+$)/, '').split(/\s*,\s*/)
49
50
  end
50
51
  end
@@ -2,11 +2,6 @@ require 'puppet/indirector/terminus'
2
2
 
3
3
  # The base class for YAML indirection termini.
4
4
  class Puppet::Indirector::Yaml < Puppet::Indirector::Terminus
5
- def initialize
6
- # Make sure our base directory exists.
7
- Puppet.settings.use(:yaml)
8
- end
9
-
10
5
  # Read a given name's file in and convert it from YAML.
11
6
  def find(name)
12
7
  raise ArgumentError.new("You must specify the name of the object to retrieve") unless name
@@ -4,6 +4,11 @@ class Puppet::Type
4
4
  # This returns any changes resulting from testing, thus 'collect' rather
5
5
  # than 'each'.
6
6
  def evaluate
7
+ if self.provider.is_a?(Puppet::Provider)
8
+ unless provider.class.suitable?
9
+ raise Puppet::Error, "Provider %s is not functional on this platform" % provider.class.name
10
+ end
11
+ end
7
12
  #Puppet.err "Evaluating %s" % self.path.join(":")
8
13
  unless defined? @evalcount
9
14
  self.err "No evalcount defined on '%s' of type '%s'" %
@@ -125,14 +130,19 @@ class Puppet::Type
125
130
  # the other properties matter.
126
131
  changes = []
127
132
  ensureparam = @parameters[:ensure]
128
- if @parameters.include?(:ensure) && !currentvalues.include?(ensureparam)
133
+
134
+ # This allows resource types to have 'ensure' be a parameter, which allows them to
135
+ # just pass the parameter on to other generated resources.
136
+ ensureparam = nil unless ensureparam.is_a?(Puppet::Property)
137
+ if ensureparam && !currentvalues.include?(ensureparam)
129
138
  raise Puppet::DevError, "Parameter ensure defined but missing from current values"
130
139
  end
131
- if @parameters.include?(:ensure) and ! ensureparam.insync?(currentvalues[ensureparam])
140
+
141
+ if ensureparam and ! ensureparam.insync?(currentvalues[ensureparam])
132
142
  changes << Puppet::PropertyChange.new(ensureparam, currentvalues[ensureparam])
133
143
  # Else, if the 'ensure' property is correctly absent, then do
134
144
  # nothing
135
- elsif @parameters.include?(:ensure) and currentvalues[ensureparam] == :absent
145
+ elsif ensureparam and currentvalues[ensureparam] == :absent
136
146
  return []
137
147
  else
138
148
  changes = properties().find_all { |property|
@@ -375,7 +375,7 @@ class Puppet::Type
375
375
  }
376
376
  service { nagios:
377
377
  running => true,
378
- subscribe => file[nagconf]
378
+ subscribe => File[nagconf]
379
379
  }
380
380
  }
381
381
 
@@ -392,7 +392,7 @@ class Puppet::Type
392
392
  file { "/var/nagios/configuration":
393
393
  source => "...",
394
394
  recurse => true,
395
- before => exec["nagios-rebuid"]
395
+ before => Exec["nagios-rebuid"]
396
396
  }
397
397
 
398
398
  exec { "nagios-rebuild":
@@ -410,7 +410,7 @@ class Puppet::Type
410
410
 
411
411
  file { "/etc/sshd_config":
412
412
  source => "....",
413
- notify => service[sshd]
413
+ notify => Service[sshd]
414
414
  }
415
415
 
416
416
  service { sshd:
@@ -188,15 +188,8 @@ class Puppet::Type
188
188
  provider_class = provider_class.class.name
189
189
  end
190
190
 
191
- if provider = @resource.class.provider(provider_class)
192
- unless provider.suitable?
193
- raise ArgumentError,
194
- "Provider '%s' is not functional on this platform" %
195
- [provider_class]
196
- end
197
- else
198
- raise ArgumentError, "Invalid %s provider '%s'" %
199
- [@resource.class.name, provider_class]
191
+ unless provider = @resource.class.provider(provider_class)
192
+ raise ArgumentError, "Invalid %s provider '%s'" % [@resource.class.name, provider_class]
200
193
  end
201
194
  end
202
195
 
@@ -235,7 +235,8 @@ module Puppet
235
235
 
236
236
  # Convert the name to a common pattern.
237
237
  def munge_name(name)
238
- name.downcase.split(".").reverse
238
+ # LAK:NOTE http://snurl.com/21zf8 [groups_google_com]
239
+ x = name.downcase.split(".").reverse
239
240
  end
240
241
 
241
242
  # Parse our input pattern and figure out what kind of allowal
@@ -96,8 +96,9 @@ class Puppet::Network::Client
96
96
  self.read_cert
97
97
 
98
98
  # We have to start the HTTP connection manually before we start
99
- # sending it requests or keep-alive won't work.
100
- @driver.start if @driver.respond_to? :start
99
+ # sending it requests or keep-alive won't work. Note that with #1010,
100
+ # we don't currently actually want keep-alive.
101
+ @driver.start if @driver.respond_to? :start and Puppet::Network::HttpPool.keep_alive?
101
102
 
102
103
  @local = false
103
104
  elsif hash.include?(driverparam)
@@ -50,7 +50,8 @@ class Puppet::Network::Client::Master < Puppet::Network::Client
50
50
 
51
51
  # Return the list of dynamic facts as an array of symbols
52
52
  def self.dynamic_facts
53
- Puppet.settings[:dynamicfacts].split(/\s*,\s*/).collect { |fact| fact.downcase }
53
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
54
+ x = Puppet.settings[:dynamicfacts].split(/\s*,\s*/).collect { |fact| fact.downcase }
54
55
  end
55
56
 
56
57
  # Cache the config
@@ -425,7 +426,8 @@ class Puppet::Network::Client::Master < Puppet::Network::Client
425
426
  end
426
427
 
427
428
  def self.loadfacts
428
- Puppet[:factpath].split(":").each do |dir|
429
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
430
+ x = Puppet[:factpath].split(":").each do |dir|
429
431
  loaddir(dir, "fact")
430
432
  end
431
433
  end
@@ -429,55 +429,6 @@ class Puppet::Network::Handler
429
429
 
430
430
  Puppet::Util.logmethods(self, true)
431
431
 
432
- def getfileobject(dir, links, client = nil)
433
- unless path_exists?(dir, client)
434
- self.debug "File source %s does not exist" % dir
435
- return nil
436
- end
437
-
438
- return fileobj(dir, links, client)
439
- end
440
-
441
- # Run 'retrieve' on a file. This gets the actual parameters, so
442
- # we can pass them to the client.
443
- def check(obj)
444
- # Retrieval is enough here, because we don't want to cache
445
- # any information in the state file, and we don't want to generate
446
- # any state changes or anything. We don't even need to sync
447
- # the checksum, because we're always going to hit the disk
448
- # directly.
449
-
450
- # We're now caching file data, using the LoadedFile to check the
451
- # disk no more frequently than the :filetimeout.
452
- path = obj[:path]
453
- sync = sync(path)
454
- unless data = @@files[path]
455
- data = {}
456
- sync.synchronize(Sync::EX) do
457
- @@files[path] = data
458
- data[:loaded_obj] = Puppet::Util::LoadedFile.new(path)
459
- data[:values] = properties(obj)
460
- return data[:values]
461
- end
462
- end
463
-
464
- changed = nil
465
- sync.synchronize(Sync::SH) do
466
- changed = data[:loaded_obj].changed?
467
- end
468
-
469
- if changed
470
- sync.synchronize(Sync::EX) do
471
- data[:values] = properties(obj)
472
- return data[:values]
473
- end
474
- else
475
- sync.synchronize(Sync::SH) do
476
- return data[:values]
477
- end
478
- end
479
- end
480
-
481
432
  # Create a map for a specific client.
482
433
  def clientmap(client)
483
434
  {
@@ -81,9 +81,9 @@ class Puppet::Network::Handler
81
81
  clientip = facts["ipaddress"]
82
82
  if Puppet[:node_name] == 'cert'
83
83
  if name
84
+ client = name
84
85
  facts["fqdn"] = client
85
86
  facts["hostname"], facts["domain"] = client.split('.', 2)
86
- client = name
87
87
  end
88
88
  if ip
89
89
  clientip = ip
@@ -79,7 +79,8 @@ class Puppet::Network::Handler
79
79
 
80
80
  # Handle the parsing of the reports attribute.
81
81
  def reports
82
- Puppet[:reports].gsub(/(^\s+)|(\s+$)/, '').split(/\s*,\s*/)
82
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
83
+ x = Puppet[:reports].gsub(/(^\s+)|(\s+$)/, '').split(/\s*,\s*/)
83
84
  end
84
85
  end
85
86
  end
@@ -14,11 +14,13 @@ class Puppet::Network::HTTP::MongrelREST < Puppet::Network::HTTP::Handler
14
14
  end
15
15
 
16
16
  def path(request)
17
- '/' + request.params[Mongrel::Const::REQUEST_PATH].split('/')[1]
17
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
18
+ x = '/' + request.params[Mongrel::Const::REQUEST_PATH].split('/')[1]
18
19
  end
19
20
 
20
21
  def request_key(request)
21
- request.params[Mongrel::Const::REQUEST_PATH].split('/')[2]
22
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
23
+ x = request.params[Mongrel::Const::REQUEST_PATH].split('/')[2]
22
24
  end
23
25
 
24
26
  def body(request)
@@ -19,11 +19,13 @@ class Puppet::Network::HTTP::WEBrickREST < Puppet::Network::HTTP::Handler
19
19
  end
20
20
 
21
21
  def path(request)
22
- '/' + request.path.split('/')[1]
22
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
23
+ x = '/' + request.path.split('/')[1]
23
24
  end
24
25
 
25
26
  def request_key(request)
26
- request.path.split('/')[2]
27
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
28
+ x = request.path.split('/')[2]
27
29
  end
28
30
 
29
31
  def body(request)
@@ -38,4 +40,4 @@ class Puppet::Network::HTTP::WEBrickREST < Puppet::Network::HTTP::Handler
38
40
  response.status = status
39
41
  response.body = result
40
42
  end
41
- end
43
+ end
@@ -6,6 +6,15 @@ end
6
6
 
7
7
  # Manage Net::HTTP instances for keep-alive.
8
8
  module Puppet::Network::HttpPool
9
+ # 2008/03/23
10
+ # LAK:WARNING: Enabling this has a high propability of
11
+ # causing corrupt files and who knows what else. See #1010.
12
+ HTTP_KEEP_ALIVE = false
13
+
14
+ def self.keep_alive?
15
+ HTTP_KEEP_ALIVE
16
+ end
17
+
9
18
  # This handles reading in the key and such-like.
10
19
  extend Puppet::SSLCertificates::Support
11
20
  @http_cache = {}
@@ -56,12 +65,14 @@ module Puppet::Network::HttpPool
56
65
 
57
66
  # Return our cached instance if we've got a cache, as long as we're not
58
67
  # resetting the instance.
59
- return @http_cache[key] if ! reset and @http_cache[key]
60
-
61
- # Clean up old connections if we have them.
62
- if http = @http_cache[key]
63
- @http_cache.delete(key)
64
- http.finish if http.started?
68
+ if keep_alive?
69
+ return @http_cache[key] if ! reset and @http_cache[key]
70
+
71
+ # Clean up old connections if we have them.
72
+ if http = @http_cache[key]
73
+ @http_cache.delete(key)
74
+ http.finish if http.started?
75
+ end
65
76
  end
66
77
 
67
78
  args = [host, port]
@@ -88,7 +99,7 @@ module Puppet::Network::HttpPool
88
99
 
89
100
  cert_setup(http)
90
101
 
91
- @http_cache[key] = http
102
+ @http_cache[key] = http if keep_alive?
92
103
 
93
104
  return http
94
105
  end
@@ -10,7 +10,7 @@ class Puppet::Node
10
10
  extend Puppet::Indirector
11
11
 
12
12
  # Use the node source as the indirection terminus.
13
- indirects :node, :terminus_setting => :node_terminus, :cache_class => :yaml, :doc => "Where to find node information.
13
+ indirects :node, :terminus_setting => :node_terminus, :doc => "Where to find node information.
14
14
  A node is composed of its name, its facts, and its environment."
15
15
 
16
16
  # Retrieve a node from the node source, with some additional munging
@@ -4,7 +4,8 @@ class Puppet::Node::Environment
4
4
  # Return the list of valid environments. Just looks them up in
5
5
  # the settings.
6
6
  def self.valid
7
- Puppet.settings.value(:environments).split(",").collect { |e| e.to_sym }
7
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
8
+ x = Puppet.settings.value(:environments).split(",").collect { |e| e.to_sym }
8
9
  end
9
10
 
10
11
  # Is the provided environment valid?
@@ -123,13 +123,17 @@ class Puppet::Parser::Parser
123
123
  def fqfind(namespace, name, table)
124
124
  namespace = namespace.downcase
125
125
  name = name.to_s.downcase
126
+
127
+ # If our classname is fully qualified or we have no namespace,
128
+ # just try directly for the class, and return either way.
126
129
  if name =~ /^::/ or namespace == ""
127
130
  classname = name.sub(/^::/, '')
128
- unless table[classname]
129
- self.load(classname)
130
- end
131
+ self.load(classname) unless table[classname]
131
132
  return table[classname]
132
133
  end
134
+
135
+ # Else, build our namespace up piece by piece, checking
136
+ # for the class in each namespace.
133
137
  ary = namespace.split("::")
134
138
 
135
139
  while ary.length > 0
@@ -221,7 +225,6 @@ class Puppet::Parser::Parser
221
225
  return false if classname == ""
222
226
  filename = classname.gsub("::", File::SEPARATOR)
223
227
 
224
- loaded = false
225
228
  # First try to load the top-level module
226
229
  mod = filename.scan(/^[\w-]+/).shift
227
230
  unless @loaded.include?(mod)
@@ -229,24 +232,24 @@ class Puppet::Parser::Parser
229
232
  begin
230
233
  import(mod)
231
234
  Puppet.info "Autoloaded module %s" % mod
232
- loaded = true
233
235
  rescue Puppet::ImportError => detail
234
236
  # We couldn't load the module
235
237
  end
236
238
  end
237
239
 
238
- unless filename == mod and ! @loaded.include?(mod)
239
- @loaded << mod
240
+ return true if classes.include?(classname)
241
+
242
+ unless @loaded.include?(filename)
243
+ @loaded << filename
240
244
  # Then the individual file
241
245
  begin
242
246
  import(filename)
243
247
  Puppet.info "Autoloaded file %s from module %s" % [filename, mod]
244
- loaded = true
245
248
  rescue Puppet::ImportError => detail
246
249
  # We couldn't load the file
247
250
  end
248
251
  end
249
- return loaded
252
+ return classes.include?(classname)
250
253
  end
251
254
 
252
255
  # Split an fq name into a namespace and name