puppet 6.12.0 → 6.13.0

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 (144) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +12 -12
  3. data/README.md +1 -1
  4. data/ext/project_data.yaml +1 -1
  5. data/lib/puppet.rb +22 -7
  6. data/lib/puppet/application/resource.rb +1 -1
  7. data/lib/puppet/configurer.rb +8 -13
  8. data/lib/puppet/defaults.rb +83 -49
  9. data/lib/puppet/environments.rb +26 -18
  10. data/lib/puppet/face/facts.rb +8 -5
  11. data/lib/puppet/file_system/memory_file.rb +6 -0
  12. data/lib/puppet/file_system/memory_impl.rb +13 -0
  13. data/lib/puppet/file_system/windows.rb +7 -10
  14. data/lib/puppet/http.rb +2 -0
  15. data/lib/puppet/http/client.rb +30 -0
  16. data/lib/puppet/http/errors.rb +2 -0
  17. data/lib/puppet/http/service.rb +61 -2
  18. data/lib/puppet/http/service/compiler.rb +86 -0
  19. data/lib/puppet/http/service/file_server.rb +85 -0
  20. data/lib/puppet/http/service/report.rb +4 -8
  21. data/lib/puppet/http/session.rb +8 -1
  22. data/lib/puppet/indirector/catalog/compiler.rb +10 -0
  23. data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
  24. data/lib/puppet/indirector/json.rb +1 -1
  25. data/lib/puppet/indirector/msgpack.rb +1 -1
  26. data/lib/puppet/network/http/connection.rb +4 -0
  27. data/lib/puppet/network/http/nocache_pool.rb +1 -0
  28. data/lib/puppet/network/http/pool.rb +5 -1
  29. data/lib/puppet/parser/ast/pops_bridge.rb +6 -11
  30. data/lib/puppet/pops/evaluator/access_operator.rb +2 -2
  31. data/lib/puppet/pops/evaluator/evaluator_impl.rb +1 -1
  32. data/lib/puppet/pops/loader/puppet_plan_instantiator.rb +12 -3
  33. data/lib/puppet/pops/parser/evaluating_parser.rb +5 -7
  34. data/lib/puppet/pops/types/p_object_type_extension.rb +10 -0
  35. data/lib/puppet/pops/types/type_calculator.rb +24 -0
  36. data/lib/puppet/pops/validation/checker4_0.rb +1 -1
  37. data/lib/puppet/pops/validation/tasks_checker.rb +5 -1
  38. data/lib/puppet/provider/aix_object.rb +4 -2
  39. data/lib/puppet/provider/group/aix.rb +1 -0
  40. data/lib/puppet/provider/group/groupadd.rb +52 -24
  41. data/lib/puppet/provider/package/apt.rb +14 -3
  42. data/lib/puppet/provider/package/dnfmodule.rb +9 -2
  43. data/lib/puppet/provider/package/dpkg.rb +14 -7
  44. data/lib/puppet/provider/package/fink.rb +20 -3
  45. data/lib/puppet/provider/package/openbsd.rb +13 -1
  46. data/lib/puppet/provider/package/pkg.rb +18 -5
  47. data/lib/puppet/provider/package/yum.rb +9 -5
  48. data/lib/puppet/provider/user/aix.rb +1 -0
  49. data/lib/puppet/provider/user/directoryservice.rb +30 -5
  50. data/lib/puppet/provider/user/useradd.rb +6 -7
  51. data/lib/puppet/reports/store.rb +1 -1
  52. data/lib/puppet/settings.rb +2 -0
  53. data/lib/puppet/ssl/certificate.rb +2 -1
  54. data/lib/puppet/test/test_helper.rb +4 -0
  55. data/lib/puppet/transaction/resource_harness.rb +1 -1
  56. data/lib/puppet/type/group.rb +2 -2
  57. data/lib/puppet/type/package.rb +63 -9
  58. data/lib/puppet/type/user.rb +2 -2
  59. data/lib/puppet/util/log/destinations.rb +1 -1
  60. data/lib/puppet/util/pidlock.rb +26 -6
  61. data/lib/puppet/util/plist.rb +6 -0
  62. data/lib/puppet/util/storage.rb +0 -1
  63. data/lib/puppet/util/yaml.rb +1 -1
  64. data/lib/puppet/version.rb +1 -1
  65. data/locales/puppet.pot +127 -115
  66. data/man/man5/puppet.conf.5 +21 -7
  67. data/man/man8/puppet-agent.8 +1 -1
  68. data/man/man8/puppet-apply.8 +1 -1
  69. data/man/man8/puppet-catalog.8 +1 -1
  70. data/man/man8/puppet-config.8 +1 -1
  71. data/man/man8/puppet-describe.8 +1 -1
  72. data/man/man8/puppet-device.8 +1 -1
  73. data/man/man8/puppet-doc.8 +1 -1
  74. data/man/man8/puppet-epp.8 +1 -1
  75. data/man/man8/puppet-facts.8 +1 -1
  76. data/man/man8/puppet-filebucket.8 +1 -1
  77. data/man/man8/puppet-generate.8 +1 -1
  78. data/man/man8/puppet-help.8 +1 -1
  79. data/man/man8/puppet-key.8 +1 -1
  80. data/man/man8/puppet-lookup.8 +1 -1
  81. data/man/man8/puppet-man.8 +1 -1
  82. data/man/man8/puppet-module.8 +1 -1
  83. data/man/man8/puppet-node.8 +1 -1
  84. data/man/man8/puppet-parser.8 +1 -1
  85. data/man/man8/puppet-plugin.8 +1 -1
  86. data/man/man8/puppet-report.8 +1 -1
  87. data/man/man8/puppet-resource.8 +1 -1
  88. data/man/man8/puppet-script.8 +1 -1
  89. data/man/man8/puppet-ssl.8 +1 -1
  90. data/man/man8/puppet-status.8 +1 -1
  91. data/man/man8/puppet.8 +2 -2
  92. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_fetch_if_not_on_the_local_disk.yml +0 -35
  93. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_not_update_if_content_on_disk_is_up-to-date.yml +0 -37
  94. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_update_if_content_differs_on_disk.yml +0 -37
  95. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_mtime_is_older_on_disk.yml +0 -35
  96. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_no_header_specified.yml +0 -33
  97. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_not_on_the_local_disk.yml +0 -35
  98. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_not_update_if_mtime_is_newer_on_disk.yml +0 -35
  99. data/spec/integration/configurer_spec.rb +26 -7
  100. data/spec/integration/indirector/facts/facter_spec.rb +4 -0
  101. data/spec/unit/application/apply_spec.rb +2 -12
  102. data/spec/unit/application/resource_spec.rb +2 -2
  103. data/spec/unit/configurer/fact_handler_spec.rb +0 -4
  104. data/spec/unit/configurer_spec.rb +0 -3
  105. data/spec/unit/defaults_spec.rb +1 -1
  106. data/spec/unit/environments_spec.rb +57 -28
  107. data/spec/unit/face/facts_spec.rb +24 -20
  108. data/spec/unit/file_system_spec.rb +16 -2
  109. data/spec/unit/http/client_spec.rb +6 -0
  110. data/spec/unit/http/service/compiler_spec.rb +322 -0
  111. data/spec/unit/http/service/file_server_spec.rb +219 -0
  112. data/spec/unit/http/service/report_spec.rb +8 -1
  113. data/spec/unit/http/service_spec.rb +4 -0
  114. data/spec/unit/http/session_spec.rb +31 -0
  115. data/spec/unit/indirector/catalog/compiler_spec.rb +46 -29
  116. data/spec/unit/network/http/connection_spec.rb +23 -1
  117. data/spec/unit/network/http/nocache_pool_spec.rb +3 -3
  118. data/spec/unit/network/http/pool_spec.rb +32 -0
  119. data/spec/unit/node/facts_spec.rb +2 -1
  120. data/spec/unit/node_spec.rb +7 -4
  121. data/spec/unit/pops/serialization/to_from_hr_spec.rb +6 -1
  122. data/spec/unit/pops/validator/validator_spec.rb +7 -2
  123. data/spec/unit/provider/aix_object_spec.rb +16 -2
  124. data/spec/unit/provider/group/groupadd_spec.rb +167 -56
  125. data/spec/unit/provider/package/apt_spec.rb +13 -2
  126. data/spec/unit/provider/package/aptitude_spec.rb +1 -0
  127. data/spec/unit/provider/package/dnfmodule_spec.rb +22 -0
  128. data/spec/unit/provider/package/dpkg_spec.rb +28 -6
  129. data/spec/unit/provider/package/openbsd_spec.rb +17 -0
  130. data/spec/unit/provider/package/pkg_spec.rb +15 -1
  131. data/spec/unit/provider/package/yum_spec.rb +50 -0
  132. data/spec/unit/provider/user/directoryservice_spec.rb +41 -0
  133. data/spec/unit/provider/user/useradd_spec.rb +13 -8
  134. data/spec/unit/puppet_pal_2pec.rb +3 -0
  135. data/spec/unit/puppet_pal_catalog_spec.rb +3 -0
  136. data/spec/unit/puppet_spec.rb +14 -0
  137. data/spec/unit/ssl/certificate_spec.rb +7 -0
  138. data/spec/unit/transaction/persistence_spec.rb +1 -10
  139. data/spec/unit/type/package_spec.rb +8 -0
  140. data/spec/unit/type/user_spec.rb +0 -1
  141. data/spec/unit/util/pidlock_spec.rb +38 -16
  142. data/spec/unit/util/plist_spec.rb +20 -0
  143. data/spec/unit/util/storage_spec.rb +1 -8
  144. metadata +10 -4
@@ -75,7 +75,12 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
75
75
  cmd += install_options if @resource[:install_options]
76
76
  cmd << :install << str
77
77
 
78
- aptget(*cmd)
78
+ self.unhold if self.properties[:mark] == :hold
79
+ begin
80
+ aptget(*cmd)
81
+ ensure
82
+ self.hold if @resource[:mark] == :hold
83
+ end
79
84
  end
80
85
 
81
86
  # What's the latest package version available?
@@ -106,12 +111,18 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
106
111
 
107
112
  def uninstall
108
113
  self.run_preseed if @resource[:responsefile]
109
- aptget "-y", "-q", :remove, @resource[:name]
114
+ args = ['-y', '-q']
115
+ args << '--allow-change-held-packages' if self.properties[:mark] == :hold
116
+ args << :remove << @resource[:name]
117
+ aptget(*args)
110
118
  end
111
119
 
112
120
  def purge
113
121
  self.run_preseed if @resource[:responsefile]
114
- aptget '-y', '-q', :remove, '--purge', @resource[:name]
122
+ args = ['-y', '-q']
123
+ args << '--allow-change-held-packages' if self.properties[:mark] == :hold
124
+ args << :remove << '--purge' << @resource[:name]
125
+ aptget(*args)
115
126
  # workaround a "bug" in apt, that already removed packages are not purged
116
127
  super
117
128
  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
@@ -45,8 +45,8 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
45
45
  # eventually become this Puppet::Type::Package::ProviderDpkg class.
46
46
  self::DPKG_QUERY_FORMAT_STRING = %Q{'${Status} ${Package} ${Version}\\n'}
47
47
  self::DPKG_QUERY_PROVIDES_FORMAT_STRING = %Q{'${Status} ${Package} ${Version} [${Provides}]\\n'}
48
- self::FIELDS_REGEX = %r{^(\S+) +(\S+) +(\S+) (\S+) (\S*)$}
49
- self::FIELDS_REGEX_WITH_PROVIDES = %r{^(\S+) +(\S+) +(\S+) (\S+) (\S*) \[.*\]$}
48
+ self::FIELDS_REGEX = %r{^'?(\S+) +(\S+) +(\S+) (\S+) (\S*)$}
49
+ self::FIELDS_REGEX_WITH_PROVIDES = %r{^'?(\S+) +(\S+) +(\S+) (\S+) (\S*) \[.*\]$}
50
50
  self::FIELDS= [:desired, :error, :status, :name, :ensure]
51
51
 
52
52
  def self.defaultto_allow_virtual
@@ -74,7 +74,7 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
74
74
  elsif ['config-files', 'half-installed', 'unpacked', 'half-configured'].include?(hash[:status])
75
75
  hash[:ensure] = :absent
76
76
  end
77
- hash[:ensure] = :held if hash[:desired] == 'hold'
77
+ hash[:mark] = :hold if hash[:desired] == 'hold'
78
78
  else
79
79
  Puppet.debug("Failed to match dpkg-query line #{line.inspect}")
80
80
  end
@@ -91,8 +91,6 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
91
91
  end
92
92
  args = []
93
93
 
94
- # We always unhold when installing to remove any prior hold.
95
- self.unhold
96
94
 
97
95
  if @resource[:configfiles] == :keep
98
96
  args << '--force-confold'
@@ -101,7 +99,12 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
101
99
  end
102
100
  args << '-i' << file
103
101
 
104
- dpkg(*args)
102
+ self.unhold if self.properties[:mark] == :hold
103
+ begin
104
+ dpkg(*args)
105
+ ensure
106
+ self.hold if @resource[:mark] == :hold
107
+ end
105
108
  end
106
109
 
107
110
  def update
@@ -170,10 +173,14 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
170
173
  dpkg "--purge", @resource[:name]
171
174
  end
172
175
 
173
- def hold
176
+ def deprecated_hold
174
177
  if package_not_installed?
175
178
  self.install
176
179
  end
180
+ hold
181
+ end
182
+
183
+ def hold
177
184
  Tempfile.open('puppet_dpkg_set_selection') do |tmpfile|
178
185
  tmpfile.write("#{@resource[:name]} hold\n")
179
186
  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
- finkcmd(cmd)
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?
@@ -71,10 +76,22 @@ Puppet::Type.type(:package).provide :fink, :parent => :dpkg, :source => :dpkg do
71
76
  end
72
77
 
73
78
  def uninstall
74
- finkcmd "-y", "-q", :remove, @model[:name]
79
+ self.unhold if self.properties[:mark] == :hold
80
+ begin
81
+ finkcmd "-y", "-q", :remove, @model[:name]
82
+ rescue StandardError, LoadError => e
83
+ self.hold if self.properties[:mark] == :hold
84
+ raise e
85
+ end
75
86
  end
76
87
 
77
88
  def purge
78
- aptget '-y', '-q', 'remove', '--purge', @resource[:name]
89
+ self.unhold if self.properties[:mark] == :hold
90
+ begin
91
+ aptget '-y', '-q', 'remove', '--purge', @resource[:name]
92
+ rescue StandardError, LoadError => e
93
+ self.hold if self.properties[:mark] == :hold
94
+ raise e
95
+ end
79
96
  end
80
97
  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
 
@@ -245,4 +246,15 @@ Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Packa
245
246
  def purge
246
247
  pkgdelete "-c", "-q", @resource[:name]
247
248
  end
249
+
250
+ def flavor
251
+ @property_hash[:flavor]
252
+ end
253
+
254
+ def flavor=(value)
255
+ if flavor != @resource.should(:flavor)
256
+ uninstall
257
+ install
258
+ end
259
+ end
248
260
  end
@@ -56,7 +56,7 @@ Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package d
56
56
  ).merge(
57
57
  case flags[1..1]
58
58
  when 'f'
59
- {:ensure => 'held'}
59
+ {:mark => :hold}
60
60
  when '-'
61
61
  {}
62
62
  else
@@ -114,6 +114,10 @@ Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package d
114
114
  end).merge({:provider => self.name})
115
115
  end
116
116
 
117
+ def deprecated_hold
118
+ hold
119
+ end
120
+
117
121
  def hold
118
122
  pkg(:freeze, @resource[:name])
119
123
  end
@@ -214,8 +218,6 @@ Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package d
214
218
  def install(nofail = false)
215
219
  name = @resource[:name]
216
220
  should = @resource[:ensure]
217
- # always unhold if explicitly told to install/update
218
- self.unhold
219
221
  is = self.query
220
222
  if is[:ensure].to_sym == :absent
221
223
  command = 'install'
@@ -230,7 +232,12 @@ Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package d
230
232
  unless should.is_a? Symbol
231
233
  name += "@#{should}"
232
234
  end
233
- r = exec_cmd(command(:pkg), command, *args, name)
235
+ self.unhold if self.properties[:mark] == :hold
236
+ begin
237
+ r = exec_cmd(command(:pkg), command, *args, name)
238
+ ensure
239
+ self.hold if @resource[:mark] == :hold
240
+ end
234
241
  return r if nofail
235
242
  raise Puppet::Error, _("Unable to update %{package}") % { package: r[:out] } if r[:exit] != 0
236
243
  end
@@ -244,7 +251,13 @@ Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package d
244
251
  cmd << '-r'
245
252
  end
246
253
  cmd << @resource[:name]
247
- pkg cmd
254
+ self.unhold if self.properties[:mark] == :hold
255
+ begin
256
+ pkg cmd
257
+ rescue StandardError, LoadError => e
258
+ self.hold if self.properties[:mark] == :hold
259
+ raise e
260
+ end
248
261
  end
249
262
 
250
263
  # update the package to the latest version available
@@ -286,12 +286,16 @@ defaultfor :osfamily => :redhat, :operatingsystemmajrelease => (4..7).to_a
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 [] if options.nil?
290
- options.inject([]) do |repos, opt|
291
- if opt.is_a? Hash and opt[key]
292
- repos << opt[key]
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
- repos
297
+ value[key]
295
298
  end
299
+ values.compact.uniq
296
300
  end
297
301
  end
@@ -32,6 +32,7 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
32
32
  has_features :manages_aix_lam
33
33
  has_features :manages_homedir, :manages_passwords, :manages_shell
34
34
  has_features :manages_expiry, :manages_password_age
35
+ has_features :manages_local_users_and_groups
35
36
 
36
37
  class << self
37
38
  def group_provider
@@ -387,7 +387,7 @@ Puppet::Type.type(:user).provide :directoryservice do
387
387
  if (Puppet::Util::Package.versioncmp(self.class.get_os_version, '10.7') > 0)
388
388
  assert_full_pbkdf2_password
389
389
 
390
- sleep 2
390
+ sleep 3
391
391
  flush_dscl_cache
392
392
  users_plist = get_users_plist(@resource.name)
393
393
  shadow_hash_data = get_shadow_hash_data(users_plist)
@@ -404,7 +404,7 @@ Puppet::Type.type(:user).provide :directoryservice do
404
404
  if (Puppet::Util::Package.versioncmp(self.class.get_os_version, '10.7') > 0)
405
405
  assert_full_pbkdf2_password
406
406
 
407
- sleep 2
407
+ sleep 3
408
408
  flush_dscl_cache
409
409
  users_plist = get_users_plist(@resource.name)
410
410
  shadow_hash_data = get_shadow_hash_data(users_plist)
@@ -435,8 +435,8 @@ Puppet::Type.type(:user).provide :directoryservice do
435
435
  ['home', 'uid', 'gid', 'comment', 'shell'].each do |setter_method|
436
436
  define_method("#{setter_method}=") do |value|
437
437
  if @property_hash[setter_method.intern]
438
- if self.class.get_os_version == '10.14' && %w(home uid).include?(setter_method)
439
- raise Puppet::Error, "OS X version 10\.14 does not allow changing #{setter_method} using puppet"
438
+ if self.class.get_os_version.split('.').last.to_i >= 14 && %w(home uid).include?(setter_method)
439
+ raise Puppet::Error, "OS X version #{self.class.get_os_version} does not allow changing #{setter_method} using puppet"
440
440
  end
441
441
  begin
442
442
  dscl '.', '-change', "/Users/#{resource.name}", self.class.ns_to_ds_attribute_map[setter_method.intern], @property_hash[setter_method.intern], value
@@ -572,7 +572,32 @@ Puppet::Type.type(:user).provide :directoryservice do
572
572
  else
573
573
  users_plist['ShadowHashData'] = [binary_plist]
574
574
  end
575
- write_users_plist_to_disk(users_plist)
575
+ if Puppet::Util::Package.versioncmp(self.class.get_os_version, '10.15') < 0
576
+ write_users_plist_to_disk(users_plist)
577
+ else
578
+ write_and_import_shadow_hash_data(users_plist['ShadowHashData'].first)
579
+ end
580
+ end
581
+
582
+ # This method writes the ShadowHashData plist in a temporary file,
583
+ # then imports it using dsimport. macOS versions 10.15 and newer do
584
+ # not support directly managing binary plists, so we have to use an
585
+ # intermediary.
586
+ # dsimport is an archaic utilitary with hard-to-find documentation
587
+ #
588
+ # See http://web.archive.org/web/20090106120111/http://support.apple.com/kb/TA21305?viewlocale=en_US
589
+ # for information regarding the dsimport syntax
590
+ def write_and_import_shadow_hash_data(data_plist)
591
+ Tempfile.create("dsimport_#{@resource.name}", :encoding => Encoding::ASCII) do |dsimport_file|
592
+ dsimport_file.write <<-DSIMPORT
593
+ 0x0A 0x5C 0x3A 0x2C dsRecTypeStandard:Users 2 dsAttrTypeStandard:RecordName base64:dsAttrTypeNative:ShadowHashData
594
+ #{@resource.name}:#{Base64.strict_encode64(data_plist)}
595
+ DSIMPORT
596
+ dsimport_file.flush
597
+ # Delete the user's existing ShadowHashData, since dsimport appends, not replaces
598
+ dscl('.', 'delete', "/Users/#{@resource.name}", 'ShadowHashData')
599
+ dsimport(dsimport_file.path, '/Local/Default', 'M')
600
+ end
576
601
  end
577
602
 
578
603
  # This method accepts an argument of a hex password hash, and base64
@@ -43,7 +43,7 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
43
43
  }
44
44
 
45
45
  optional_commands :localadd => "luseradd", :localdelete => "luserdel", :localmodify => "lusermod", :localpassword => "lchage"
46
- has_feature :libuser if Puppet.features.libuser?
46
+ has_feature :manages_local_users_and_groups if Puppet.features.libuser?
47
47
 
48
48
  def exists?
49
49
  return !!localuid if @resource.forcelocal?
@@ -64,12 +64,11 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
64
64
  passwd_file = "/etc/passwd"
65
65
  passwd_keys = [:account, :password, :uid, :gid, :gecos, :directory, :shell]
66
66
  index = passwd_keys.index(key)
67
- File.open(passwd_file) do |f|
68
- f.each_line do |line|
69
- user = line.split(":")
70
- if user[index] == value
71
- return Hash[passwd_keys.zip(user)]
72
- end
67
+ @passwd_content ||= File.read(passwd_file)
68
+ @passwd_content.each_line do |line|
69
+ user = line.split(":")
70
+ if user[index] == value
71
+ return Hash[passwd_keys.zip(user)]
73
72
  end
74
73
  end
75
74
  false
@@ -32,7 +32,7 @@ Puppet::Reports.register_report(:store) do
32
32
  file = File.join(dir, name)
33
33
 
34
34
  begin
35
- Puppet::Util.replace_file(file, 0640) do |fh|
35
+ Puppet::FileSystem.replace_file(file, 0640) do |fh|
36
36
  fh.print to_yaml
37
37
  end
38
38
  rescue => detail
@@ -1239,6 +1239,8 @@ Generated on #{Time.now}.
1239
1239
  configured_environment = self[:environment]
1240
1240
  if configured_environment == "production" && envdir && Puppet::FileSystem.exist?(envdir)
1241
1241
  configured_environment_path = File.join(envdir, configured_environment)
1242
+ # If configured_environment_path is a symlink, assume the source path is being managed
1243
+ # elsewhere, so don't do any of this configuration
1242
1244
  if !Puppet::FileSystem.symlink?(configured_environment_path)
1243
1245
  parameters = { :ensure => 'directory' }
1244
1246
  unless Puppet::FileSystem.exist?(configured_environment_path)
@@ -56,7 +56,8 @@ DOC
56
56
  def custom_extensions
57
57
  custom_exts = content.extensions.select do |ext|
58
58
  Puppet::SSL::Oids.subtree_of?('ppRegCertExt', ext.oid) or
59
- Puppet::SSL::Oids.subtree_of?('ppPrivCertExt', ext.oid)
59
+ Puppet::SSL::Oids.subtree_of?('ppPrivCertExt', ext.oid) or
60
+ Puppet::SSL::Oids.subtree_of?('ppAuthCertExt', ext.oid)
60
61
  end
61
62
 
62
63
  custom_exts.map do |ext|
@@ -147,6 +147,10 @@ module Puppet::Test
147
147
  Puppet::SSL::Host.reset
148
148
  Puppet::Rest::Routes.clear
149
149
 
150
+ Puppet::Node::Facts.indirection.terminus_class = :memory
151
+ facts = Puppet::Node::Facts.new(Puppet[:node_name_value])
152
+ Puppet::Node::Facts.indirection.save(facts)
153
+
150
154
  Puppet.clear_deprecation_warnings
151
155
  end
152
156
 
@@ -101,7 +101,7 @@ class Puppet::Transaction::ResourceHarness
101
101
  # We persist the last known values for the properties of a resource after resource
102
102
  # application.
103
103
  # @param [Puppet::Type] resource resource whose values we are to persist.
104
- # @param [ResourceApplicationContent] context the application context to operate on.
104
+ # @param [ResourceApplicationContext] context the application context to operate on.
105
105
  def persist_system_values(resource, context)
106
106
  param_to_event = {}
107
107
  context.status.events.each do |ev|
@@ -22,7 +22,7 @@ module Puppet
22
22
  feature :system_groups,
23
23
  "The provider allows you to create system groups with lower GIDs."
24
24
 
25
- feature :libuser,
25
+ feature :manages_local_users_and_groups,
26
26
  "Allows local groups to be managed on systems that also use some other
27
27
  remote Name Switch Service (NSS) method of managing accounts."
28
28
 
@@ -214,7 +214,7 @@ module Puppet
214
214
  end
215
215
 
216
216
  newparam(:forcelocal, :boolean => true,
217
- :required_features => :libuser,
217
+ :required_features => :manages_local_users_and_groups,
218
218
  :parent => Puppet::Parameter::Boolean) do
219
219
  desc "Forces the management of local accounts when accounts are also
220
220
  being managed by some other Name Switch Service (NSS). For AIX, refer to the `ia_load_module` parameter.
@@ -54,14 +54,14 @@ module Puppet
54
54
  feature :holdable, "The provider is capable of placing packages on hold
55
55
  such that they are not automatically upgraded as a result of
56
56
  other package dependencies unless explicit action is taken by
57
- a user or another package. Held is considered a superset of
58
- installed.",
59
- :methods => [:hold]
57
+ a user or another package.",
58
+ :methods => [:hold, :unhold]
60
59
  feature :install_only, "The provider accepts options to only install packages never update (kernels, etc.)"
61
60
  feature :install_options, "The provider accepts options to be
62
61
  passed to the installer command."
63
62
  feature :uninstall_options, "The provider accepts options to be
64
63
  passed to the uninstaller command."
64
+ feature :supports_flavors, "The provider accepts flavors, which are specific variants of packages."
65
65
  feature :package_settings, "The provider accepts package_settings to be
66
66
  ensured for the given package. The meaning and format of these settings is
67
67
  provider-specific.",
@@ -101,7 +101,7 @@ module Puppet
101
101
  end
102
102
 
103
103
  newvalue(:held, :event => :package_held, :required_features => :holdable) do
104
- provider.hold
104
+ provider.deprecated_hold
105
105
  end
106
106
 
107
107
  # Alias the 'present' value.
@@ -405,6 +405,11 @@ module Puppet
405
405
  end
406
406
  end
407
407
 
408
+ newproperty(:flavor, :required_features => :supports_flavors) do
409
+ desc "OpenBSD and DNF modules support 'flavors', which are
410
+ further specifications for which type of package you want."
411
+ end
412
+
408
413
  newparam(:source) do
409
414
  desc "Where to find the package file. This is only used by providers that don't
410
415
  automatically download packages from a central repository. (For example:
@@ -484,11 +489,6 @@ module Puppet
484
489
  newvalues(:true, :false)
485
490
  end
486
491
 
487
- newparam(:flavor) do
488
- desc "OpenBSD and DNF modules support 'flavors', which are
489
- further specifications for which type of package you want."
490
- end
491
-
492
492
  newparam(:install_only, :boolean => false, :parent => Puppet::Parameter::Boolean, :required_features => :install_only) do
493
493
  desc <<-EOT
494
494
  It should be set for packages that should only ever be installed,
@@ -625,5 +625,59 @@ module Puppet
625
625
  provider.reinstall
626
626
  end
627
627
  end
628
+
629
+ newproperty(:mark, :required_features => :holdable) do
630
+ mark_doc='Valid values are: hold/none'
631
+ desc <<-EOT
632
+ Set to hold to tell Debian apt/Solaris pkg to hold the package version
633
+
634
+ #{mark_doc}
635
+ Default is "none". Mark can be specified with or without `ensure`,
636
+ if `ensure` is missing will default to "present".
637
+
638
+ Mark cannot be specified together with "purged", "absent" or "held"
639
+ values for `ensure`.
640
+ EOT
641
+ newvalues(:hold, :none)
642
+ munge do |value|
643
+ case value
644
+ when "hold", :hold
645
+ :hold
646
+ when "none", :none
647
+ :none
648
+ else
649
+ raise ArgumentError, _('Invalid hold value %{value}. %{doc}') % { value: value.inspect, doc: mark_doc}
650
+ end
651
+ end
652
+
653
+ def insync?(is)
654
+ @should[0] == is
655
+ end
656
+
657
+ def should
658
+ @should[0] if @should && @should.is_a?(Array) && @should.size == 1
659
+ end
660
+
661
+ def retrieve
662
+ provider.properties[:mark]
663
+ end
664
+
665
+ def sync
666
+ if @should[0] == :hold
667
+ provider.hold
668
+ else
669
+ provider.unhold
670
+ end
671
+ end
672
+ end
673
+
674
+ validate do
675
+ if :held == @parameters[:ensure].should
676
+ warning '"ensure=>held" has been deprecated and will be removed in a future version, use "mark=hold" instead'
677
+ end
678
+ if @parameters[:mark] && [:absent, :purged, :held].include?(@parameters[:ensure].should)
679
+ raise ArgumentError, _('You cannot use "mark" property while "ensure" is one of ["absent", "purged", "held"]')
680
+ end
681
+ end
628
682
  end
629
683
  end