puppet 2.7.18 → 2.7.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.

Files changed (137) hide show
  1. data/CHANGELOG +82 -0
  2. data/CONTRIBUTING.md +114 -171
  3. data/README.md +8 -0
  4. data/README_DEVELOPER.md +38 -3
  5. data/Rakefile +19 -3
  6. data/conf/osx/createpackage.sh +3 -1
  7. data/conf/redhat/logrotate +1 -1
  8. data/conf/redhat/puppet.spec +35 -8
  9. data/lib/puppet.rb +1 -1
  10. data/lib/puppet/application/agent.rb +2 -0
  11. data/lib/puppet/application/master.rb +2 -0
  12. data/lib/puppet/configurer.rb +2 -3
  13. data/lib/puppet/defaults.rb +6 -5
  14. data/lib/puppet/face/module/install.rb +2 -1
  15. data/lib/puppet/file_bucket/dipper.rb +1 -1
  16. data/lib/puppet/indirector/file_content.rb +2 -2
  17. data/lib/puppet/indirector/file_metadata.rb +2 -2
  18. data/lib/puppet/indirector/indirection.rb +3 -4
  19. data/lib/puppet/indirector/rest.rb +12 -6
  20. data/lib/puppet/interface/action_manager.rb +1 -2
  21. data/lib/puppet/module_tool/applications/unpacker.rb +22 -3
  22. data/lib/puppet/network/handler/fileserver.rb +2 -2
  23. data/lib/puppet/parser/ast/resource.rb +9 -2
  24. data/lib/puppet/parser/functions/fqdn_rand.rb +2 -1
  25. data/lib/puppet/parser/functions/md5.rb +2 -2
  26. data/lib/puppet/parser/functions/sha1.rb +2 -2
  27. data/lib/puppet/parser/functions/template.rb +0 -2
  28. data/lib/puppet/parser/type_loader.rb +1 -2
  29. data/lib/puppet/provider/augeas/augeas.rb +19 -1
  30. data/lib/puppet/provider/confine.rb +1 -1
  31. data/lib/puppet/provider/package/msi.rb +97 -51
  32. data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +1 -0
  33. data/lib/puppet/provider/service/gentoo.rb +0 -2
  34. data/lib/puppet/provider/service/openrc.rb +69 -0
  35. data/lib/puppet/provider/service/windows.rb +6 -4
  36. data/lib/puppet/provider/user/aix.rb +8 -4
  37. data/lib/puppet/provider/user/useradd.rb +6 -0
  38. data/lib/puppet/rails/benchmark.rb +2 -2
  39. data/lib/puppet/reports/store.rb +9 -9
  40. data/lib/puppet/resource/catalog.rb +2 -1
  41. data/lib/puppet/resource/type_collection.rb +2 -1
  42. data/lib/puppet/ssl/base.rb +1 -2
  43. data/lib/puppet/ssl/certificate_authority/interface.rb +1 -0
  44. data/lib/puppet/test/test_helper.rb +2 -1
  45. data/lib/puppet/type.rb +1 -1
  46. data/lib/puppet/type/augeas.rb +1 -1
  47. data/lib/puppet/type/file.rb +4 -2
  48. data/lib/puppet/type/scheduled_task.rb +8 -10
  49. data/lib/puppet/type/tidy.rb +1 -1
  50. data/lib/puppet/util.rb +63 -25
  51. data/lib/puppet/util/autoload.rb +6 -4
  52. data/lib/puppet/util/checksums.rb +3 -8
  53. data/lib/puppet/util/diff.rb +2 -1
  54. data/lib/puppet/util/filetype.rb +1 -3
  55. data/lib/puppet/util/run_mode.rb +2 -1
  56. data/lib/puppet/util/suidmanager.rb +1 -1
  57. data/lib/puppet/util/windows.rb +1 -0
  58. data/lib/puppet/util/windows/file.rb +27 -0
  59. data/lib/puppet/util/windows/user.rb +1 -2
  60. data/man/man8/puppet-agent.8 +4 -0
  61. data/man/man8/puppet-master.8 +4 -0
  62. data/man/man8/puppetmasterd.8 +4 -0
  63. data/spec/fixtures/unit/provider/augeas/augeas/augeas/lenses/test.aug +13 -0
  64. data/spec/fixtures/unit/provider/augeas/augeas/etc/fstab +10 -0
  65. data/spec/fixtures/unit/provider/augeas/augeas/etc/hosts +6 -0
  66. data/spec/fixtures/unit/provider/augeas/augeas/etc/test +3 -0
  67. data/spec/fixtures/unit/provider/augeas/augeas/test.aug +13 -0
  68. data/spec/fixtures/unit/provider/service/openrc/rcservice_list +8 -0
  69. data/spec/fixtures/unit/provider/service/openrc/rcstatus +43 -0
  70. data/spec/integration/defaults_spec.rb +3 -3
  71. data/spec/integration/network/server/mongrel_spec.rb +8 -6
  72. data/spec/integration/parser/parser_spec.rb +1 -1
  73. data/spec/integration/type/file_spec.rb +49 -12
  74. data/spec/lib/puppet_spec/database.rb +5 -3
  75. data/spec/lib/puppet_spec/files.rb +2 -1
  76. data/spec/monkey_patches/alias_should_to_must.rb +15 -2
  77. data/spec/shared_behaviours/file_serving_model.rb +9 -6
  78. data/spec/shared_behaviours/path_parameters.rb +5 -5
  79. data/spec/shared_behaviours/things_that_declare_options.rb +5 -5
  80. data/spec/unit/application/facts_spec.rb +1 -1
  81. data/spec/unit/application_spec.rb +10 -8
  82. data/spec/unit/configurer_spec.rb +11 -2
  83. data/spec/unit/face/ca_spec.rb +15 -15
  84. data/spec/unit/face/help_spec.rb +5 -5
  85. data/spec/unit/face/module/install_spec.rb +13 -2
  86. data/spec/unit/face/node_spec.rb +7 -6
  87. data/spec/unit/indirector/certificate_request/ca_spec.rb +1 -1
  88. data/spec/unit/indirector/envelope_spec.rb +0 -13
  89. data/spec/unit/indirector/facts/inventory_service_spec.rb +1 -1
  90. data/spec/unit/indirector/queue_spec.rb +3 -3
  91. data/spec/unit/indirector/rest_spec.rb +31 -20
  92. data/spec/unit/indirector_spec.rb +5 -5
  93. data/spec/unit/interface/action_builder_spec.rb +3 -2
  94. data/spec/unit/interface/action_manager_spec.rb +1 -1
  95. data/spec/unit/interface/action_spec.rb +4 -3
  96. data/spec/unit/interface/face_collection_spec.rb +1 -1
  97. data/spec/unit/interface/option_spec.rb +13 -9
  98. data/spec/unit/interface_spec.rb +5 -5
  99. data/spec/unit/module_tool/applications/unpacker_spec.rb +61 -0
  100. data/spec/unit/network/handler/fileserver_spec.rb +3 -3
  101. data/spec/unit/other/transbucket_spec.rb +6 -9
  102. data/spec/unit/parser/ast/resource_spec.rb +27 -0
  103. data/spec/unit/parser/functions/create_resources_spec.rb +12 -12
  104. data/spec/unit/parser/lexer_spec.rb +5 -5
  105. data/spec/unit/provider/augeas/augeas_spec.rb +78 -0
  106. data/spec/unit/provider/nameservice/directoryservice_spec.rb +6 -6
  107. data/spec/unit/provider/package/freebsd_spec.rb +2 -2
  108. data/spec/unit/provider/package/msi_spec.rb +181 -114
  109. data/spec/unit/provider/package/openbsd_spec.rb +1 -0
  110. data/spec/unit/provider/package/pkgdmg_spec.rb +3 -3
  111. data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +1 -1
  112. data/spec/unit/provider/service/openrc_spec.rb +209 -0
  113. data/spec/unit/provider/service/windows_spec.rb +57 -59
  114. data/spec/unit/provider/user/useradd_spec.rb +7 -0
  115. data/spec/unit/reports/store_spec.rb +13 -13
  116. data/spec/unit/resource/catalog_spec.rb +29 -24
  117. data/spec/unit/resource_spec.rb +13 -13
  118. data/spec/unit/simple_graph_spec.rb +12 -12
  119. data/spec/unit/ssl/certificate_authority/interface_spec.rb +3 -3
  120. data/spec/unit/ssl/certificate_authority_spec.rb +11 -10
  121. data/spec/unit/transaction_spec.rb +3 -3
  122. data/spec/unit/type/cron_spec.rb +171 -171
  123. data/spec/unit/type/exec_spec.rb +29 -27
  124. data/spec/unit/type/file_spec.rb +22 -13
  125. data/spec/unit/type/interface_spec.rb +1 -1
  126. data/spec/unit/type/scheduled_task_spec.rb +15 -14
  127. data/spec/unit/type/tidy_spec.rb +2 -2
  128. data/spec/unit/type/user_spec.rb +15 -15
  129. data/spec/unit/type/vlan_spec.rb +1 -1
  130. data/spec/unit/type_spec.rb +22 -25
  131. data/spec/unit/util/autoload_spec.rb +13 -7
  132. data/spec/unit/util/backups_spec.rb +36 -67
  133. data/spec/unit/util/storage_spec.rb +2 -9
  134. data/spec/unit/util/suidmanager_spec.rb +1 -1
  135. data/spec/unit/util_spec.rb +20 -28
  136. data/test/ral/manager/attributes.rb +1 -1
  137. metadata +1553 -1542
@@ -1,5 +1,5 @@
1
- Puppet::Parser::Functions::newfunction(:sha1, :type => :rvalue, :doc => "Returns a SHA1 hash value from a provided string.") do |args|
2
- require 'digest/sha1'
1
+ require 'digest/sha1'
3
2
 
3
+ Puppet::Parser::Functions::newfunction(:sha1, :type => :rvalue, :doc => "Returns a SHA1 hash value from a provided string.") do |args|
4
4
  Digest::SHA1.hexdigest(args[0])
5
5
  end
@@ -5,8 +5,6 @@ Puppet::Parser::Functions::newfunction(:template, :type => :rvalue, :doc =>
5
5
 
6
6
  Note that if multiple templates are specified, their output is all
7
7
  concatenated and returned as the output of the function.") do |vals|
8
- require 'erb'
9
-
10
8
  vals.collect do |file|
11
9
  # Use a wrapper, so the template can't get access to the full
12
10
  # Scope object.
@@ -1,3 +1,4 @@
1
+ require 'find'
1
2
  require 'puppet/node/environment'
2
3
 
3
4
  class Puppet::Parser::TypeLoader
@@ -93,8 +94,6 @@ class Puppet::Parser::TypeLoader
93
94
  end
94
95
 
95
96
  def import_all
96
- require 'find'
97
-
98
97
  module_names = []
99
98
  # Collect the list of all known modules
100
99
  environment.modulepath.each do |path|
@@ -147,7 +147,7 @@ Puppet::Type.type(:augeas).provide(:augeas) do
147
147
  flags = Augeas::TYPE_CHECK if resource[:type_check] == :true
148
148
  flags |= Augeas::NO_MODL_AUTOLOAD if resource[:incl]
149
149
  root = resource[:root]
150
- load_path = resource[:load_path]
150
+ load_path = get_load_path(resource)
151
151
  debug("Opening augeas with root #{root}, lens path #{load_path}, flags #{flags}")
152
152
  @aug = Augeas::open(root, load_path,flags)
153
153
 
@@ -253,6 +253,24 @@ Puppet::Type.type(:augeas).provide(:augeas) do
253
253
  !!return_value
254
254
  end
255
255
 
256
+ # Generate lens load paths from user given paths and local pluginsync dir
257
+ def get_load_path(resource)
258
+ load_path = []
259
+
260
+ # Permits colon separated strings or arrays
261
+ if resource[:load_path]
262
+ load_path = [resource[:load_path]].flatten
263
+ load_path.map! { |path| path.split(/:/) }
264
+ load_path.flatten!
265
+ end
266
+
267
+ if File.exists?("#{Puppet[:libdir]}/augeas/lenses")
268
+ load_path << "#{Puppet[:libdir]}/augeas/lenses"
269
+ end
270
+
271
+ load_path.join(":")
272
+ end
273
+
256
274
  def get_augeas_version
257
275
  @aug.get("/augeas/version") || ""
258
276
  end
@@ -25,7 +25,7 @@ class Puppet::Provider::Confine
25
25
  begin
26
26
  require "puppet/provider/confine/#{name}"
27
27
  rescue LoadError => detail
28
- unless detail.to_s =~ /No such file/i
28
+ unless detail.to_s =~ /No such file|cannot load such file/i
29
29
  warn "Could not load confine test '#{name}': #{detail}"
30
30
  end
31
31
  # Could not find file
@@ -4,89 +4,135 @@ Puppet::Type.type(:package).provide(:msi, :parent => Puppet::Provider::Package)
4
4
  desc "Windows package management by installing and removing MSIs.
5
5
 
6
6
  This provider requires a `source` attribute, and will accept paths to local
7
- files or files on mapped drives.
8
-
9
- This provider cannot uninstall arbitrary MSI packages; it can only uninstall
10
- packages which were originally installed by Puppet."
7
+ files, mapped drives, or UNC paths."
11
8
 
12
9
  confine :operatingsystem => :windows
13
10
  defaultfor :operatingsystem => :windows
14
11
 
12
+ has_feature :installable
13
+ has_feature :uninstallable
15
14
  has_feature :install_options
16
15
 
17
- # This is just here to make sure we can find it, and fail if we
18
- # can't. Unfortunately, we need to do "special" quoting of the
19
- # install options or msiexec.exe won't know what to do with them, if
20
- # the value contains a space.
21
- commands :msiexec => "msiexec.exe"
16
+ class MsiPackage
17
+ extend Enumerable
22
18
 
23
- def self.instances
24
- Dir.entries(installed_listing_dir).reject {|d| d == '.' or d == '..'}.collect do |name|
25
- new(:name => File.basename(name, '.yml'), :provider => :msi, :ensure => :installed)
19
+ # From msi.h
20
+ INSTALLSTATE_DEFAULT = 5 # product is installed for the current user
21
+ INSTALLUILEVEL_NONE = 2 # completely silent installation
22
+
23
+ def self.installer
24
+ require 'win32ole'
25
+ WIN32OLE.new("WindowsInstaller.Installer")
26
+ end
27
+
28
+ def self.each(&block)
29
+ inst = installer
30
+ inst.UILevel = INSTALLUILEVEL_NONE
31
+
32
+ inst.Products.each do |guid|
33
+ # products may be advertised, installed in a different user
34
+ # context, etc, we only want to know about products currently
35
+ # installed in our context.
36
+ next unless inst.ProductState(guid) == INSTALLSTATE_DEFAULT
37
+
38
+ package = {
39
+ :name => inst.ProductInfo(guid, 'ProductName'),
40
+ # although packages have a version, the provider isn't versionable,
41
+ # so we can't return a version
42
+ # :ensure => inst.ProductInfo(guid, 'VersionString'),
43
+ :ensure => :installed,
44
+ :provider => :msi,
45
+ :productcode => guid,
46
+ :packagecode => inst.ProductInfo(guid, 'PackageCode')
47
+ }
48
+
49
+ yield package
50
+ end
26
51
  end
27
52
  end
28
53
 
54
+ # Get an array of provider instances for currently installed packages
55
+ def self.instances
56
+ MsiPackage.enum_for.map { |package| new(package) }
57
+ end
58
+
59
+ # Find first package whose PackageCode, e.g. {B2BE95D2-CD2C-46D6-8D27-35D150E58EC9},
60
+ # matches the resource name (case-insensitively due to hex) or the ProductName matches
61
+ # the resource name. The ProductName is not guaranteed to be unique, but the PackageCode
62
+ # should be if the package is authored correctly.
29
63
  def query
30
- {:name => resource[:name], :ensure => :installed} if FileTest.exists?(state_file)
64
+ MsiPackage.enum_for.find do |package|
65
+ resource[:name].casecmp(package[:packagecode]) == 0 || resource[:name] == package[:name]
66
+ end
31
67
  end
32
68
 
33
69
  def install
34
- properties_for_command = nil
35
- if resource[:install_options]
36
- properties_for_command = resource[:install_options].collect do |k,v|
37
- property = shell_quote k
38
- value = shell_quote v
39
-
40
- "#{property}=#{value}"
41
- end
42
- end
70
+ fail("The source parameter is required when using the MSI provider.") unless resource[:source]
43
71
 
44
72
  # Unfortunately, we can't use the msiexec method defined earlier,
45
73
  # because of the special quoting we need to do around the MSI
46
74
  # properties to use.
47
- execute ['msiexec.exe', '/qn', '/norestart', '/i', shell_quote(msi_source), properties_for_command].flatten.compact.join(' ')
48
-
49
- File.open(state_file, 'w') do |f|
50
- metadata = {
51
- 'name' => resource[:name],
52
- 'install_options' => resource[:install_options],
53
- 'source' => msi_source
54
- }
75
+ command = ['msiexec.exe', '/qn', '/norestart', '/i', shell_quote(resource[:source]), install_options].flatten.compact.join(' ')
76
+ execute(command, :combine => true)
55
77
 
56
- f.puts(YAML.dump(metadata))
57
- end
78
+ check_result(exit_status)
58
79
  end
59
80
 
60
81
  def uninstall
61
- msiexec '/qn', '/norestart', '/x', msi_source
82
+ fail("The productcode property is missing.") unless properties[:productcode]
62
83
 
63
- File.delete state_file
64
- end
84
+ command = ['msiexec.exe', '/qn', '/norestart', '/x', properties[:productcode]].flatten.compact.join(' ')
85
+ execute(command, :combine => true)
65
86
 
66
- def validate_source(value)
67
- fail("The source parameter cannot be empty when using the MSI provider.") if value.empty?
87
+ check_result(exit_status)
68
88
  end
69
89
 
70
- private
71
-
72
- def msi_source
73
- resource[:source] ||= YAML.load_file(state_file)['source'] rescue nil
74
-
75
- fail("The source parameter is required when using the MSI provider.") unless resource[:source]
90
+ def exit_status
91
+ $CHILD_STATUS.exitstatus
92
+ end
76
93
 
77
- resource[:source]
94
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa368542(v=vs.85).aspx
95
+ ERROR_SUCCESS = 0
96
+ ERROR_SUCCESS_REBOOT_INITIATED = 1641
97
+ ERROR_SUCCESS_REBOOT_REQUIRED = 3010
98
+
99
+ # (Un)install may "fail" because the package requested a reboot, the system requested a
100
+ # reboot, or something else entirely. Reboot requests mean the package was installed
101
+ # successfully, but we warn since we don't have a good reboot strategy.
102
+ def check_result(hr)
103
+ operation = resource[:ensure] == :absent ? 'uninstall' : 'install'
104
+
105
+ case hr
106
+ when ERROR_SUCCESS
107
+ # yeah
108
+ when 194
109
+ warning("The package requested a reboot to finish the operation.")
110
+ when ERROR_SUCCESS_REBOOT_INITIATED
111
+ warning("The package #{operation}ed successfully and the system is rebooting now.")
112
+ when ERROR_SUCCESS_REBOOT_REQUIRED
113
+ warning("The package #{operation}ed successfully, but the system must be rebooted.")
114
+ else
115
+ raise Puppet::Util::Windows::Error.new("Failed to #{operation}", hr)
116
+ end
78
117
  end
79
118
 
80
- def self.installed_listing_dir
81
- listing_dir = File.join(Puppet[:vardir], 'db', 'package', 'msi')
119
+ def validate_source(value)
120
+ fail("The source parameter cannot be empty when using the MSI provider.") if value.empty?
121
+ end
82
122
 
83
- FileUtils.mkdir_p listing_dir unless File.directory? listing_dir
123
+ def install_options
124
+ # properties is a string delimited by spaces, so each key value must be quoted
125
+ properties_for_command = nil
126
+ if resource[:install_options]
127
+ properties_for_command = resource[:install_options].collect do |k,v|
128
+ property = shell_quote k
129
+ value = shell_quote v
84
130
 
85
- listing_dir
86
- end
131
+ "#{property}=#{value}"
132
+ end
133
+ end
87
134
 
88
- def state_file
89
- File.join(self.class.installed_listing_dir, "#{resource[:name]}.yml")
135
+ properties_for_command
90
136
  end
91
137
 
92
138
  def shell_quote(value)
@@ -232,6 +232,7 @@ Puppet::Type.type(:scheduled_task).provide(:win32_taskscheduler) do
232
232
  unless resource[:ensure] == :absent
233
233
  self.fail('Parameter command is required.') unless resource[:command]
234
234
  task.save
235
+ @task = nil
235
236
  end
236
237
  end
237
238
 
@@ -12,8 +12,6 @@ Puppet::Type.type(:service).provide :gentoo, :parent => :init do
12
12
 
13
13
  confine :operatingsystem => :gentoo
14
14
 
15
- defaultfor :operatingsystem => :gentoo
16
-
17
15
  def self.defpath
18
16
  superclass.defpath
19
17
  end
@@ -0,0 +1,69 @@
1
+ # Gentoo OpenRC
2
+ Puppet::Type.type(:service).provide :openrc, :parent => :base do
3
+ desc <<-EOT
4
+ Support for Gentoo's OpenRC initskripts
5
+
6
+ Uses rc-update, rc-status and rc-service to manage services.
7
+
8
+ EOT
9
+
10
+ defaultfor :operatingsystem => :gentoo
11
+ defaultfor :operatingsystem => :funtoo
12
+
13
+ commands :rcservice => '/sbin/rc-service'
14
+ commands :rcstatus => '/bin/rc-status'
15
+ commands :rcupdate => '/sbin/rc-update'
16
+
17
+ self::STATUSLINE = /^\s+(.*?)\s*\[\s*(.*)\s*\]$/
18
+
19
+ def enable
20
+ rcupdate('-C', :add, @resource[:name])
21
+ end
22
+
23
+ def disable
24
+ rcupdate('-C', :del, @resource[:name])
25
+ end
26
+
27
+ # rc-status -a shows all runlevels and dynamic runlevels which
28
+ # are not considered as enabled. We have to find out under which
29
+ # runlevel our service is listed
30
+ def enabled?
31
+ enabled = :false
32
+ rcstatus('-C', '-a').each_line do |line|
33
+ case line.chomp
34
+ when /^Runlevel: /
35
+ enabled = :true
36
+ when /^\S+/ # caption of a dynamic runlevel
37
+ enabled = :false
38
+ when self.class::STATUSLINE
39
+ return enabled if @resource[:name] == $1
40
+ end
41
+ end
42
+ :false
43
+ end
44
+
45
+ def self.instances
46
+ instances = []
47
+ rcservice('-C', '--list').each_line do |line|
48
+ instances << new(:name => line.chomp)
49
+ end
50
+ instances
51
+ end
52
+
53
+ def restartcmd
54
+ (@resource[:hasrestart] == :true) && [command(:rcservice), @resource[:name], :restart]
55
+ end
56
+
57
+ def startcmd
58
+ [command(:rcservice), @resource[:name], :start ]
59
+ end
60
+
61
+ def stopcmd
62
+ [command(:rcservice), @resource[:name], :stop]
63
+ end
64
+
65
+ def statuscmd
66
+ ((@resource.provider.get(:hasstatus) == true) || (@resource[:hasstatus] == :true)) && [command(:rcservice), @resource[:name], :status]
67
+ end
68
+
69
+ end
@@ -18,6 +18,8 @@ Puppet::Type.type(:service).provide :windows do
18
18
 
19
19
  has_feature :refreshable
20
20
 
21
+ commands :net => 'net.exe'
22
+
21
23
  def enable
22
24
  w32ss = Win32::Service.configure( 'service_name' => @resource[:name], 'start_type' => Win32::Service::SERVICE_AUTO_START )
23
25
  raise Puppet::Error.new("Win32 service enable of #{@resource[:name]} failed" ) if( w32ss.nil? )
@@ -73,14 +75,14 @@ Puppet::Type.type(:service).provide :windows do
73
75
  end
74
76
  end
75
77
 
76
- Win32::Service.start( @resource[:name] )
77
- rescue Win32::Service::Error => detail
78
+ net(:start, @resource[:name])
79
+ rescue Puppet::ExecutionFailure => detail
78
80
  raise Puppet::Error.new("Cannot start #{@resource[:name]}, error was: #{detail}" )
79
81
  end
80
82
 
81
83
  def stop
82
- Win32::Service.stop( @resource[:name] )
83
- rescue Win32::Service::Error => detail
84
+ net(:stop, @resource[:name])
85
+ rescue Puppet::ExecutionFailure => detail
84
86
  raise Puppet::Error.new("Cannot stop #{@resource[:name]}, error was: #{detail}" )
85
87
  end
86
88
 
@@ -253,12 +253,16 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
253
253
  tmpfile.close()
254
254
 
255
255
  # Options '-e', '-c', use encrypted password and clear flags
256
- # Must receibe "user:enc_password" as input
256
+ # Must receive "user:enc_password" as input
257
257
  # command, arguments = {:failonfail => true, :combine => true}
258
- cmd = [self.class.command(:chpasswd),"-R", self.class.ia_module,
259
- '-e', '-c', user]
258
+ # Fix for bugs #11200 and #10915
259
+ cmd = [self.class.command(:chpasswd), get_ia_module_args, '-e', '-c', user].flatten
260
260
  begin
261
- execute(cmd, {:failonfail => true, :combine => true, :stdinfile => tmpfile.path })
261
+ output = execute(cmd, {:failonfail => false, :combine => true, :stdinfile => tmpfile.path })
262
+ # chpasswd can return 1, even on success (at least on AIX 6.1); empty output indicates success
263
+ if output != ""
264
+ raise Puppet::ExecutionFailure, "chpasswd said #{output}"
265
+ end
262
266
  rescue Puppet::ExecutionFailure => detail
263
267
  raise Puppet::Error, "Could not set #{param} on #{@resource.class.name}[#{@resource.name}]: #{detail}"
264
268
  ensure
@@ -75,6 +75,12 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
75
75
  cmd += check_system_users
76
76
  cmd << @resource[:name]
77
77
  end
78
+
79
+ def deletecmd
80
+ cmd = [command(:delete)]
81
+ cmd += @resource.managehome? ? ['-r'] : []
82
+ cmd << @resource[:name]
83
+ end
78
84
 
79
85
  def passcmd
80
86
  age_limits = [:password_min_age, :password_max_age].select { |property| @resource.should(property) }
@@ -1,4 +1,6 @@
1
1
  require 'benchmark'
2
+ require 'yaml'
3
+
2
4
  module Puppet::Rails::Benchmark
3
5
  $benchmarks = {:accumulated => {}}
4
6
 
@@ -50,8 +52,6 @@ module Puppet::Rails::Benchmark
50
52
 
51
53
  file = "/tmp/time_debugging.yaml"
52
54
 
53
- require 'yaml'
54
-
55
55
  if FileTest.exist?(file)
56
56
  data = YAML.load_file(file)
57
57
  else
@@ -13,11 +13,7 @@ Puppet::Reports.register_report(:store) do
13
13
  default report)."
14
14
 
15
15
  def process
16
- # We don't want any tracking back in the fs. Unlikely, but there
17
- # you go.
18
- if host =~ Regexp.union(/[#{SEPARATOR}]/, /\A\.\.?\Z/)
19
- raise ArgumentError, "Invalid node name #{host.inspect}"
20
- end
16
+ validate_host(host)
21
17
 
22
18
  dir = File.join(Puppet[:reportdir], host)
23
19
 
@@ -55,9 +51,7 @@ Puppet::Reports.register_report(:store) do
55
51
 
56
52
  # removes all reports for a given host?
57
53
  def self.destroy(host)
58
- if host =~ Regexp.union(/[#{SEPARATOR}]/, /\A\.\.?\Z/)
59
- raise ArgumentError, "Invalid node name #{host.inspect}"
60
- end
54
+ validate_host(host)
61
55
 
62
56
  dir = File.join(Puppet[:reportdir], host)
63
57
 
@@ -70,5 +64,11 @@ Puppet::Reports.register_report(:store) do
70
64
  Dir.rmdir(dir)
71
65
  end
72
66
  end
73
- end
74
67
 
68
+ def validate_host(host)
69
+ if host =~ Regexp.union(/[#{SEPARATOR}]/, /\A\.\.?\Z/)
70
+ raise ArgumentError, "Invalid node name #{host.inspect}"
71
+ end
72
+ end
73
+ module_function :validate_host
74
+ end