puppet 5.5.18 → 5.5.19
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +12 -11
- data/lib/puppet.rb +5 -2
- data/lib/puppet/application/filebucket.rb +13 -0
- data/lib/puppet/defaults.rb +60 -33
- data/lib/puppet/indirector/catalog/compiler.rb +8 -0
- data/lib/puppet/network/http/connection.rb +4 -0
- data/lib/puppet/network/http/pool.rb +5 -1
- data/lib/puppet/pops/evaluator/access_operator.rb +2 -2
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +1 -1
- data/lib/puppet/pops/types/type_calculator.rb +24 -0
- data/lib/puppet/provider/group/groupadd.rb +19 -19
- data/lib/puppet/provider/mailalias/aliases.rb +1 -1
- data/lib/puppet/provider/package/apt.rb +14 -3
- data/lib/puppet/provider/package/dnfmodule.rb +9 -2
- data/lib/puppet/provider/package/dpkg.rb +13 -6
- data/lib/puppet/provider/package/fink.rb +20 -3
- data/lib/puppet/provider/package/openbsd.rb +13 -1
- data/lib/puppet/provider/package/pkg.rb +18 -5
- data/lib/puppet/provider/package/yum.rb +9 -5
- data/lib/puppet/provider/user/directoryservice.rb +30 -5
- data/lib/puppet/provider/user/useradd.rb +5 -6
- data/lib/puppet/ssl/certificate.rb +2 -1
- data/lib/puppet/ssl/certificate_authority.rb +6 -5
- data/lib/puppet/test/test_helper.rb +7 -0
- data/lib/puppet/transaction/resource_harness.rb +1 -1
- data/lib/puppet/type/file.rb +13 -0
- data/lib/puppet/type/package.rb +63 -9
- data/lib/puppet/util/plist.rb +6 -0
- data/lib/puppet/version.rb +1 -1
- data/locales/puppet.pot +100 -92
- data/man/man5/puppet.conf.5 +12 -6
- data/man/man8/puppet-agent.8 +1 -1
- data/man/man8/puppet-apply.8 +1 -1
- data/man/man8/puppet-ca.8 +1 -1
- data/man/man8/puppet-catalog.8 +1 -1
- data/man/man8/puppet-cert.8 +1 -1
- data/man/man8/puppet-certificate.8 +1 -1
- data/man/man8/puppet-certificate_request.8 +1 -1
- data/man/man8/puppet-certificate_revocation_list.8 +1 -1
- data/man/man8/puppet-config.8 +1 -1
- data/man/man8/puppet-describe.8 +1 -1
- data/man/man8/puppet-device.8 +1 -1
- data/man/man8/puppet-doc.8 +1 -1
- data/man/man8/puppet-epp.8 +1 -1
- data/man/man8/puppet-facts.8 +1 -1
- data/man/man8/puppet-filebucket.8 +16 -1
- data/man/man8/puppet-generate.8 +1 -1
- data/man/man8/puppet-help.8 +1 -1
- data/man/man8/puppet-key.8 +1 -1
- data/man/man8/puppet-lookup.8 +1 -1
- data/man/man8/puppet-man.8 +1 -1
- data/man/man8/puppet-master.8 +1 -1
- data/man/man8/puppet-module.8 +1 -1
- data/man/man8/puppet-node.8 +1 -1
- data/man/man8/puppet-parser.8 +1 -1
- data/man/man8/puppet-plugin.8 +1 -1
- data/man/man8/puppet-report.8 +1 -1
- data/man/man8/puppet-resource.8 +1 -1
- data/man/man8/puppet-script.8 +1 -1
- data/man/man8/puppet-status.8 +1 -1
- data/man/man8/puppet.8 +2 -2
- data/spec/fixtures/integration/provider/mailalias/aliases/test1 +1 -0
- data/spec/integration/indirector/facts/facter_spec.rb +4 -0
- data/spec/unit/application/apply_spec.rb +2 -12
- data/spec/unit/configurer/fact_handler_spec.rb +0 -4
- data/spec/unit/configurer_spec.rb +0 -3
- data/spec/unit/indirector/catalog/compiler_spec.rb +45 -26
- data/spec/unit/network/http/connection_spec.rb +17 -1
- data/spec/unit/network/http/pool_spec.rb +32 -0
- data/spec/unit/node_spec.rb +7 -4
- data/spec/unit/provider/group/groupadd_spec.rb +30 -1
- data/spec/unit/provider/package/apt_spec.rb +13 -2
- data/spec/unit/provider/package/aptitude_spec.rb +1 -0
- data/spec/unit/provider/package/dnfmodule_spec.rb +22 -0
- data/spec/unit/provider/package/dpkg_spec.rb +20 -4
- data/spec/unit/provider/package/openbsd_spec.rb +17 -0
- data/spec/unit/provider/package/pkg_spec.rb +13 -1
- data/spec/unit/provider/package/yum_spec.rb +50 -0
- data/spec/unit/provider/user/directoryservice_spec.rb +41 -0
- data/spec/unit/provider/user/useradd_spec.rb +7 -2
- data/spec/unit/puppet_pal_2pec.rb +3 -0
- data/spec/unit/ssl/certificate_authority_spec.rb +2 -3
- data/spec/unit/ssl/certificate_spec.rb +7 -0
- data/spec/unit/type/package_spec.rb +8 -0
- data/spec/unit/util/plist_spec.rb +20 -0
- metadata +2 -2
@@ -33,7 +33,7 @@ class Puppet::Network::HTTP::Pool
|
|
33
33
|
reuse = false
|
34
34
|
raise detail
|
35
35
|
ensure
|
36
|
-
if reuse
|
36
|
+
if reuse && http.started?
|
37
37
|
release(site, http)
|
38
38
|
else
|
39
39
|
close_connection(site, http)
|
@@ -56,13 +56,17 @@ class Puppet::Network::HTTP::Pool
|
|
56
56
|
end
|
57
57
|
|
58
58
|
# Safely close a persistent connection.
|
59
|
+
# Don't try to close a connection that's already closed.
|
59
60
|
#
|
60
61
|
# @api private
|
61
62
|
def close_connection(site, http)
|
63
|
+
return false unless http.started?
|
62
64
|
Puppet.debug("Closing connection for #{site}")
|
63
65
|
http.finish
|
66
|
+
true
|
64
67
|
rescue => detail
|
65
68
|
Puppet.log_exception(detail, _("Failed to close connection for %{site}: %{detail}") % { site: site, detail: detail })
|
69
|
+
nil
|
66
70
|
end
|
67
71
|
|
68
72
|
# Borrow and take ownership of a persistent connection. If a new
|
@@ -20,14 +20,14 @@ class AccessOperator
|
|
20
20
|
@semantic = access_expression
|
21
21
|
end
|
22
22
|
|
23
|
-
def access
|
23
|
+
def access(o, scope, *keys)
|
24
24
|
@@access_visitor.visit_this_2(self, o, scope, keys)
|
25
25
|
end
|
26
26
|
|
27
27
|
protected
|
28
28
|
|
29
29
|
def access_Object(o, scope, keys)
|
30
|
-
type = Puppet::Pops::Types::TypeCalculator.
|
30
|
+
type = Puppet::Pops::Types::TypeCalculator.infer_callable_methods_t(o)
|
31
31
|
if type.is_a?(Puppet::Pops::Types::TypeWithMembers)
|
32
32
|
access_func = type['[]']
|
33
33
|
return access_func.invoke(o, scope, keys) unless access_func.nil?
|
@@ -947,7 +947,7 @@ class EvaluatorImpl
|
|
947
947
|
name = name.value # the string function name
|
948
948
|
|
949
949
|
obj = receiver[0]
|
950
|
-
receiver_type = Types::TypeCalculator.
|
950
|
+
receiver_type = Types::TypeCalculator.infer_callable_methods_t(obj)
|
951
951
|
if receiver_type.is_a?(Types::TypeWithMembers)
|
952
952
|
member = receiver_type[name]
|
953
953
|
unless member.nil?
|
@@ -120,6 +120,30 @@ class TypeCalculator
|
|
120
120
|
singleton.infer(o)
|
121
121
|
end
|
122
122
|
|
123
|
+
# Infers a type if given object may have callable members, else returns nil.
|
124
|
+
# Caller must check for nil or if returned type supports members.
|
125
|
+
# This is a much cheaper call than doing a call to the general infer(o) method.
|
126
|
+
#
|
127
|
+
# @api private
|
128
|
+
def self.infer_callable_methods_t(o)
|
129
|
+
# If being a value that cannot have Pcore based methods callable from Puppet Language
|
130
|
+
if (o.is_a?(String) ||
|
131
|
+
o.is_a?(Numeric) ||
|
132
|
+
o.is_a?(TrueClass) ||
|
133
|
+
o.is_a?(FalseClass) ||
|
134
|
+
o.is_a?(Regexp) ||
|
135
|
+
o.instance_of?(Array) ||
|
136
|
+
o.instance_of?(Hash) ||
|
137
|
+
Types::PUndefType::DEFAULT.instance?(o)
|
138
|
+
)
|
139
|
+
return nil
|
140
|
+
end
|
141
|
+
# For other objects (e.g. PObjectType instances, and runtime types) full inference needed, since that will
|
142
|
+
# cover looking into the runtime type registry.
|
143
|
+
#
|
144
|
+
infer(o)
|
145
|
+
end
|
146
|
+
|
123
147
|
# @api public
|
124
148
|
def self.generalize(o)
|
125
149
|
singleton.generalize(o)
|
@@ -28,25 +28,9 @@ Puppet::Type.type(:group).provide :groupadd, :parent => Puppet::Provider::NameSe
|
|
28
28
|
get(:gid)
|
29
29
|
end
|
30
30
|
|
31
|
-
def findgroup(key, value)
|
32
|
-
group_file = "/etc/group"
|
33
|
-
group_keys = ['group_name', 'password', 'gid', 'user_list']
|
34
|
-
index = group_keys.index(key)
|
35
|
-
File.open(group_file) do |f|
|
36
|
-
f.each_line do |line|
|
37
|
-
group = line.split(":")
|
38
|
-
if group[index] == value
|
39
|
-
f.close
|
40
|
-
return group
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
false
|
45
|
-
end
|
46
|
-
|
47
31
|
def localgid
|
48
|
-
group = findgroup(
|
49
|
-
return group[
|
32
|
+
group = findgroup(:group_name, resource[:name])
|
33
|
+
return group[:gid] if group
|
50
34
|
false
|
51
35
|
end
|
52
36
|
|
@@ -56,7 +40,7 @@ Puppet::Type.type(:group).provide :groupadd, :parent => Puppet::Provider::NameSe
|
|
56
40
|
# to ensure consistent behaviour of the useradd provider when
|
57
41
|
# using both useradd and luseradd
|
58
42
|
if not @resource.allowdupe? and @resource.forcelocal?
|
59
|
-
if @resource.should(:gid) and findgroup(
|
43
|
+
if @resource.should(:gid) and findgroup(:gid, @resource.should(:gid).to_s)
|
60
44
|
raise(Puppet::Error, _("GID %{resource} already exists, use allowdupe to force group creation") % { resource: @resource.should(:gid).to_s })
|
61
45
|
end
|
62
46
|
elsif @resource.allowdupe? and not @resource.forcelocal?
|
@@ -108,4 +92,20 @@ Puppet::Type.type(:group).provide :groupadd, :parent => Puppet::Provider::NameSe
|
|
108
92
|
[command(:delete), @resource[:name]]
|
109
93
|
end
|
110
94
|
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def findgroup(key, value)
|
99
|
+
group_file = "/etc/group"
|
100
|
+
group_keys = [:group_name, :password, :gid, :user_list]
|
101
|
+
index = group_keys.index(key)
|
102
|
+
@group_content ||= File.read(group_file)
|
103
|
+
@group_content.each_line do |line|
|
104
|
+
group = line.split(":")
|
105
|
+
if group[index] == value
|
106
|
+
return Hash[group_keys.zip(group)]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
false
|
110
|
+
end
|
111
111
|
end
|
@@ -12,7 +12,7 @@ Puppet::Type.type(:mailalias).provide(
|
|
12
12
|
record_line :aliases, :fields => %w{name recipient}, :separator => /\s*:\s*/, :block_eval => :instance do
|
13
13
|
def post_parse(record)
|
14
14
|
if record[:recipient]
|
15
|
-
|
15
|
+
record[:recipient] = record[:recipient].split(/\s*,\s*(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/).collect { |d| d.gsub(/^['"]|['"]$/, '') }
|
16
16
|
end
|
17
17
|
record
|
18
18
|
end
|
@@ -70,7 +70,12 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
|
|
70
70
|
cmd += install_options if @resource[:install_options]
|
71
71
|
cmd << :install << str
|
72
72
|
|
73
|
-
|
73
|
+
self.unhold if self.properties[:mark] == :hold
|
74
|
+
begin
|
75
|
+
aptget(*cmd)
|
76
|
+
ensure
|
77
|
+
self.hold if @resource[:mark] == :hold
|
78
|
+
end
|
74
79
|
end
|
75
80
|
|
76
81
|
# What's the latest package version available?
|
@@ -100,12 +105,18 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
|
|
100
105
|
|
101
106
|
def uninstall
|
102
107
|
self.run_preseed if @resource[:responsefile]
|
103
|
-
|
108
|
+
args = ['-y', '-q']
|
109
|
+
args << '--allow-change-held-packages' if self.properties[:mark] == :hold
|
110
|
+
args << :remove << @resource[:name]
|
111
|
+
aptget(*args)
|
104
112
|
end
|
105
113
|
|
106
114
|
def purge
|
107
115
|
self.run_preseed if @resource[:responsefile]
|
108
|
-
|
116
|
+
args = ['-y', '-q']
|
117
|
+
args << '--allow-change-held-packages' if self.properties[:mark] == :hold
|
118
|
+
args << :remove << '--purge' << @resource[:name]
|
119
|
+
aptget(*args)
|
109
120
|
# workaround a "bug" in apt, that already removed packages are not purged
|
110
121
|
super
|
111
122
|
end
|
@@ -12,7 +12,7 @@ require 'puppet/provider/package'
|
|
12
12
|
|
13
13
|
Puppet::Type.type(:package).provide :dnfmodule, :parent => :dnf do
|
14
14
|
|
15
|
-
has_feature :installable, :uninstallable, :versionable
|
15
|
+
has_feature :installable, :uninstallable, :versionable, :supports_flavors
|
16
16
|
#has_feature :upgradeable
|
17
17
|
# it's not (yet) feasible to make this upgradeable since module streams don't
|
18
18
|
# always have matching version types (i.e. idm has streams DL1 and client,
|
@@ -83,5 +83,12 @@ Puppet::Type.type(:package).provide :dnfmodule, :parent => :dnf do
|
|
83
83
|
execute([command(:dnf), 'module', 'remove', '-d', '0', '-e', self.class.error_level, '-y', @resource[:name]])
|
84
84
|
reset # reset module to the default stream
|
85
85
|
end
|
86
|
-
end
|
87
86
|
|
87
|
+
def flavor
|
88
|
+
@property_hash[:flavor]
|
89
|
+
end
|
90
|
+
|
91
|
+
def flavor=(value)
|
92
|
+
install if flavor != @resource.should(:flavor)
|
93
|
+
end
|
94
|
+
end
|
@@ -44,7 +44,7 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
|
|
44
44
|
# Note: self:: is required here to keep these constants in the context of what will
|
45
45
|
# eventually become this Puppet::Type::Package::ProviderDpkg class.
|
46
46
|
self::DPKG_QUERY_FORMAT_STRING = %Q{'${Status} ${Package} ${Version}\\n'}
|
47
|
-
self::FIELDS_REGEX = %r{^(\S+) +(\S+) +(\S+) (\S+) (\S*)$}
|
47
|
+
self::FIELDS_REGEX = %r{^'?(\S+) +(\S+) +(\S+) (\S+) (\S*)$}
|
48
48
|
self::FIELDS= [:desired, :error, :status, :name, :ensure]
|
49
49
|
|
50
50
|
# @param line [String] one line of dpkg-query output
|
@@ -67,7 +67,7 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
|
|
67
67
|
elsif ['config-files', 'half-installed', 'unpacked', 'half-configured'].include?(hash[:status])
|
68
68
|
hash[:ensure] = :absent
|
69
69
|
end
|
70
|
-
hash[:
|
70
|
+
hash[:mark] = :hold if hash[:desired] == 'hold'
|
71
71
|
else
|
72
72
|
Puppet.debug("Failed to match dpkg-query line #{line.inspect}")
|
73
73
|
end
|
@@ -83,8 +83,6 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
|
|
83
83
|
end
|
84
84
|
args = []
|
85
85
|
|
86
|
-
# We always unhold when installing to remove any prior hold.
|
87
|
-
self.unhold
|
88
86
|
|
89
87
|
if @resource[:configfiles] == :keep
|
90
88
|
args << '--force-confold'
|
@@ -93,7 +91,12 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
|
|
93
91
|
end
|
94
92
|
args << '-i' << file
|
95
93
|
|
96
|
-
|
94
|
+
self.unhold if self.properties[:mark] == :hold
|
95
|
+
begin
|
96
|
+
dpkg(*args)
|
97
|
+
ensure
|
98
|
+
self.hold if @resource[:mark] == :hold
|
99
|
+
end
|
97
100
|
end
|
98
101
|
|
99
102
|
def update
|
@@ -144,10 +147,14 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
|
|
144
147
|
dpkg "--purge", @resource[:name]
|
145
148
|
end
|
146
149
|
|
147
|
-
def
|
150
|
+
def deprecated_hold
|
148
151
|
if package_not_installed?
|
149
152
|
self.install
|
150
153
|
end
|
154
|
+
hold
|
155
|
+
end
|
156
|
+
|
157
|
+
def hold
|
151
158
|
Tempfile.open('puppet_dpkg_set_selection') do |tmpfile|
|
152
159
|
tmpfile.write("#{@resource[:name]} hold\n")
|
153
160
|
tmpfile.flush
|
@@ -37,7 +37,12 @@ Puppet::Type.type(:package).provide :fink, :parent => :dpkg, :source => :dpkg do
|
|
37
37
|
|
38
38
|
cmd << :install << str
|
39
39
|
|
40
|
-
|
40
|
+
self.unhold if self.properties[:mark] == :hold
|
41
|
+
begin
|
42
|
+
finkcmd(cmd)
|
43
|
+
ensure
|
44
|
+
self.hold if @resource[:mark] == :hold
|
45
|
+
end
|
41
46
|
end
|
42
47
|
|
43
48
|
# What's the latest package version available?
|
@@ -70,10 +75,22 @@ Puppet::Type.type(:package).provide :fink, :parent => :dpkg, :source => :dpkg do
|
|
70
75
|
end
|
71
76
|
|
72
77
|
def uninstall
|
73
|
-
|
78
|
+
self.unhold if self.properties[:mark] == :hold
|
79
|
+
begin
|
80
|
+
finkcmd "-y", "-q", :remove, @model[:name]
|
81
|
+
rescue StandardError, LoadError => e
|
82
|
+
self.hold if self.properties[:mark] == :hold
|
83
|
+
raise e
|
84
|
+
end
|
74
85
|
end
|
75
86
|
|
76
87
|
def purge
|
77
|
-
|
88
|
+
self.unhold if self.properties[:mark] == :hold
|
89
|
+
begin
|
90
|
+
aptget '-y', '-q', 'remove', '--purge', @resource[:name]
|
91
|
+
rescue StandardError, LoadError => e
|
92
|
+
self.hold if self.properties[:mark] == :hold
|
93
|
+
raise e
|
94
|
+
end
|
78
95
|
end
|
79
96
|
end
|
@@ -20,6 +20,7 @@ Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Packa
|
|
20
20
|
has_feature :install_options
|
21
21
|
has_feature :uninstall_options
|
22
22
|
has_feature :upgradeable
|
23
|
+
has_feature :supports_flavors
|
23
24
|
|
24
25
|
def self.instances
|
25
26
|
packages = []
|
@@ -27,7 +28,7 @@ Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Packa
|
|
27
28
|
begin
|
28
29
|
execpipe(listcmd) do |process|
|
29
30
|
# our regex for matching pkg_info output
|
30
|
-
regex = /^(.*)-(\d[^-]*)[-]?(\w*)(.*)$/
|
31
|
+
regex = /^(.*)-(\d[^-]*)[-]?([\w-]*)(.*)$/
|
31
32
|
fields = [:name, :ensure, :flavor ]
|
32
33
|
hash = {}
|
33
34
|
|
@@ -239,4 +240,15 @@ Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Packa
|
|
239
240
|
def purge
|
240
241
|
pkgdelete "-c", "-q", @resource[:name]
|
241
242
|
end
|
243
|
+
|
244
|
+
def flavor
|
245
|
+
@property_hash[:flavor]
|
246
|
+
end
|
247
|
+
|
248
|
+
def flavor=(value)
|
249
|
+
if flavor != @resource.should(:flavor)
|
250
|
+
uninstall
|
251
|
+
install
|
252
|
+
end
|
253
|
+
end
|
242
254
|
end
|
@@ -49,7 +49,7 @@ Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package d
|
|
49
49
|
).merge(
|
50
50
|
case flags[1..1]
|
51
51
|
when 'f'
|
52
|
-
{:
|
52
|
+
{:mark => :hold}
|
53
53
|
when '-'
|
54
54
|
{}
|
55
55
|
else
|
@@ -107,6 +107,10 @@ Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package d
|
|
107
107
|
end).merge({:provider => self.name})
|
108
108
|
end
|
109
109
|
|
110
|
+
def deprecated_hold
|
111
|
+
hold
|
112
|
+
end
|
113
|
+
|
110
114
|
def hold
|
111
115
|
pkg(:freeze, @resource[:name])
|
112
116
|
end
|
@@ -201,8 +205,6 @@ Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package d
|
|
201
205
|
def install(nofail = false)
|
202
206
|
name = @resource[:name]
|
203
207
|
should = @resource[:ensure]
|
204
|
-
# always unhold if explicitly told to install/update
|
205
|
-
self.unhold
|
206
208
|
is = self.query
|
207
209
|
if is[:ensure].to_sym == :absent
|
208
210
|
command = 'install'
|
@@ -216,7 +218,12 @@ Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package d
|
|
216
218
|
unless should.is_a? Symbol
|
217
219
|
name += "@#{should}"
|
218
220
|
end
|
219
|
-
|
221
|
+
self.unhold if self.properties[:mark] == :hold
|
222
|
+
begin
|
223
|
+
r = exec_cmd(command(:pkg), command, *args, name)
|
224
|
+
ensure
|
225
|
+
self.hold if @resource[:mark] == :hold
|
226
|
+
end
|
220
227
|
return r if nofail
|
221
228
|
raise Puppet::Error, _("Unable to update %{package}") % { package: r[:out] } if r[:exit] != 0
|
222
229
|
end
|
@@ -230,7 +237,13 @@ Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package d
|
|
230
237
|
cmd << '-r'
|
231
238
|
end
|
232
239
|
cmd << @resource[:name]
|
233
|
-
|
240
|
+
self.unhold if self.properties[:mark] == :hold
|
241
|
+
begin
|
242
|
+
pkg cmd
|
243
|
+
rescue StandardError, LoadError => e
|
244
|
+
self.hold if self.properties[:mark] == :hold
|
245
|
+
raise e
|
246
|
+
end
|
234
247
|
end
|
235
248
|
|
236
249
|
# update the package to the latest version available
|
@@ -286,12 +286,16 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
|
|
286
286
|
# @param key [String] The key to look for in all contained hashes
|
287
287
|
# @return [Array<String>] All hash values with the given key.
|
288
288
|
def scan_options(options, key)
|
289
|
-
return []
|
290
|
-
options.
|
291
|
-
if
|
292
|
-
|
289
|
+
return [] unless options.is_a?(Enumerable)
|
290
|
+
values = options.map do | repo |
|
291
|
+
value = if repo.is_a?(String)
|
292
|
+
next unless repo.include?('=')
|
293
|
+
Hash[*repo.strip.split('=')] # make it a hash
|
294
|
+
else
|
295
|
+
repo
|
293
296
|
end
|
294
|
-
|
297
|
+
value[key]
|
295
298
|
end
|
299
|
+
values.compact.uniq
|
296
300
|
end
|
297
301
|
end
|
@@ -386,7 +386,7 @@ Puppet::Type.type(:user).provide :directoryservice do
|
|
386
386
|
if (Puppet::Util::Package.versioncmp(self.class.get_os_version, '10.7') > 0)
|
387
387
|
assert_full_pbkdf2_password
|
388
388
|
|
389
|
-
sleep
|
389
|
+
sleep 3
|
390
390
|
flush_dscl_cache
|
391
391
|
users_plist = get_users_plist(@resource.name)
|
392
392
|
shadow_hash_data = get_shadow_hash_data(users_plist)
|
@@ -403,7 +403,7 @@ Puppet::Type.type(:user).provide :directoryservice do
|
|
403
403
|
if (Puppet::Util::Package.versioncmp(self.class.get_os_version, '10.7') > 0)
|
404
404
|
assert_full_pbkdf2_password
|
405
405
|
|
406
|
-
sleep
|
406
|
+
sleep 3
|
407
407
|
flush_dscl_cache
|
408
408
|
users_plist = get_users_plist(@resource.name)
|
409
409
|
shadow_hash_data = get_shadow_hash_data(users_plist)
|
@@ -434,8 +434,8 @@ Puppet::Type.type(:user).provide :directoryservice do
|
|
434
434
|
['home', 'uid', 'gid', 'comment', 'shell'].each do |setter_method|
|
435
435
|
define_method("#{setter_method}=") do |value|
|
436
436
|
if @property_hash[setter_method.intern]
|
437
|
-
if self.class.get_os_version
|
438
|
-
raise Puppet::Error, "OS X version
|
437
|
+
if self.class.get_os_version.split('.').last.to_i >= 14 && %w(home uid).include?(setter_method)
|
438
|
+
raise Puppet::Error, "OS X version #{self.class.get_os_version} does not allow changing #{setter_method} using puppet"
|
439
439
|
end
|
440
440
|
begin
|
441
441
|
dscl '.', '-change', "/Users/#{resource.name}", self.class.ns_to_ds_attribute_map[setter_method.intern], @property_hash[setter_method.intern], value
|
@@ -571,7 +571,32 @@ Puppet::Type.type(:user).provide :directoryservice do
|
|
571
571
|
else
|
572
572
|
users_plist['ShadowHashData'] = [binary_plist]
|
573
573
|
end
|
574
|
-
|
574
|
+
if Puppet::Util::Package.versioncmp(self.class.get_os_version, '10.15') < 0
|
575
|
+
write_users_plist_to_disk(users_plist)
|
576
|
+
else
|
577
|
+
write_and_import_shadow_hash_data(users_plist['ShadowHashData'].first)
|
578
|
+
end
|
579
|
+
end
|
580
|
+
|
581
|
+
# This method writes the ShadowHashData plist in a temporary file,
|
582
|
+
# then imports it using dsimport. macOS versions 10.15 and newer do
|
583
|
+
# not support directly managing binary plists, so we have to use an
|
584
|
+
# intermediary.
|
585
|
+
# dsimport is an archaic utilitary with hard-to-find documentation
|
586
|
+
#
|
587
|
+
# See http://web.archive.org/web/20090106120111/http://support.apple.com/kb/TA21305?viewlocale=en_US
|
588
|
+
# for information regarding the dsimport syntax
|
589
|
+
def write_and_import_shadow_hash_data(data_plist)
|
590
|
+
Tempfile.create("dsimport_#{@resource.name}", :encoding => Encoding::ASCII) do |dsimport_file|
|
591
|
+
dsimport_file.write <<-DSIMPORT
|
592
|
+
0x0A 0x5C 0x3A 0x2C dsRecTypeStandard:Users 2 dsAttrTypeStandard:RecordName base64:dsAttrTypeNative:ShadowHashData
|
593
|
+
#{@resource.name}:#{Base64.strict_encode64(data_plist)}
|
594
|
+
DSIMPORT
|
595
|
+
dsimport_file.flush
|
596
|
+
# Delete the user's existing ShadowHashData, since dsimport appends, not replaces
|
597
|
+
dscl('.', 'delete', "/Users/#{@resource.name}", 'ShadowHashData')
|
598
|
+
dsimport(dsimport_file.path, '/Local/Default', 'M')
|
599
|
+
end
|
575
600
|
end
|
576
601
|
|
577
602
|
# This method accepts an argument of a hex password hash, and base64
|