puppet 3.8.4 → 3.8.5
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.
- data/ext/build_defaults.yaml +4 -4
- data/lib/puppet/daemon.rb +15 -6
- data/lib/puppet/node.rb +11 -2
- data/lib/puppet/pops/evaluator/access_operator.rb +12 -3
- data/lib/puppet/pops/issues.rb +4 -0
- data/lib/puppet/pops/types/type_calculator.rb +1 -5
- data/lib/puppet/pops/types/type_factory.rb +6 -0
- data/lib/puppet/pops/types/types.rb +3 -15
- data/lib/puppet/pops/validation/checker4_0.rb +10 -0
- data/lib/puppet/provider/group/windows_adsi.rb +9 -0
- data/lib/puppet/provider/package/pip.rb +11 -1
- data/lib/puppet/provider/service/launchd.rb +6 -0
- data/lib/puppet/provider/service/upstart.rb +5 -1
- data/lib/puppet/resource.rb +1 -1
- data/lib/puppet/type/group.rb +15 -3
- data/lib/puppet/util/windows/security.rb +4 -1
- data/lib/puppet/version.rb +1 -1
- data/spec/integration/util/windows/security_spec.rb +18 -0
- data/spec/unit/daemon_spec.rb +15 -6
- data/spec/unit/node_spec.rb +8 -0
- data/spec/unit/pops/evaluator/access_ops_spec.rb +4 -4
- data/spec/unit/pops/parser/parser_rspec_helper.rb +5 -0
- data/spec/unit/pops/validator/validator_spec.rb +12 -0
- data/spec/unit/provider/group/windows_adsi_spec.rb +5 -0
- data/spec/unit/provider/package/pip_spec.rb +42 -13
- data/spec/unit/provider/service/launchd_spec.rb +11 -0
- data/spec/unit/provider/service/upstart_spec.rb +57 -0
- metadata +2 -2
data/ext/build_defaults.yaml
CHANGED
@@ -19,17 +19,17 @@ build_msi:
|
|
19
19
|
ref: 'refs/tags/3.8.3'
|
20
20
|
repo: 'git://github.com/puppetlabs/puppet_for_the_win.git'
|
21
21
|
facter:
|
22
|
-
ref: 'refs/tags/2.4.
|
22
|
+
ref: 'refs/tags/2.4.5'
|
23
23
|
repo: 'git://github.com/puppetlabs/facter.git'
|
24
24
|
hiera:
|
25
25
|
ref: 'refs/tags/1.3.4'
|
26
26
|
repo: 'git://github.com/puppetlabs/hiera.git'
|
27
27
|
sys:
|
28
28
|
ref:
|
29
|
-
x86: 'refs/tags/1.9.3-p551.
|
30
|
-
x64: 'refs/tags/2.0.0.
|
29
|
+
x86: 'refs/tags/1.9.3-p551.8'
|
30
|
+
x64: 'refs/tags/2.0.0.11-x64'
|
31
31
|
repo: 'git://github.com/puppetlabs/puppet-win32-ruby.git'
|
32
|
-
|
32
|
+
apt_signing_server: 'apt.puppetlabs.com'
|
33
33
|
apt_repo_url: 'http://apt.puppetlabs.com'
|
34
34
|
apt_repo_path: '/opt/repository/incoming'
|
35
35
|
ips_repo: '/var/pkgrepo'
|
data/lib/puppet/daemon.rb
CHANGED
@@ -24,6 +24,7 @@ class Puppet::Daemon
|
|
24
24
|
SIGNAL_CHECK_INTERVAL = 5
|
25
25
|
|
26
26
|
attr_accessor :agent, :server, :argv
|
27
|
+
attr_reader :signals
|
27
28
|
|
28
29
|
def initialize(pidfile, scheduler = Puppet::Scheduler::Scheduler.new())
|
29
30
|
@scheduler = scheduler
|
@@ -107,13 +108,21 @@ class Puppet::Daemon
|
|
107
108
|
# Trap a couple of the main signals. This should probably be handled
|
108
109
|
# in a way that anyone else can register callbacks for traps, but, eh.
|
109
110
|
def set_signal_traps
|
110
|
-
|
111
|
-
# extended signals not supported under windows
|
112
|
-
signals.update({:HUP => :restart, :USR1 => :reload, :USR2 => :reopen_logs }) unless Puppet.features.microsoft_windows?
|
113
|
-
signals.each do |signal, method|
|
111
|
+
[:INT, :TERM].each do |signal|
|
114
112
|
Signal.trap(signal) do
|
115
|
-
Puppet.notice "Caught #{signal};
|
116
|
-
|
113
|
+
Puppet.notice "Caught #{signal}; exiting"
|
114
|
+
stop
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# extended signals not supported under windows
|
119
|
+
if !Puppet.features.microsoft_windows?
|
120
|
+
signals = {:HUP => :restart, :USR1 => :reload, :USR2 => :reopen_logs }
|
121
|
+
signals.each do |signal, method|
|
122
|
+
Signal.trap(signal) do
|
123
|
+
Puppet.notice "Caught #{signal}; storing #{method}"
|
124
|
+
@signals << method
|
125
|
+
end
|
117
126
|
end
|
118
127
|
end
|
119
128
|
end
|
data/lib/puppet/node.rb
CHANGED
@@ -18,6 +18,8 @@ class Puppet::Node
|
|
18
18
|
|
19
19
|
::PSON.register_document_type('Node',self)
|
20
20
|
|
21
|
+
ENVIRONMENT = 'environment'.freeze
|
22
|
+
|
21
23
|
def self.from_data_hash(data)
|
22
24
|
raise ArgumentError, "No name provided in serialized data" unless name = data['name']
|
23
25
|
|
@@ -58,7 +60,7 @@ class Puppet::Node
|
|
58
60
|
if @environment
|
59
61
|
@environment
|
60
62
|
else
|
61
|
-
if env = parameters[
|
63
|
+
if env = parameters[ENVIRONMENT]
|
62
64
|
self.environment = env
|
63
65
|
elsif environment_name
|
64
66
|
self.environment = environment_name
|
@@ -80,6 +82,13 @@ class Puppet::Node
|
|
80
82
|
else
|
81
83
|
@environment = env
|
82
84
|
end
|
85
|
+
|
86
|
+
# Keep environment_name attribute and parameter in sync if they have been set
|
87
|
+
unless @environment.nil?
|
88
|
+
@parameters[ENVIRONMENT] = @environment.name if @parameters.include?(ENVIRONMENT)
|
89
|
+
self.environment_name = @environment.name if instance_variable_defined?(:@environment_name)
|
90
|
+
end
|
91
|
+
@environment
|
83
92
|
end
|
84
93
|
|
85
94
|
def has_environment_instance?
|
@@ -129,7 +138,7 @@ class Puppet::Node
|
|
129
138
|
@parameters[name] = value unless @parameters.include?(name)
|
130
139
|
end
|
131
140
|
|
132
|
-
@parameters[
|
141
|
+
@parameters[ENVIRONMENT] ||= self.environment.name.to_s
|
133
142
|
end
|
134
143
|
|
135
144
|
# Calculate the list of names we might use for looking
|
@@ -39,7 +39,7 @@ class Puppet::Pops::Evaluator::AccessOperator
|
|
39
39
|
fail(Puppet::Pops::Issues::BAD_STRING_SLICE_ARITY, @semantic.left_expr, {:actual => keys.size})
|
40
40
|
when 1
|
41
41
|
# Note that Ruby 1.8.7 requires a length of 1 to produce a String
|
42
|
-
k1 = coerce_numeric(keys[0], @semantic.keys, scope)
|
42
|
+
k1 = coerce_numeric(keys[0], @semantic.keys[0], scope)
|
43
43
|
bad_access_key_type(o, 0, k1, Integer) unless k1.is_a?(Integer)
|
44
44
|
k2 = 1
|
45
45
|
k1 = k1 < 0 ? o.length + k1 : k1 # abs pos
|
@@ -50,8 +50,8 @@ class Puppet::Pops::Evaluator::AccessOperator
|
|
50
50
|
o[ k1, k2 ]
|
51
51
|
end
|
52
52
|
when 2
|
53
|
-
k1 = coerce_numeric(keys[0], @semantic.keys, scope)
|
54
|
-
k2 = coerce_numeric(keys[1], @semantic.keys, scope)
|
53
|
+
k1 = coerce_numeric(keys[0], @semantic.keys[0], scope)
|
54
|
+
k2 = coerce_numeric(keys[1], @semantic.keys[1], scope)
|
55
55
|
[k1, k2].each_with_index { |k,i| bad_access_key_type(o, i, k, Integer) unless k.is_a?(Integer) }
|
56
56
|
|
57
57
|
k1 = k1 < 0 ? o.length + k1 : k1 # abs pos (negative is count from end)
|
@@ -317,6 +317,9 @@ class Puppet::Pops::Evaluator::AccessOperator
|
|
317
317
|
end
|
318
318
|
ranged_integer = Puppet::Pops::Types::PIntegerType.new()
|
319
319
|
from, to = keys
|
320
|
+
# NOTE! Do not merge the following line to 4.x. It has the same check in the initialize method
|
321
|
+
raise ArgumentError, "'from' must be less or equal to 'to'. Got (#{from}, #{to}" if from.is_a?(Numeric) && to.is_a?(Numeric) && from > to
|
322
|
+
|
320
323
|
ranged_integer.from = from == :default ? nil : from
|
321
324
|
ranged_integer.to = to == :default ? nil : to
|
322
325
|
ranged_integer
|
@@ -333,6 +336,9 @@ class Puppet::Pops::Evaluator::AccessOperator
|
|
333
336
|
end
|
334
337
|
ranged_float = Puppet::Pops::Types::PFloatType.new()
|
335
338
|
from, to = keys
|
339
|
+
# NOTE! Do not merge the following line to 4.x. It has the same check in the initialize method
|
340
|
+
raise ArgumentError, "'from' must be less or equal to 'to'. Got (#{from}, #{to}" if from.is_a?(Numeric) && to.is_a?(Numeric) && from > to
|
341
|
+
|
336
342
|
ranged_float.from = from == :default || from.nil? ? nil : Float(from)
|
337
343
|
ranged_float.to = to == :default || to.nil? ? nil : Float(to)
|
338
344
|
ranged_float
|
@@ -428,6 +434,9 @@ class Puppet::Pops::Evaluator::AccessOperator
|
|
428
434
|
end
|
429
435
|
ranged_integer = Puppet::Pops::Types::PIntegerType.new()
|
430
436
|
from, to = keys
|
437
|
+
# NOTE! Do not merge the following line to 4.x. It has the same check in the initialize method
|
438
|
+
raise ArgumentError, "'from' must be less or equal to 'to'. Got (#{from}, #{to}" if from.is_a?(Numeric) && to.is_a?(Numeric) && from > to
|
439
|
+
|
431
440
|
ranged_integer.from = from == :default ? nil : from
|
432
441
|
ranged_integer.to = to == :default ? nil : to
|
433
442
|
ranged_integer
|
data/lib/puppet/pops/issues.rb
CHANGED
@@ -546,6 +546,10 @@ module Puppet::Pops::Issues
|
|
546
546
|
"Resource Override can only operate on resources, got: #{label.label(actual)}"
|
547
547
|
end
|
548
548
|
|
549
|
+
DUPLICATE_PARAMETER = hard_issue :DUPLICATE_PARAMETER, :param_name do
|
550
|
+
"The parameter '#{param_name}' is declared more than once in the parameter list"
|
551
|
+
end
|
552
|
+
|
549
553
|
RESERVED_PARAMETER = hard_issue :RESERVED_PARAMETER, :container, :param_name do
|
550
554
|
"The parameter $#{param_name} redefines a built in parameter in #{label.the(container)}"
|
551
555
|
end
|
@@ -17,6 +17,9 @@ module Puppet::Pops::Types::TypeFactory
|
|
17
17
|
# @api public
|
18
18
|
#
|
19
19
|
def self.range(from, to)
|
20
|
+
# NOTE! Do not merge the following line to 4.x. It has the same check in the initialize method
|
21
|
+
raise ArgumentError, "'from' must be less or equal to 'to'. Got (#{from}, #{to}" if from.is_a?(Numeric) && to.is_a?(Numeric) && from > to
|
22
|
+
|
20
23
|
t = Types::PIntegerType.new()
|
21
24
|
# optimize eq with symbol (faster when it is left)
|
22
25
|
t.from = from unless (:default == from || from == 'default')
|
@@ -28,6 +31,9 @@ module Puppet::Pops::Types::TypeFactory
|
|
28
31
|
# @api public
|
29
32
|
#
|
30
33
|
def self.float_range(from, to)
|
34
|
+
# NOTE! Do not merge the following line to 4.x. It has the same check in the initialize method
|
35
|
+
raise ArgumentError, "'from' must be less or equal to 'to'. Got (#{from}, #{to}" if from.is_a?(Numeric) && to.is_a?(Numeric) && from > to
|
36
|
+
|
31
37
|
t = Types::PFloatType.new()
|
32
38
|
# optimize eq with symbol (faster when it is left)
|
33
39
|
t.from = Float(from) unless :default == from || from.nil?
|
@@ -121,11 +121,7 @@ module Puppet::Pops
|
|
121
121
|
def range
|
122
122
|
f = from || NEGATIVE_INFINITY
|
123
123
|
t = to || INFINITY
|
124
|
-
|
125
|
-
[f, t]
|
126
|
-
else
|
127
|
-
[t,f]
|
128
|
-
end
|
124
|
+
[f, t]
|
129
125
|
end
|
130
126
|
|
131
127
|
# Returns Enumerator if no block is given
|
@@ -133,11 +129,7 @@ module Puppet::Pops
|
|
133
129
|
def each
|
134
130
|
return self.to_enum unless block_given?
|
135
131
|
return nil if from.nil? || to.nil?
|
136
|
-
|
137
|
-
from.downto(to) {|x| yield x }
|
138
|
-
else
|
139
|
-
from.upto(to) {|x| yield x }
|
140
|
-
end
|
132
|
+
from.upto(to) {|x| yield x }
|
141
133
|
end
|
142
134
|
|
143
135
|
def hash
|
@@ -212,11 +204,7 @@ module Puppet::Pops
|
|
212
204
|
return [0, INFINITY] if size_type.nil?
|
213
205
|
f = size_type.from || 0
|
214
206
|
t = size_type.to || INFINITY
|
215
|
-
|
216
|
-
[f, t]
|
217
|
-
else
|
218
|
-
[t,f]
|
219
|
-
end
|
207
|
+
[f, t]
|
220
208
|
end
|
221
209
|
|
222
210
|
def hash
|
@@ -233,6 +233,7 @@ class Puppet::Pops::Validation::Checker4_0
|
|
233
233
|
def check_EppExpression(o)
|
234
234
|
if o.eContainer.is_a?(Puppet::Pops::Model::LambdaExpression)
|
235
235
|
internal_check_no_capture(o.eContainer, o)
|
236
|
+
internal_check_parameter_name_uniqueness(o.eContainer)
|
236
237
|
end
|
237
238
|
end
|
238
239
|
|
@@ -327,12 +328,14 @@ class Puppet::Pops::Validation::Checker4_0
|
|
327
328
|
def check_HostClassDefinition(o)
|
328
329
|
check_NamedDefinition(o)
|
329
330
|
internal_check_no_capture(o)
|
331
|
+
internal_check_parameter_name_uniqueness(o)
|
330
332
|
internal_check_reserved_params(o)
|
331
333
|
end
|
332
334
|
|
333
335
|
def check_ResourceTypeDefinition(o)
|
334
336
|
check_NamedDefinition(o)
|
335
337
|
internal_check_no_capture(o)
|
338
|
+
internal_check_parameter_name_uniqueness(o)
|
336
339
|
internal_check_reserved_params(o)
|
337
340
|
end
|
338
341
|
|
@@ -366,6 +369,13 @@ class Puppet::Pops::Validation::Checker4_0
|
|
366
369
|
end
|
367
370
|
end
|
368
371
|
|
372
|
+
def internal_check_parameter_name_uniqueness(o)
|
373
|
+
unique = Set.new
|
374
|
+
o.parameters.each do |p|
|
375
|
+
acceptor.accept(Issues::DUPLICATE_PARAMETER, p, {:param_name => p.name}) unless unique.add?(p.name)
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
369
379
|
def check_IfExpression(o)
|
370
380
|
rvalue(o.test)
|
371
381
|
end
|
@@ -39,6 +39,11 @@ Puppet::Type.type(:group).provide :windows_adsi do
|
|
39
39
|
return '' if users.nil? or !users.kind_of?(Array)
|
40
40
|
users = users.map do |user_name|
|
41
41
|
sid = Puppet::Util::Windows::SID.name_to_sid_object(user_name)
|
42
|
+
if !sid
|
43
|
+
resource.debug("#{user_name} (unresolvable to SID)")
|
44
|
+
next user_name
|
45
|
+
end
|
46
|
+
|
42
47
|
if sid.account =~ /\\/
|
43
48
|
account, _ = Puppet::Util::Windows::ADSI::User.parse_name(sid.account)
|
44
49
|
else
|
@@ -50,6 +55,10 @@ Puppet::Type.type(:group).provide :windows_adsi do
|
|
50
55
|
return users.join(',')
|
51
56
|
end
|
52
57
|
|
58
|
+
def member_valid?(user_name)
|
59
|
+
! Puppet::Util::Windows::SID.name_to_sid_object(user_name).nil?
|
60
|
+
end
|
61
|
+
|
53
62
|
def group
|
54
63
|
@group ||= Puppet::Util::Windows::ADSI::Group.new(@resource[:name])
|
55
64
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
require 'puppet/provider/package'
|
5
5
|
require 'xmlrpc/client'
|
6
|
+
require 'puppet/util/http_proxy'
|
6
7
|
|
7
8
|
Puppet::Type.type(:package).provide :pip,
|
8
9
|
:parent => ::Puppet::Provider::Package do
|
@@ -56,7 +57,16 @@ Puppet::Type.type(:package).provide :pip,
|
|
56
57
|
# cache of PyPI's package list so this operation will always have to
|
57
58
|
# ask the web service.
|
58
59
|
def latest
|
59
|
-
|
60
|
+
http_proxy_host = Puppet::Util::HttpProxy.http_proxy_host
|
61
|
+
http_proxy_port = Puppet::Util::HttpProxy.http_proxy_port
|
62
|
+
if http_proxy_host && http_proxy_port
|
63
|
+
proxy = "#{http_proxy_host}:#{http_proxy_port}"
|
64
|
+
else
|
65
|
+
# nil is acceptable
|
66
|
+
proxy = http_proxy_host
|
67
|
+
end
|
68
|
+
|
69
|
+
client = XMLRPC::Client.new2("http://pypi.python.org/pypi", proxy)
|
60
70
|
client.http_header_extra = {"Content-Type" => "text/xml"}
|
61
71
|
client.timeout = 10
|
62
72
|
result = client.call("package_releases", @resource[:name])
|
@@ -204,6 +204,12 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
|
|
204
204
|
# Read a plist, whether its format is XML or in Apple's "binary1"
|
205
205
|
# format.
|
206
206
|
def self.read_plist(path)
|
207
|
+
begin
|
208
|
+
return Plist::parse_xml(path)
|
209
|
+
rescue ArgumentError => detail
|
210
|
+
Puppet.debug("Error reading #{path}: #{detail}. Retrying with plutil.")
|
211
|
+
end
|
212
|
+
|
207
213
|
begin
|
208
214
|
Plist::parse_xml(plutil('-convert', 'xml1', '-o', '/dev/stdout', path))
|
209
215
|
rescue Puppet::ExecutionFailure => detail
|
@@ -151,7 +151,11 @@ Puppet::Type.type(:service).provide :upstart, :parent => :debian do
|
|
151
151
|
end
|
152
152
|
|
153
153
|
def status
|
154
|
-
|
154
|
+
if (@resource[:hasstatus] == :false) ||
|
155
|
+
@resource[:status] ||
|
156
|
+
! is_upstart?
|
157
|
+
return super
|
158
|
+
end
|
155
159
|
|
156
160
|
output = status_exec(@resource[:name].split)
|
157
161
|
if output =~ /start\//
|
data/lib/puppet/resource.rb
CHANGED
@@ -387,7 +387,7 @@ class Puppet::Resource
|
|
387
387
|
begin
|
388
388
|
Puppet::DataBinding.indirection.find(
|
389
389
|
name,
|
390
|
-
:environment => scope.environment
|
390
|
+
:environment => scope.environment,
|
391
391
|
:variables => scope)
|
392
392
|
rescue Puppet::DataBinding::LookupError => e
|
393
393
|
raise Puppet::Error.new("Error from DataBinding '#{Puppet[:data_binding_terminus]}' while looking up '#{name}': #{e.message}", e)
|
data/lib/puppet/type/group.rb
CHANGED
@@ -80,7 +80,9 @@ module Puppet
|
|
80
80
|
|
81
81
|
newproperty(:members, :array_matching => :all, :required_features => :manages_members) do
|
82
82
|
desc "The members of the group. For directory services where group
|
83
|
-
membership is stored in the group objects, not the users.
|
83
|
+
membership is stored in the group objects, not the users. Use
|
84
|
+
with auth_membership to determine whether the specified members
|
85
|
+
are inclusive or the minimum."
|
84
86
|
|
85
87
|
def change_to_s(currentvalue, newvalue)
|
86
88
|
currentvalue = currentvalue.join(",") if currentvalue != :absent
|
@@ -99,16 +101,26 @@ module Puppet
|
|
99
101
|
def is_to_s(currentvalue)
|
100
102
|
if provider.respond_to?(:members_to_s)
|
101
103
|
currentvalue = '' if currentvalue.nil?
|
102
|
-
|
104
|
+
currentvalue = currentvalue.is_a?(Array) ? currentvalue : currentvalue.split(',')
|
105
|
+
|
106
|
+
return provider.members_to_s(currentvalue)
|
103
107
|
end
|
104
108
|
|
105
109
|
super(currentvalue)
|
106
110
|
end
|
107
111
|
alias :should_to_s :is_to_s
|
112
|
+
|
113
|
+
validate do |value|
|
114
|
+
if provider.respond_to?(:member_valid?)
|
115
|
+
return provider.member_valid?(value)
|
116
|
+
end
|
117
|
+
end
|
108
118
|
end
|
109
119
|
|
110
120
|
newparam(:auth_membership, :boolean => true, :parent => Puppet::Parameter::Boolean) do
|
111
|
-
desc "
|
121
|
+
desc "Whether the provider is authoritative for group membership. This
|
122
|
+
must be set to true to allow setting the group to no members with
|
123
|
+
`members => [],`."
|
112
124
|
defaultto true
|
113
125
|
end
|
114
126
|
|
@@ -372,7 +372,10 @@ module Puppet::Util::Windows::Security
|
|
372
372
|
dacl.allow(well_known_nobody_sid, nobody_allow)
|
373
373
|
|
374
374
|
# TODO: system should be first?
|
375
|
-
|
375
|
+
flags = !isdir ? 0 :
|
376
|
+
Puppet::Util::Windows::AccessControlEntry::CONTAINER_INHERIT_ACE |
|
377
|
+
Puppet::Util::Windows::AccessControlEntry::OBJECT_INHERIT_ACE
|
378
|
+
dacl.allow(well_known_system_sid, system_allow, flags)
|
376
379
|
|
377
380
|
# add inherit-only aces for child dirs and files that are created within the dir
|
378
381
|
inherit_only = Puppet::Util::Windows::AccessControlEntry::INHERIT_ONLY_ACE
|
data/lib/puppet/version.rb
CHANGED
@@ -237,6 +237,24 @@ describe "Puppet::Util::Windows::Security", :if => Puppet.features.microsoft_win
|
|
237
237
|
system_aces.each do |ace|
|
238
238
|
ace.mask.should == klass::FILE_ALL_ACCESS && ! ace.inherited?
|
239
239
|
end
|
240
|
+
|
241
|
+
if Puppet::FileSystem.directory?(path)
|
242
|
+
system_aces.each do |ace|
|
243
|
+
ace.object_inherit?.should be_true
|
244
|
+
ace.container_inherit?.should be_true
|
245
|
+
end
|
246
|
+
|
247
|
+
# it's critically important that this file be default created
|
248
|
+
# and that this file not have it's owner / group / mode set by winsec
|
249
|
+
nested_file = File.join(path, 'nested_file')
|
250
|
+
File.new(nested_file, 'w').close
|
251
|
+
|
252
|
+
system_aces = winsec.get_aces_for_path_by_sid(nested_file, sids[:system])
|
253
|
+
# even when SYSTEM is the owner (in CI), there should be an inherited SYSTEM
|
254
|
+
system_aces.any? do |ace|
|
255
|
+
ace.mask == klass::FILE_ALL_ACCESS && ace.inherited?
|
256
|
+
end.should be_true
|
257
|
+
end
|
240
258
|
end
|
241
259
|
|
242
260
|
describe "for modes that require deny aces" do
|
data/spec/unit/daemon_spec.rb
CHANGED
@@ -47,15 +47,24 @@ describe Puppet::Daemon, :unless => Puppet.features.microsoft_windows? do
|
|
47
47
|
let(:server) { stub("Server", :start => nil, :wait_for_shutdown => nil) }
|
48
48
|
|
49
49
|
describe "when setting signal traps" do
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
50
|
+
[:INT, :TERM].each do |signal|
|
51
|
+
it "logs a notice and exits when sent #{signal}" do
|
52
|
+
Signal.stubs(:trap).with(signal).yields
|
53
|
+
Puppet.expects(:notice).with("Caught #{signal}; exiting")
|
54
|
+
daemon.expects(:stop)
|
55
55
|
|
56
|
-
|
56
|
+
daemon.set_signal_traps
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
{:HUP => :restart, :USR1 => :reload, :USR2 => :reopen_logs}.each do |signal, method|
|
61
|
+
it "logs a notice and remembers to call #{method} when it receives #{signal}" do
|
62
|
+
Signal.stubs(:trap).with(signal).yields
|
63
|
+
Puppet.expects(:notice).with("Caught #{signal}; storing #{method}")
|
57
64
|
|
58
65
|
daemon.set_signal_traps
|
66
|
+
|
67
|
+
expect(daemon.signals).to eq([method])
|
59
68
|
end
|
60
69
|
end
|
61
70
|
end
|
data/spec/unit/node_spec.rb
CHANGED
@@ -48,6 +48,14 @@ describe Puppet::Node do
|
|
48
48
|
node.parameters["environment"] = :bar
|
49
49
|
node.environment.name.should == :bar
|
50
50
|
end
|
51
|
+
|
52
|
+
it "should allow its environment parameter to be set by attribute after initialization" do
|
53
|
+
node = Puppet::Node.new("foo", { :parameters => { 'environment' => :foo } })
|
54
|
+
node.environment_name = :foo
|
55
|
+
node.environment = :bar
|
56
|
+
expect(node.environment_name).to eq(:bar)
|
57
|
+
expect(node.parameters['environment']).to eq(:bar)
|
58
|
+
end
|
51
59
|
end
|
52
60
|
|
53
61
|
it "can survive a round-trip through YAML" do
|
@@ -123,9 +123,9 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl/AccessOperator' do
|
|
123
123
|
expect(evaluate(expr)).to eql(range(1,1))
|
124
124
|
end
|
125
125
|
|
126
|
-
it '
|
126
|
+
it 'gives an error for Integer[from, <from]' do
|
127
127
|
expr = fqr('Integer')[1,0]
|
128
|
-
expect
|
128
|
+
expect{evaluate(expr)}.to raise_error(/'from' must be less or equal to 'to'/)
|
129
129
|
end
|
130
130
|
|
131
131
|
it 'produces an error for Integer[] if there are more than 2 keys' do
|
@@ -154,9 +154,9 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl/AccessOperator' do
|
|
154
154
|
expect(evaluate(expr)).to eql(float_range(1.0,1.0))
|
155
155
|
end
|
156
156
|
|
157
|
-
it '
|
157
|
+
it 'gives an error for Float[from, <from]' do
|
158
158
|
expr = fqr('Float')[1.0,0.0]
|
159
|
-
expect
|
159
|
+
expect{evaluate(expr)}.to raise_error(/'from' must be less or equal to 'to'/)
|
160
160
|
end
|
161
161
|
|
162
162
|
it 'produces an error for Float[] if there are more than 2 keys' do
|
@@ -177,6 +177,18 @@ describe "validating 4x" do
|
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
180
|
+
context 'for parameter names' do
|
181
|
+
['class', 'define'].each do |word|
|
182
|
+
it "should require that #{word} parameter names are unique" do
|
183
|
+
expect(validate(parse("#{word} foo($a = 10, $a = 20) {}"))).to have_issue(Puppet::Pops::Issues::DUPLICATE_PARAMETER)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should require that template parameter names are unique" do
|
188
|
+
expect(validate(parse_epp("<%-| $a, $a |-%><%= $a == doh %>"))).to have_issue(Puppet::Pops::Issues::DUPLICATE_PARAMETER)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
180
192
|
context 'for reserved parameter names' do
|
181
193
|
['name', 'title'].each do |word|
|
182
194
|
it "produces an error when $#{word} is used as a parameter in a class" do
|
@@ -35,11 +35,13 @@ describe Puppet::Type.type(:group).provider(:windows_adsi), :if => Puppet.featur
|
|
35
35
|
let(:user1) { stub(:account => 'user1', :domain => '.', :to_s => 'user1sid') }
|
36
36
|
let(:user2) { stub(:account => 'user2', :domain => '.', :to_s => 'user2sid') }
|
37
37
|
let(:user3) { stub(:account => 'user3', :domain => '.', :to_s => 'user3sid') }
|
38
|
+
let(:invalid_user) { SecureRandom.uuid }
|
38
39
|
|
39
40
|
before :each do
|
40
41
|
Puppet::Util::Windows::SID.stubs(:name_to_sid_object).with('user1').returns(user1)
|
41
42
|
Puppet::Util::Windows::SID.stubs(:name_to_sid_object).with('user2').returns(user2)
|
42
43
|
Puppet::Util::Windows::SID.stubs(:name_to_sid_object).with('user3').returns(user3)
|
44
|
+
Puppet::Util::Windows::SID.stubs(:name_to_sid_object).with(invalid_user).returns(nil)
|
43
45
|
end
|
44
46
|
|
45
47
|
describe "#members_insync?" do
|
@@ -123,6 +125,9 @@ describe Puppet::Type.type(:group).provider(:windows_adsi), :if => Puppet.featur
|
|
123
125
|
it "should return a user string like DOMAIN\\USER,DOMAIN2\\USER2" do
|
124
126
|
provider.members_to_s(['user1', 'user2']).should == '.\user1,.\user2'
|
125
127
|
end
|
128
|
+
it "should return the username when it cannot be resolved to a SID (for the sake of resource_harness error messages)" do
|
129
|
+
expect(provider.members_to_s([invalid_user])).to eq("#{invalid_user}")
|
130
|
+
end
|
126
131
|
end
|
127
132
|
end
|
128
133
|
|
@@ -12,7 +12,6 @@ describe provider_class do
|
|
12
12
|
@client = stub_everything('client')
|
13
13
|
@client.stubs(:call).with('package_releases', 'real_package').returns(["1.3", "1.2.5", "1.2.4"])
|
14
14
|
@client.stubs(:call).with('package_releases', 'fake_package').returns([])
|
15
|
-
XMLRPC::Client.stubs(:new2).returns(@client)
|
16
15
|
end
|
17
16
|
|
18
17
|
describe "parse" do
|
@@ -118,23 +117,53 @@ describe provider_class do
|
|
118
117
|
end
|
119
118
|
|
120
119
|
describe "latest" do
|
120
|
+
context "connecting directly" do
|
121
121
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
end
|
122
|
+
before :each do
|
123
|
+
XMLRPC::Client.expects(:new2).with("http://pypi.python.org/pypi", nil).returns(@client)
|
124
|
+
end
|
126
125
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
126
|
+
it "should find a version number for real_package" do
|
127
|
+
@resource[:name] = "real_package"
|
128
|
+
@provider.latest.should_not == nil
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should not find a version number for fake_package" do
|
132
|
+
@resource[:name] = "fake_package"
|
133
|
+
@provider.latest.should == nil
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should handle a timeout gracefully" do
|
137
|
+
@resource[:name] = "fake_package"
|
138
|
+
@client.stubs(:call).raises(Timeout::Error)
|
139
|
+
lambda { @provider.latest }.should raise_error(Puppet::Error)
|
140
|
+
end
|
131
141
|
|
132
|
-
it "should handle a timeout gracefully" do
|
133
|
-
@resource[:name] = "fake_package"
|
134
|
-
@client.stubs(:call).raises(Timeout::Error)
|
135
|
-
lambda { @provider.latest }.should raise_error(Puppet::Error)
|
136
142
|
end
|
137
143
|
|
144
|
+
context "connecting via a proxy" do
|
145
|
+
before :each do
|
146
|
+
Puppet::Util::HttpProxy.expects(:http_proxy_host).returns 'some_host'
|
147
|
+
Puppet::Util::HttpProxy.expects(:http_proxy_port).returns 'some_port'
|
148
|
+
XMLRPC::Client.expects(:new2).with("http://pypi.python.org/pypi", "some_host:some_port").returns(@client)
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should find a version number for real_package" do
|
152
|
+
@resource[:name] = "real_package"
|
153
|
+
@provider.latest.should_not == nil
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should not find a version number for fake_package" do
|
157
|
+
@resource[:name] = "fake_package"
|
158
|
+
@provider.latest.should == nil
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should handle a timeout gracefully" do
|
162
|
+
@resource[:name] = "fake_package"
|
163
|
+
@client.stubs(:call).raises(Timeout::Error)
|
164
|
+
lambda { @provider.latest }.should raise_error(Puppet::Error)
|
165
|
+
end
|
166
|
+
end
|
138
167
|
end
|
139
168
|
|
140
169
|
describe "install" do
|
@@ -274,6 +274,7 @@ describe Puppet::Type.type(:service).provider(:launchd) do
|
|
274
274
|
}
|
275
275
|
end
|
276
276
|
let(:busted_plist_path) { '/Library/LaunchAgents/org.busted.plist' }
|
277
|
+
let(:binary_plist_path) { '/Library/LaunchAgents/org.binary.plist' }
|
277
278
|
|
278
279
|
it "[17624] should warn that the plist in question is being skipped" do
|
279
280
|
provider.expects(:launchd_paths).returns(['/Library/LaunchAgents'])
|
@@ -284,6 +285,8 @@ describe Puppet::Type.type(:service).provider(:launchd) do
|
|
284
285
|
end
|
285
286
|
|
286
287
|
it "[15929] should skip plists that plutil cannot read" do
|
288
|
+
Plist.expects(:parse_xml).with(busted_plist_path).raises(ArgumentError, 'boom')
|
289
|
+
Puppet.expects(:debug).with("Error reading #{busted_plist_path}: boom. Retrying with plutil.")
|
287
290
|
provider.expects(:plutil).with('-convert', 'xml1', '-o', '/dev/stdout',
|
288
291
|
busted_plist_path).raises(Puppet::ExecutionFailure, 'boom')
|
289
292
|
Puppet.expects(:warning).with("Cannot read file #{busted_plist_path}; " +
|
@@ -291,6 +294,14 @@ describe Puppet::Type.type(:service).provider(:launchd) do
|
|
291
294
|
"Details: boom")
|
292
295
|
provider.read_plist(busted_plist_path)
|
293
296
|
end
|
297
|
+
|
298
|
+
it "should read binary plists with plutil" do
|
299
|
+
Plist.expects(:parse_xml).with(binary_plist_path).raises(ArgumentError, 'boom')
|
300
|
+
Puppet.expects(:debug).with("Error reading #{binary_plist_path}: boom. Retrying with plutil.")
|
301
|
+
provider.expects(:plutil).with('-convert', 'xml1', '-o', '/dev/stdout', binary_plist_path).returns('plist')
|
302
|
+
Plist.expects(:parse_xml).with('plist').returns('plist_map')
|
303
|
+
expect(provider.read_plist(binary_plist_path)).to eq('plist_map')
|
304
|
+
end
|
294
305
|
end
|
295
306
|
it "should return the cached value when available" do
|
296
307
|
provider.instance_variable_set(:@label_to_path_map, {'xx'=>'yy'})
|
@@ -100,6 +100,63 @@ describe Puppet::Type.type(:service).provider(:upstart) do
|
|
100
100
|
provider.status.should == :running
|
101
101
|
end
|
102
102
|
|
103
|
+
describe "when a special status command is specifed" do
|
104
|
+
it "should use the provided status command" do
|
105
|
+
resource = Puppet::Type.type(:service).new(:name => 'foo', :provider => :upstart, :status => '/bin/foo')
|
106
|
+
provider = provider_class.new(resource)
|
107
|
+
provider.stubs(:is_upstart?).returns(true)
|
108
|
+
|
109
|
+
provider.expects(:status_exec).with(['foo']).never
|
110
|
+
provider.expects(:execute).with(['/bin/foo'], :failonfail => false, :override_locale => false, :squelch => false, :combine => true)
|
111
|
+
Process::Status.any_instance.stubs(:exitstatus).returns(0)
|
112
|
+
provider.status
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should return :stopped when the provided status command return non-zero" do
|
116
|
+
resource = Puppet::Type.type(:service).new(:name => 'foo', :provider => :upstart, :status => '/bin/foo')
|
117
|
+
provider = provider_class.new(resource)
|
118
|
+
provider.stubs(:is_upstart?).returns(true)
|
119
|
+
|
120
|
+
provider.expects(:status_exec).with(['foo']).never
|
121
|
+
provider.expects(:execute).with(['/bin/foo'], :failonfail => false, :override_locale => false, :squelch => false, :combine => true)
|
122
|
+
$CHILD_STATUS.stubs(:exitstatus).returns 1
|
123
|
+
provider.status.should == :stopped
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should return :running when the provided status command return zero" do
|
127
|
+
resource = Puppet::Type.type(:service).new(:name => 'foo', :provider => :upstart, :status => '/bin/foo')
|
128
|
+
provider = provider_class.new(resource)
|
129
|
+
provider.stubs(:is_upstart?).returns(true)
|
130
|
+
|
131
|
+
provider.expects(:status_exec).with(['foo']).never
|
132
|
+
provider.expects(:execute).with(['/bin/foo'], :failonfail => false, :override_locale => false, :squelch => false, :combine => true)
|
133
|
+
$CHILD_STATUS.stubs(:exitstatus).returns 0
|
134
|
+
provider.status.should == :running
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "when :hasstatus is set to false" do
|
139
|
+
it "should return :stopped if the pid can not be found" do
|
140
|
+
resource = Puppet::Type.type(:service).new(:name => 'foo', :hasstatus => false, :provider => :upstart)
|
141
|
+
provider = provider_class.new(resource)
|
142
|
+
provider.stubs(:is_upstart?).returns(true)
|
143
|
+
|
144
|
+
provider.expects(:status_exec).with(['foo']).never
|
145
|
+
provider.expects(:getpid).returns nil
|
146
|
+
provider.status.should == :stopped
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should return :running if the pid can be found" do
|
150
|
+
resource = Puppet::Type.type(:service).new(:name => 'foo', :hasstatus => false, :provider => :upstart)
|
151
|
+
provider = provider_class.new(resource)
|
152
|
+
provider.stubs(:is_upstart?).returns(true)
|
153
|
+
|
154
|
+
provider.expects(:status_exec).with(['foo']).never
|
155
|
+
provider.expects(:getpid).returns 2706
|
156
|
+
provider.status.should == :running
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
103
160
|
it "should properly handle services with 'start' in their name" do
|
104
161
|
resource = Puppet::Type.type(:service).new(:name => "foostartbar", :provider => :upstart)
|
105
162
|
provider = provider_class.new(resource)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.8.
|
4
|
+
version: 3.8.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2016-01-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: facter
|