puppet 2.6.2 → 2.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. data/CHANGELOG +61 -0
  2. data/ext/envpuppet +80 -0
  3. data/ext/puppet-load.rb +62 -26
  4. data/ext/puppetstoredconfigclean.rb +0 -2
  5. data/lib/puppet.rb +1 -1
  6. data/lib/puppet/daemon.rb +2 -2
  7. data/lib/puppet/defaults.rb +10 -8
  8. data/lib/puppet/external/pson/pure/generator.rb +5 -12
  9. data/lib/puppet/indirector/catalog/compiler.rb +8 -4
  10. data/lib/puppet/network/handler/fileserver.rb +2 -0
  11. data/lib/puppet/network/server.rb +2 -2
  12. data/lib/puppet/node/environment.rb +4 -0
  13. data/lib/puppet/parser/ast/collection.rb +34 -51
  14. data/lib/puppet/parser/ast/leaf.rb +10 -2
  15. data/lib/puppet/parser/ast/resource.rb +4 -3
  16. data/lib/puppet/parser/compiler.rb +2 -2
  17. data/lib/puppet/parser/functions.rb +4 -2
  18. data/lib/puppet/parser/lexer.rb +2 -1
  19. data/lib/puppet/parser/parser_support.rb +3 -3
  20. data/lib/puppet/provider.rb +2 -2
  21. data/lib/puppet/provider/confine/exists.rb +1 -4
  22. data/lib/puppet/provider/mount.rb +1 -1
  23. data/lib/puppet/provider/nameservice.rb +3 -1
  24. data/lib/puppet/provider/package/openbsd.rb +6 -10
  25. data/lib/puppet/provider/service/freebsd.rb +4 -1
  26. data/lib/puppet/provider/service/launchd.rb +1 -1
  27. data/lib/puppet/provider/user/user_role_add.rb +8 -6
  28. data/lib/puppet/provider/user/useradd.rb +7 -8
  29. data/lib/puppet/rails.rb +2 -6
  30. data/lib/puppet/rails/host.rb +0 -72
  31. data/lib/puppet/resource.rb +22 -0
  32. data/lib/puppet/resource/type.rb +18 -13
  33. data/lib/puppet/type/exec.rb +1 -7
  34. data/lib/puppet/type/schedule.rb +5 -5
  35. data/lib/puppet/util.rb +20 -18
  36. data/lib/puppet/util/command_line.rb +1 -1
  37. data/lib/puppet/util/file_locking.rb +6 -3
  38. data/lib/puppet/util/metric.rb +1 -1
  39. data/lib/puppet/util/rdoc.rb +5 -4
  40. data/lib/puppet/util/rdoc/generators/puppet_generator.rb +6 -0
  41. data/lib/puppet/util/reference.rb +1 -10
  42. data/lib/puppet/util/suidmanager.rb +1 -1
  43. data/lib/puppet/util/zaml.rb +4 -1
  44. data/spec/integration/indirector/bucket_file/rest_spec.rb +10 -2
  45. data/spec/integration/indirector/certificate_revocation_list/rest_spec.rb +10 -2
  46. data/spec/integration/parser/functions_spec.rb +21 -0
  47. data/spec/integration/parser/ruby_manifest_spec.rb +1 -1
  48. data/spec/integration/ssl/certificate_authority_spec.rb +1 -3
  49. data/spec/integration/util/file_locking_spec.rb +31 -11
  50. data/spec/spec_helper.rb +1 -1
  51. data/spec/unit/application/apply_spec.rb +1 -1
  52. data/spec/unit/daemon_spec.rb +3 -9
  53. data/spec/unit/indirector/catalog/compiler_spec.rb +9 -8
  54. data/spec/unit/network/handler/fileserver_spec.rb +2 -4
  55. data/spec/unit/network/server_spec.rb +3 -10
  56. data/spec/unit/parser/ast/collection_spec.rb +4 -0
  57. data/spec/unit/parser/ast/leaf_spec.rb +43 -1
  58. data/spec/unit/parser/ast/resource_spec.rb +133 -88
  59. data/spec/unit/parser/compiler_spec.rb +8 -8
  60. data/spec/unit/parser/lexer_spec.rb +1 -0
  61. data/spec/unit/parser/parser_spec.rb +9 -2
  62. data/spec/unit/provider/confine/exists_spec.rb +6 -13
  63. data/spec/unit/provider/mount_spec.rb +8 -1
  64. data/spec/unit/provider/service/freebsd_spec.rb +50 -0
  65. data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +1 -2
  66. data/spec/unit/provider/user/user_role_add_spec.rb +1 -1
  67. data/spec/unit/provider/user/useradd_spec.rb +42 -0
  68. data/spec/unit/rails_spec.rb +82 -22
  69. data/spec/unit/resource/type_spec.rb +13 -13
  70. data/spec/unit/type/schedule_spec.rb +21 -49
  71. data/spec/unit/util/command_line_spec.rb +2 -2
  72. data/spec/unit/util/file_locking_spec.rb +28 -24
  73. data/spec/unit/util/{json_spec.rb → pson_spec.rb} +17 -0
  74. data/spec/unit/util/rdoc_spec.rb +9 -1
  75. data/spec/unit/util/storage_spec.rb +2 -3
  76. data/test/other/provider.rb +1 -12
  77. data/test/other/report.rb +2 -5
  78. data/test/puppet/tc_suidmanager.rb +5 -14
  79. data/test/ral/manager/type.rb +1 -1
  80. data/test/ral/providers/provider.rb +3 -3
  81. data/test/util/metrics.rb +2 -2
  82. metadata +8 -6
  83. data/spec/integration/indirector/rest_spec.rb +0 -525
@@ -107,10 +107,14 @@ class Puppet::Resource::Catalog::Compiler < Puppet::Indirector::Code
107
107
  return node
108
108
  end
109
109
 
110
- # If the request is authenticated, then the 'node' info will
111
- # be available; if not, then we use the passed-in key. We rely
112
- # on our authorization system to determine whether this is allowed.
113
- name = request.node || request.key
110
+ # We rely on our authorization system to determine whether the connected
111
+ # node is allowed to compile the catalog's node referenced by key.
112
+ # By default the REST authorization system makes sure only the connected node
113
+ # can compile his catalog.
114
+ # This allows for instance monitoring systems or puppet-load to check several
115
+ # node's catalog with only one certificate and a modification to auth.conf
116
+ # If no key is provided we can only compile the currently connected node.
117
+ name = request.key || request.node
114
118
  if node = find_node(name)
115
119
  return node
116
120
  end
@@ -5,6 +5,8 @@ require 'cgi'
5
5
  require 'delegate'
6
6
  require 'sync'
7
7
 
8
+ require 'puppet/network/handler'
9
+ require 'puppet/network/xmlrpc/server'
8
10
  require 'puppet/file_serving'
9
11
  require 'puppet/file_serving/metadata'
10
12
 
@@ -32,14 +32,14 @@ class Puppet::Network::Server
32
32
  # Create a pidfile for our daemon, so we can be stopped and others
33
33
  # don't try to start.
34
34
  def create_pidfile
35
- Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
35
+ Puppet::Util.synchronize_on(Puppet[:name],Sync::EX) do
36
36
  raise "Could not create PID file: #{pidfile}" unless Puppet::Util::Pidlock.new(pidfile).lock
37
37
  end
38
38
  end
39
39
 
40
40
  # Remove the pid file for our daemon.
41
41
  def remove_pidfile
42
- Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
42
+ Puppet::Util.synchronize_on(Puppet[:name],Sync::EX) do
43
43
  locker = Puppet::Util::Pidlock.new(pidfile)
44
44
  locker.unlock or Puppet.err "Could not remove PID file #{pidfile}" if locker.locked?
45
45
  end
@@ -124,6 +124,10 @@ class Puppet::Node::Environment
124
124
  name.to_s
125
125
  end
126
126
 
127
+ def to_sym
128
+ to_s.to_sym
129
+ end
130
+
127
131
  # The only thing we care about when serializing an environment is its
128
132
  # identity; everything else is ephemeral and should not be stored or
129
133
  # transmitted.
@@ -5,61 +5,44 @@ require 'puppet/parser/collector'
5
5
  # An object that collects stored objects from the central cache and returns
6
6
  # them to the current host, yo.
7
7
  class Puppet::Parser::AST
8
- class Collection < AST::Branch
9
- attr_accessor :type, :query, :form
10
- attr_reader :override
11
-
12
- associates_doc
13
-
14
- # We return an object that does a late-binding evaluation.
15
- def evaluate(scope)
16
- if self.query
17
- str, code = self.query.safeevaluate scope
18
- else
19
- str = code = nil
20
- end
21
-
22
- newcoll = Puppet::Parser::Collector.new(scope, @type, str, code, self.form)
23
-
24
- scope.compiler.add_collection(newcoll)
25
-
26
- # overrides if any
27
- # Evaluate all of the specified params.
28
- if @override
29
- params = @override.collect do |param|
30
- param.safeevaluate(scope)
8
+ class Collection < AST::Branch
9
+ attr_accessor :type, :query, :form
10
+ attr_reader :override
11
+
12
+ associates_doc
13
+
14
+ # We return an object that does a late-binding evaluation.
15
+ def evaluate(scope)
16
+ str, code = query && query.safeevaluate(scope)
17
+
18
+ resource_type = scope.find_resource_type(@type)
19
+ newcoll = Puppet::Parser::Collector.new(scope, resource_type.name, str, code, self.form)
20
+
21
+ scope.compiler.add_collection(newcoll)
22
+
23
+ # overrides if any
24
+ # Evaluate all of the specified params.
25
+ if @override
26
+ params = @override.collect { |param| param.safeevaluate(scope) }
27
+ newcoll.add_override(
28
+ :parameters => params,
29
+ :file => @file,
30
+ :line => @line,
31
+ :source => scope.source,
32
+ :scope => scope
33
+ )
31
34
  end
32
35
 
33
-
34
- newcoll.add_override(
35
-
36
- :parameters => params,
37
- :file => @file,
38
- :line => @line,
39
- :source => scope.source,
40
-
41
- :scope => scope
42
- )
36
+ newcoll
43
37
  end
44
38
 
45
- newcoll
46
- end
47
-
48
- # Handle our parameter ourselves
49
- def override=(override)
50
- if override.is_a?(AST::ASTArray)
51
- @override = override
52
- else
53
-
54
- @override = AST::ASTArray.new(
55
-
56
- :line => override.line,
57
- :file => override.file,
58
-
59
- :children => [override]
60
- )
39
+ # Handle our parameter ourselves
40
+ def override=(override)
41
+ @override = if override.is_a?(AST::ASTArray)
42
+ override
43
+ else
44
+ AST::ASTArray.new(:line => override.line,:file => override.file,:children => [override])
45
+ end
61
46
  end
62
47
  end
63
-
64
- end
65
48
  end
@@ -148,12 +148,20 @@ class Puppet::Parser::AST
148
148
  key.respond_to?(:evaluate) ? key.safeevaluate(scope) : key
149
149
  end
150
150
 
151
+ def array_index_or_key(object, key)
152
+ if object.is_a?(Array)
153
+ raise Puppet::ParserError, "#{key} is not an integer, but is used as an index of an array" unless key = Puppet::Parser::Scope.number?(key)
154
+ end
155
+ key
156
+ end
157
+
151
158
  def evaluate(scope)
152
159
  object = evaluate_container(scope)
160
+ accesskey = evaluate_key(scope)
153
161
 
154
162
  raise Puppet::ParseError, "#{variable} is not an hash or array when accessing it with #{accesskey}" unless object.is_a?(Hash) or object.is_a?(Array)
155
163
 
156
- object[evaluate_key(scope)]
164
+ object[array_index_or_key(object, accesskey)]
157
165
  end
158
166
 
159
167
  # Assign value to this hashkey or array index
@@ -166,7 +174,7 @@ class Puppet::Parser::AST
166
174
  end
167
175
 
168
176
  # assign to hash or array
169
- object[accesskey] = value
177
+ object[array_index_or_key(object, accesskey)] = value
170
178
  end
171
179
 
172
180
  def to_s
@@ -49,10 +49,11 @@ class Resource < AST::ResourceReference
49
49
  :strict => true
50
50
  )
51
51
 
52
- # And then store the resource in the compiler.
53
- # At some point, we need to switch all of this to return
54
- # resources instead of storing them like this.
52
+ if resource.resource_type.is_a? Puppet::Resource::Type
53
+ resource.resource_type.instantiate_resource(scope, resource)
54
+ end
55
55
  scope.compiler.add_resource(scope, resource)
56
+ scope.compiler.evaluate_classes([resource_title],scope,false) if fully_qualified_type == 'class'
56
57
  resource
57
58
  end
58
59
  }.reject { |resource| resource.nil? }
@@ -144,7 +144,7 @@ class Puppet::Parser::Compiler
144
144
  if klass = scope.find_hostclass(name)
145
145
  found << name and next if scope.class_scope(klass)
146
146
 
147
- resource = klass.mk_plain_resource(scope)
147
+ resource = klass.ensure_in_catalog(scope)
148
148
 
149
149
  # If they've disabled lazy evaluation (which the :include function does),
150
150
  # then evaluate our resource immediately.
@@ -220,7 +220,7 @@ class Puppet::Parser::Compiler
220
220
 
221
221
  # Create a resource to model this node, and then add it to the list
222
222
  # of resources.
223
- resource = astnode.mk_plain_resource(topscope)
223
+ resource = astnode.ensure_in_catalog(topscope)
224
224
 
225
225
  resource.evaluate
226
226
 
@@ -73,8 +73,10 @@ module Puppet::Parser::Functions
73
73
  def self.function(name)
74
74
  name = symbolize(name)
75
75
 
76
- unless functions.include?(name) or functions(Puppet::Node::Environment.root).include?(name)
77
- autoloader.load(name,Environment.current || Environment.root)
76
+ @functions.synchronize do
77
+ unless functions.include?(name) or functions(Puppet::Node::Environment.root).include?(name)
78
+ autoloader.load(name,Environment.current || Environment.root)
79
+ end
78
80
  end
79
81
 
80
82
  ( functions(Environment.root)[name] || functions[name] || {:name => false} )[:name]
@@ -522,13 +522,14 @@ class Puppet::Parser::Lexer
522
522
  # backslash; the caret is there to match empty strings
523
523
  str = @scanner.scan_until(/([^\\]|^|[^\\])([\\]{2})*[#{terminators}]/) or lex_error "Unclosed quote after '#{last}' in '#{rest}'"
524
524
  @line += str.count("\n") # literal carriage returns add to the line count.
525
- str.gsub!(/\\(.)/) {
525
+ str.gsub!(/\\(.)/m) {
526
526
  ch = $1
527
527
  if escapes.include? ch
528
528
  case ch
529
529
  when 'n'; "\n"
530
530
  when 't'; "\t"
531
531
  when 's'; " "
532
+ when "\n": ''
532
533
  else ch
533
534
  end
534
535
  else
@@ -46,12 +46,12 @@ class Puppet::Parser::Parser
46
46
  # Create an AST object, and automatically add the file and line information if
47
47
  # available.
48
48
  def ast(klass, hash = {})
49
- klass.new ast_context(klass.use_docs).merge(hash)
49
+ klass.new ast_context(klass.use_docs, hash[:line]).merge(hash)
50
50
  end
51
51
 
52
- def ast_context(include_docs = false)
52
+ def ast_context(include_docs = false, ast_line = nil)
53
53
  result = {
54
- :line => lexer.line,
54
+ :line => ast_line || lexer.line,
55
55
  :file => lexer.file
56
56
  }
57
57
  result[:doc] = lexer.getcomment(result[:line]) if include_docs
@@ -12,7 +12,7 @@ class Puppet::Provider
12
12
  Puppet::Util.logmethods(self, true)
13
13
 
14
14
  class << self
15
- # Include the util module so we have access to things like 'binary'
15
+ # Include the util module so we have access to things like 'which'
16
16
  include Puppet::Util, Puppet::Util::Docs
17
17
  include Puppet::Util::Logging
18
18
  attr_accessor :name
@@ -43,7 +43,7 @@ class Puppet::Provider
43
43
  raise Puppet::DevError, "No command #{name} defined for provider #{self.name}"
44
44
  end
45
45
 
46
- binary(command)
46
+ which(command)
47
47
  end
48
48
 
49
49
  # Define commands that are not optional.
@@ -6,10 +6,7 @@ class Puppet::Provider::Confine::Exists < Puppet::Provider::Confine
6
6
  end
7
7
 
8
8
  def pass?(value)
9
- if for_binary?
10
- return false unless value = binary(value)
11
- end
12
- value and FileTest.exist?(value)
9
+ value && (for_binary? ? which(value) : FileTest.exist?(value))
13
10
  end
14
11
 
15
12
  def message(value)
@@ -41,7 +41,7 @@ module Puppet::Provider::Mount
41
41
  case platform
42
42
  when "Darwin"
43
43
  line =~ / on #{name} / or line =~ %r{ on /private/var/automount#{name}}
44
- when "Solaris"
44
+ when "Solaris", "HP-UX"
45
45
  line =~ /^#{name} on /
46
46
  else
47
47
  line =~ / on #{name} /
@@ -165,7 +165,9 @@ class Puppet::Provider::NameService < Puppet::Provider
165
165
 
166
166
  begin
167
167
  execute(self.addcmd)
168
- execute(self.passcmd) if self.feature? :manages_password_age
168
+ if feature?(:manages_password_age) && (cmd = passcmd)
169
+ execute(cmd)
170
+ end
169
171
  rescue Puppet::ExecutionFailure => detail
170
172
  raise Puppet::Error, "Could not create #{@resource.class.name} #{@resource.name}: #{detail}"
171
173
  end
@@ -2,7 +2,6 @@ require 'puppet/provider/package'
2
2
 
3
3
  # Packaging on OpenBSD. Doesn't work anywhere else that I know of.
4
4
  Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Package do
5
- include Puppet::Util::Execution
6
5
  desc "OpenBSD's form of `pkg_add` support."
7
6
 
8
7
  commands :pkginfo => "pkg_info", :pkgadd => "pkg_add", :pkgdelete => "pkg_delete"
@@ -61,18 +60,15 @@ Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Packa
61
60
  "You must specify a package source for BSD packages"
62
61
  end
63
62
 
64
- old_ensure = @resource[:ensure]
65
-
66
- if @resource[:source] =~ /\/$/
67
- withenv :PKG_PATH => @resource[:source] do
68
- @resource[:ensure] = old_ensure if (@resource[:ensure] = get_version) == nil
69
- full_name = [ @resource[:name], @resource[:ensure], @resource[:flavor] ]
70
- pkgadd full_name.join('-').chomp('-')
71
- end
63
+ if @resource[:source][-1,1] == ::File::PATH_SEPARATOR
64
+ e_vars = { :PKG_PATH => @resource[:source] }
65
+ full_name = [ @resource[:name], get_version || @resource[:ensure], @resource[:flavor] ].join('-').chomp('-')
72
66
  else
73
- pkgadd @resource[:source]
67
+ e_vars = {}
68
+ full_name = @resource[:source]
74
69
  end
75
70
 
71
+ Puppet::Util::Execution::withenv(e_vars) { pkgadd full_name }
76
72
  end
77
73
 
78
74
  def get_version
@@ -18,6 +18,9 @@ Puppet::Type.type(:service).provide :freebsd, :parent => :init do
18
18
  def rcvar
19
19
  rcvar = execute([self.initscript, :rcvar], :failonfail => true, :squelch => false)
20
20
  rcvar = rcvar.split("\n")
21
+ rcvar.delete_if {|str| str =~ /^#\s*$/}
22
+ rcvar[1] = rcvar[1].gsub(/^\$/, '')
23
+ rcvar
21
24
  end
22
25
 
23
26
  # Extract service name
@@ -44,7 +47,7 @@ Puppet::Type.type(:service).provide :freebsd, :parent => :init do
44
47
  def rcvar_value
45
48
  value = self.rcvar[1]
46
49
  self.error("No rcvar value found in rcvar") if value.nil?
47
- value = value.gsub!(/(.*)_enable=\"?(.*)\"?/, '\2')
50
+ value = value.gsub!(/(.*)_enable="?(\w+)"?/, '\2')
48
51
  self.error("rcvar value is empty") if value.nil?
49
52
  self.debug("rcvar value is #{value}")
50
53
  value
@@ -56,7 +56,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
56
56
  # Read a plist, whether its format is XML or in Apple's "binary1"
57
57
  # format.
58
58
  def self.read_plist(path)
59
- Plist::parse_xml(plutil('-convert', 'xml1', '-o', '-', path))
59
+ Plist::parse_xml(plutil('-convert', 'xml1', '-o', '/dev/stdout', path))
60
60
  end
61
61
 
62
62
  # returns a label => path map for either all jobs, or just a single
@@ -6,15 +6,15 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source =>
6
6
 
7
7
  defaultfor :operatingsystem => :solaris
8
8
 
9
- commands :add => "useradd", :delete => "userdel", :modify => "usermod", :password => "chage", :role_add => "roleadd", :role_delete => "roledel", :role_modify => "rolemod"
9
+ commands :add => "useradd", :delete => "userdel", :modify => "usermod", :password => "passwd", :role_add => "roleadd", :role_delete => "roledel", :role_modify => "rolemod"
10
10
  options :home, :flag => "-d", :method => :dir
11
11
  options :comment, :method => :gecos
12
12
  options :groups, :flag => "-G"
13
13
  options :roles, :flag => "-R"
14
14
  options :auths, :flag => "-A"
15
15
  options :profiles, :flag => "-P"
16
- options :password_min_age, :flag => "-m"
17
- options :password_max_age, :flag => "-M"
16
+ options :password_min_age, :flag => "-n"
17
+ options :password_max_age, :flag => "-x"
18
18
 
19
19
  verify :gid, "GID must be an integer" do |value|
20
20
  value.is_a? Integer
@@ -81,7 +81,9 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source =>
81
81
  run(transition("normal"), "transition role to")
82
82
  else
83
83
  run(addcmd, "create")
84
- run(passcmd, "change password policy for")
84
+ if cmd = passcmd
85
+ run(cmd, "change password policy for")
86
+ end
85
87
  end
86
88
  # added to handle case when password is specified
87
89
  self.password = @resource[:password] if @resource[:password]
@@ -154,11 +156,11 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source =>
154
156
  shadow_entry[1] if shadow_entry
155
157
  end
156
158
 
157
- def min_age
159
+ def password_min_age
158
160
  shadow_entry ? shadow_entry[3] : :absent
159
161
  end
160
162
 
161
- def max_age
163
+ def password_max_age
162
164
  shadow_entry ? shadow_entry[4] : :absent
163
165
  end
164
166
 
@@ -70,16 +70,15 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
70
70
  end
71
71
 
72
72
  def passcmd
73
- cmd = [command(:password)]
74
- [:password_min_age, :password_max_age].each do |property|
75
- if value = @resource.should(property)
76
- cmd << flag(property) << value
77
- end
73
+ age_limits = [:password_min_age, :password_max_age].select { |property| @resource.should(property) }
74
+ if age_limits.empty?
75
+ nil
76
+ else
77
+ [command(:password),age_limits.collect { |property| [flag(property), @resource.should(property)]}, @resource[:name]].flatten
78
78
  end
79
- cmd << @resource[:name]
80
79
  end
81
80
 
82
- def min_age
81
+ def password_min_age
83
82
  if Puppet.features.libshadow?
84
83
  if ent = Shadow::Passwd.getspnam(@resource.name)
85
84
  return ent.sp_min
@@ -88,7 +87,7 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
88
87
  :absent
89
88
  end
90
89
 
91
- def max_age
90
+ def password_max_age
92
91
  if Puppet.features.libshadow?
93
92
  if ent = Shadow::Passwd.getspnam(@resource.name)
94
93
  return ent.sp_max