puppet 2.7.14 → 2.7.16

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 (111) hide show
  1. data/CHANGELOG +85 -0
  2. data/conf/redhat/puppet.spec +31 -4
  3. data/lib/puppet.rb +1 -1
  4. data/lib/puppet/defaults.rb +2 -3
  5. data/lib/puppet/face/module/install.rb +3 -3
  6. data/lib/puppet/face/module/search.rb +3 -3
  7. data/lib/puppet/indirector/face.rb +1 -1
  8. data/lib/puppet/network/http_pool.rb +17 -8
  9. data/lib/puppet/node/environment.rb +1 -3
  10. data/lib/puppet/parser/ast.rb +1 -1
  11. data/lib/puppet/parser/compiler.rb +2 -10
  12. data/lib/puppet/parser/functions/template.rb +2 -1
  13. data/lib/puppet/parser/lexer.rb +2 -2
  14. data/lib/puppet/parser/scope.rb +3 -2
  15. data/lib/puppet/provider/package/gem.rb +3 -1
  16. data/lib/puppet/provider/package/pkg.rb +18 -2
  17. data/lib/puppet/provider/service/gentoo.rb +5 -0
  18. data/lib/puppet/provider/service/init.rb +12 -14
  19. data/lib/puppet/provider/service/redhat.rb +1 -1
  20. data/lib/puppet/provider/service/upstart.rb +257 -7
  21. data/lib/puppet/provider/ssh_authorized_key/parsed.rb +6 -9
  22. data/lib/puppet/reports/http.rb +1 -1
  23. data/lib/puppet/reports/tagmail.rb +1 -1
  24. data/lib/puppet/type/cron.rb +5 -0
  25. data/lib/puppet/type/filebucket.rb +12 -0
  26. data/lib/puppet/util.rb +15 -9
  27. data/lib/puppet/util/colors.rb +94 -64
  28. data/lib/puppet/util/platform.rb +15 -0
  29. data/man/man5/puppet.conf.5 +73 -27
  30. data/man/man8/filebucket.8 +1 -1
  31. data/man/man8/pi.8 +1 -1
  32. data/man/man8/puppet-agent.8 +17 -17
  33. data/man/man8/puppet-apply.8 +8 -3
  34. data/man/man8/puppet-ca.8 +183 -0
  35. data/man/man8/puppet-catalog.8 +17 -10
  36. data/man/man8/puppet-cert.8 +1 -1
  37. data/man/man8/puppet-certificate.8 +27 -11
  38. data/man/man8/puppet-certificate_request.8 +12 -11
  39. data/man/man8/puppet-certificate_revocation_list.8 +11 -10
  40. data/man/man8/puppet-config.8 +1 -1
  41. data/man/man8/puppet-describe.8 +1 -1
  42. data/man/man8/puppet-device.8 +2 -2
  43. data/man/man8/puppet-doc.8 +15 -3
  44. data/man/man8/puppet-facts.8 +18 -8
  45. data/man/man8/puppet-file.8 +13 -22
  46. data/man/man8/puppet-filebucket.8 +1 -1
  47. data/man/man8/puppet-help.8 +1 -1
  48. data/man/man8/puppet-inspect.8 +10 -2
  49. data/man/man8/puppet-instrumentation_data.8 +145 -0
  50. data/man/man8/puppet-instrumentation_listener.8 +222 -0
  51. data/man/man8/puppet-instrumentation_probe.8 +207 -0
  52. data/man/man8/puppet-key.8 +11 -7
  53. data/man/man8/puppet-kick.8 +35 -3
  54. data/man/man8/puppet-man.8 +1 -1
  55. data/man/man8/puppet-master.8 +1 -1
  56. data/man/man8/puppet-module.8 +451 -0
  57. data/man/man8/puppet-node.8 +64 -22
  58. data/man/man8/puppet-parser.8 +1 -1
  59. data/man/man8/puppet-plugin.8 +1 -1
  60. data/man/man8/puppet-queue.8 +1 -1
  61. data/man/man8/puppet-report.8 +12 -8
  62. data/man/man8/puppet-resource.8 +1 -1
  63. data/man/man8/puppet-resource_type.8 +11 -7
  64. data/man/man8/puppet-secret_agent.8 +1 -1
  65. data/man/man8/puppet-status.8 +11 -7
  66. data/man/man8/puppet.8 +1 -1
  67. data/man/man8/puppetca.8 +1 -1
  68. data/man/man8/puppetd.8 +17 -17
  69. data/man/man8/puppetdoc.8 +15 -3
  70. data/man/man8/puppetmasterd.8 +1 -1
  71. data/man/man8/puppetqd.8 +1 -1
  72. data/man/man8/puppetrun.8 +35 -3
  73. data/man/man8/ralsh.8 +1 -1
  74. data/spec/fixtures/unit/provider/package/gem/line-with-1.8.5-warning +14 -0
  75. data/spec/fixtures/unit/provider/package/pkg/{dummy → dummy_solaris10} +0 -0
  76. data/spec/fixtures/unit/provider/package/pkg/dummy_solaris11 +1 -0
  77. data/spec/fixtures/unit/provider/package/pkg/solaris11 +12 -0
  78. data/spec/fixtures/unit/provider/package/pkg/unknown_status +12 -0
  79. data/spec/fixtures/unit/provider/service/gentoo/rc_update_show +30 -0
  80. data/spec/integration/defaults_spec.rb +2 -7
  81. data/spec/integration/network/server/mongrel_spec.rb +16 -10
  82. data/spec/integration/network/server/webrick_spec.rb +16 -9
  83. data/spec/integration/provider/service/init_spec.rb +20 -4
  84. data/spec/integration/provider/ssh_authorized_key_spec.rb +119 -107
  85. data/spec/unit/face/module/install_spec.rb +16 -4
  86. data/spec/unit/network/http/api/v1_spec.rb +8 -0
  87. data/spec/unit/network/http_pool_spec.rb +80 -74
  88. data/spec/unit/node/environment_spec.rb +9 -4
  89. data/spec/unit/parser/ast/leaf_spec.rb +2 -2
  90. data/spec/unit/parser/ast_spec.rb +3 -3
  91. data/spec/unit/parser/compiler_spec.rb +0 -17
  92. data/spec/unit/parser/lexer_spec.rb +45 -2
  93. data/spec/unit/parser/scope_spec.rb +181 -14
  94. data/spec/unit/provider/package/gem_spec.rb +17 -1
  95. data/spec/unit/provider/package/pkg_spec.rb +70 -22
  96. data/spec/unit/provider/service/gentoo_spec.rb +237 -0
  97. data/spec/unit/provider/service/init_spec.rb +2 -2
  98. data/spec/unit/provider/service/redhat_spec.rb +2 -2
  99. data/spec/unit/provider/service/upstart_spec.rb +414 -5
  100. data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +24 -0
  101. data/spec/unit/reports/tagmail_spec.rb +50 -0
  102. data/spec/unit/type/cron_spec.rb +21 -1
  103. data/spec/unit/type/filebucket_spec.rb +39 -9
  104. data/spec/unit/util/colors_spec.rb +69 -0
  105. data/spec/unit/util/log/destinations_spec.rb +17 -9
  106. data/spec/unit/util/log_spec.rb +2 -1
  107. data/spec/unit/util_spec.rb +11 -0
  108. data/tasks/rake/gem.rake +1 -1
  109. data/tasks/rake/manpages.rake +11 -3
  110. data/test/network/handler/fileserver.rb +7 -1
  111. metadata +22 -10
@@ -18,6 +18,11 @@ Puppet::Type.type(:service).provide :gentoo, :parent => :init do
18
18
  superclass.defpath
19
19
  end
20
20
 
21
+ def self.instances
22
+ # this exclude list was found with grep -L '\/sbin\/runscript' /etc/init.d/*
23
+ self.get_services(self.defpath, ['functions.sh', 'reboot.sh', 'shutdown.sh'])
24
+ end
25
+
21
26
  def disable
22
27
  output = update :del, @resource[:name], :default
23
28
  rescue Puppet::ExecutionFailure
@@ -3,23 +3,21 @@
3
3
  Puppet::Type.type(:service).provide :init, :parent => :base do
4
4
  desc "Standard `init`-style service management."
5
5
 
6
- class << self
7
- attr_accessor :defpath
8
- end
9
-
10
- case Facter["operatingsystem"].value
11
- when "FreeBSD"
12
- @defpath = ["/etc/rc.d", "/usr/local/etc/rc.d"]
13
- when "HP-UX"
14
- @defpath = "/sbin/init.d"
15
- when "Archlinux"
16
- @defpath = "/etc/rc.d"
17
- else
18
- @defpath = "/etc/init.d"
6
+ def self.defpath
7
+ case Facter.value(:operatingsystem)
8
+ when "FreeBSD"
9
+ ["/etc/rc.d", "/usr/local/etc/rc.d"]
10
+ when "HP-UX"
11
+ "/sbin/init.d"
12
+ when "Archlinux"
13
+ "/etc/rc.d"
14
+ else
15
+ "/etc/init.d"
16
+ end
19
17
  end
20
18
 
21
19
  # We can't confine this here, because the init path can be overridden.
22
- #confine :exists => @defpath
20
+ #confine :exists => defpath
23
21
 
24
22
  # List all services of this type.
25
23
  def self.instances
@@ -12,7 +12,7 @@ Puppet::Type.type(:service).provide :redhat, :parent => :init, :source => :init
12
12
 
13
13
  def self.instances
14
14
  # this exclude list is all from /sbin/service (5.x), but I did not exclude kudzu
15
- self.get_services(['/etc/init.d'], ['functions', 'halt', 'killall', 'single', 'linuxconf'])
15
+ self.get_services(['/etc/init.d'], ['functions', 'halt', 'killall', 'single', 'linuxconf', 'reboot', 'boot'])
16
16
  end
17
17
 
18
18
  def self.defpath
@@ -1,4 +1,10 @@
1
+ require 'semver'
2
+
1
3
  Puppet::Type.type(:service).provide :upstart, :parent => :debian do
4
+ START_ON = /^\s*start\s+on/
5
+ COMMENTED_START_ON = /^\s*#+\s*start\s+on/
6
+ MANUAL = /^\s*manual\s*$/
7
+
2
8
  desc "Ubuntu service management with `upstart`.
3
9
 
4
10
  This provider manages `upstart` jobs, which have replaced `initd` services
@@ -6,7 +12,7 @@ Puppet::Type.type(:service).provide :upstart, :parent => :debian do
6
12
  "
7
13
  # confine to :ubuntu for now because I haven't tested on other platforms
8
14
  confine :operatingsystem => :ubuntu #[:ubuntu, :fedora, :debian]
9
-
15
+
10
16
  defaultfor :operatingsystem => :ubuntu
11
17
 
12
18
  commands :start => "/sbin/start",
@@ -17,7 +23,7 @@ Puppet::Type.type(:service).provide :upstart, :parent => :debian do
17
23
 
18
24
  # upstart developer haven't implemented initctl enable/disable yet:
19
25
  # http://www.linuxplanet.com/linuxplanet/tutorials/7033/2/
20
- # has_feature :enableable
26
+ has_feature :enableable
21
27
 
22
28
  def self.instances
23
29
  instances = []
@@ -40,6 +46,72 @@ Puppet::Type.type(:service).provide :upstart, :parent => :debian do
40
46
  instances
41
47
  end
42
48
 
49
+ def self.defpath
50
+ ["/etc/init", "/etc/init.d"]
51
+ end
52
+
53
+ def upstart_version
54
+ @@upstart_version ||= SemVer.new(initctl(" --version").match(/initctl \(upstart (\d\.\d[\.\d]?)\)/)[1])
55
+ end
56
+
57
+ # Where is our override script?
58
+ def overscript
59
+ @overscript ||= initscript.gsub(/\.conf$/,".override")
60
+ end
61
+
62
+ def search(name)
63
+ # Search prefers .conf as that is what upstart uses
64
+ [".conf", "", ".sh"].each do |suffix|
65
+ paths.each do |path|
66
+ fqname = File.join(path,name+suffix)
67
+ if File.exists?(fqname)
68
+ return fqname
69
+ end
70
+
71
+ self.debug("Could not find #{name}#{suffix} in #{path}")
72
+ end
73
+ end
74
+
75
+ raise Puppet::Error, "Could not find init script or upstart conf file for '#{name}'"
76
+ end
77
+
78
+ def enabled?
79
+ return super if not is_upstart?
80
+
81
+ script_contents = read_script_from(initscript)
82
+ if upstart_version < "0.6.7"
83
+ enabled_pre_0_6_7?(script_contents)
84
+ elsif upstart_version < "0.9.0"
85
+ enabled_pre_0_9_0?(script_contents)
86
+ elsif upstart_version >= "0.9.0"
87
+ enabled_post_0_9_0?(script_contents, read_override_file)
88
+ end
89
+ end
90
+
91
+ def enable
92
+ return super if not is_upstart?
93
+
94
+ script_text = read_script_from(initscript)
95
+ if upstart_version < "0.9.0"
96
+ enable_pre_0_9_0(script_text)
97
+ else
98
+ enable_post_0_9_0(script_text, read_override_file)
99
+ end
100
+ end
101
+
102
+ def disable
103
+ return super if not is_upstart?
104
+
105
+ script_text = read_script_from(initscript)
106
+ if upstart_version < "0.6.7"
107
+ disable_pre_0_6_7(script_text)
108
+ elsif upstart_version < "0.9.0"
109
+ disable_pre_0_9_0(script_text)
110
+ elsif upstart_version >= "0.9.0"
111
+ disable_post_0_9_0(read_override_file)
112
+ end
113
+ end
114
+
43
115
  def startcmd
44
116
  is_upstart? ? [command(:start), @resource[:name]] : super
45
117
  end
@@ -55,7 +127,7 @@ Puppet::Type.type(:service).provide :upstart, :parent => :debian do
55
127
  def statuscmd
56
128
  is_upstart? ? nil : super #this is because upstart is broken with its return codes
57
129
  end
58
-
130
+
59
131
  def status
60
132
  if @resource[:status]
61
133
  is_upstart?(@resource[:status]) ? upstart_status(@resource[:status]) : normal_status
@@ -65,12 +137,12 @@ Puppet::Type.type(:service).provide :upstart, :parent => :debian do
65
137
  super
66
138
  end
67
139
  end
68
-
140
+
69
141
  def normal_status
70
142
  ucommand(:status, false)
71
143
  ($?.exitstatus == 0) ? :running : :stopped
72
144
  end
73
-
145
+
74
146
  def upstart_status(exec = @resource[:name])
75
147
  output = status_exec(@resource[:name].split)
76
148
  if (! $?.nil?) && (output =~ /start\//)
@@ -79,9 +151,187 @@ Puppet::Type.type(:service).provide :upstart, :parent => :debian do
79
151
  return :stopped
80
152
  end
81
153
  end
82
-
154
+
83
155
  def is_upstart?(script = initscript)
84
- File.symlink?(script) && File.readlink(script) == "/lib/init/upstart-job"
156
+ return true if (File.symlink?(script) && File.readlink(script) == "/lib/init/upstart-job")
157
+ return true if (File.file?(script) && (not script.include?("init.d")))
158
+ return false
159
+ end
160
+
161
+ private
162
+
163
+ def enabled_pre_0_6_7?(script_text)
164
+ # Upstart version < 0.6.7 means no manual stanza.
165
+ if script_text.match(START_ON)
166
+ return :true
167
+ else
168
+ return :false
169
+ end
170
+ end
171
+
172
+ def enabled_pre_0_9_0?(script_text)
173
+ # Upstart version < 0.9.0 means no override files
174
+ # So we check to see if an uncommented start on or manual stanza is the last one in the file
175
+ # The last one in the file wins.
176
+ enabled = :false
177
+ script_text.each do |line|
178
+ if line.match(START_ON)
179
+ enabled = :true
180
+ elsif line.match(MANUAL)
181
+ enabled = :false
182
+ end
183
+ end
184
+ enabled
85
185
  end
86
186
 
187
+ def enabled_post_0_9_0?(script_text, over_text)
188
+ # This version has manual stanzas and override files
189
+ # So we check to see if an uncommented start on or manual stanza is the last one in the
190
+ # conf file and any override files. The last one in the file wins.
191
+ enabled = :false
192
+
193
+ script_text.each do |line|
194
+ if line.match(START_ON)
195
+ enabled = :true
196
+ elsif line.match(MANUAL)
197
+ enabled = :false
198
+ end
199
+ end
200
+ over_text.each do |line|
201
+ if line.match(START_ON)
202
+ enabled = :true
203
+ elsif line.match(MANUAL)
204
+ enabled = :false
205
+ end
206
+ end if over_text
207
+ enabled
208
+ end
209
+
210
+ def enable_pre_0_9_0(text)
211
+ # We also need to remove any manual stanzas to ensure that it is enabled
212
+ text = remove_manual_from(text)
213
+
214
+ if enabled_pre_0_9_0?(text) == :false
215
+ enabled_script =
216
+ if text.match(COMMENTED_START_ON)
217
+ uncomment_start_block_in(text)
218
+ else
219
+ add_default_start_to(text)
220
+ end
221
+ else
222
+ enabled_script = text
223
+ end
224
+
225
+ write_script_to(initscript, enabled_script)
226
+ end
227
+
228
+ def enable_post_0_9_0(script_text, over_text)
229
+ over_text = remove_manual_from(over_text)
230
+
231
+ if enabled_post_0_9_0?(script_text, over_text) == :false
232
+ if script_text.match(START_ON)
233
+ over_text << extract_start_on_block_from(script_text)
234
+ else
235
+ over_text << "\nstart on runlevel [2,3,4,5]"
236
+ end
237
+ end
238
+
239
+ write_script_to(overscript, over_text)
240
+ end
241
+
242
+ def disable_pre_0_6_7(script_text)
243
+ disabled_script = comment_start_block_in(script_text)
244
+ write_script_to(initscript, disabled_script)
245
+ end
246
+
247
+ def disable_pre_0_9_0(script_text)
248
+ write_script_to(initscript, ensure_disabled_with_manual(script_text))
249
+ end
250
+
251
+ def disable_post_0_9_0(over_text)
252
+ write_script_to(overscript, ensure_disabled_with_manual(over_text))
253
+ end
254
+
255
+ def read_override_file
256
+ if File.exists?(overscript)
257
+ read_script_from(overscript)
258
+ else
259
+ ""
260
+ end
261
+ end
262
+
263
+ def uncomment(line)
264
+ line.gsub(/^(\s*)#+/, '\1')
265
+ end
266
+
267
+ def remove_trailing_comments_from_commented_line_of(line)
268
+ line.gsub(/^(\s*#+\s*[^#]*).*/, '\1')
269
+ end
270
+
271
+ def remove_trailing_comments_from(line)
272
+ line.gsub(/^(\s*[^#]*).*/, '\1')
273
+ end
274
+
275
+ def unbalanced_parens_on(line)
276
+ line.count('(') - line.count(')')
277
+ end
278
+
279
+ def remove_manual_from(text)
280
+ text.gsub(MANUAL, "")
281
+ end
282
+
283
+ def comment_start_block_in(text)
284
+ parens = 0
285
+ text.map do |line|
286
+ if line.match(START_ON) || parens > 0
287
+ # If there are more opening parens than closing parens, we need to comment out a multiline 'start on' stanza
288
+ parens += unbalanced_parens_on(remove_trailing_comments_from(line))
289
+ "#" + line
290
+ else
291
+ line
292
+ end
293
+ end.join('')
294
+ end
295
+
296
+ def uncomment_start_block_in(text)
297
+ parens = 0
298
+ text.map do |line|
299
+ if line.match(COMMENTED_START_ON) || parens > 0
300
+ parens += unbalanced_parens_on(remove_trailing_comments_from_commented_line_of(line))
301
+ uncomment(line)
302
+ else
303
+ line
304
+ end
305
+ end.join('')
306
+ end
307
+
308
+ def extract_start_on_block_from(text)
309
+ parens = 0
310
+ text.map do |line|
311
+ if line.match(START_ON) || parens > 0
312
+ parens += unbalanced_parens_on(remove_trailing_comments_from(line))
313
+ line
314
+ end
315
+ end.join('')
316
+ end
317
+
318
+ def add_default_start_to(text)
319
+ text + "\nstart on runlevel [2,3,4,5]"
320
+ end
321
+
322
+ def ensure_disabled_with_manual(text)
323
+ remove_manual_from(text) + "\nmanual"
324
+ end
325
+
326
+ def read_script_from(filename)
327
+ File.open(filename) do |file|
328
+ file.read
329
+ end
330
+ end
331
+
332
+ def write_script_to(file, text)
333
+ Puppet::Util.replace_file(file, 0644) do |file|
334
+ file.write(text)
335
+ end
336
+ end
87
337
  end
@@ -1,17 +1,14 @@
1
1
  require 'puppet/provider/parsedfile'
2
-
3
-
4
- Puppet::Type.type(:ssh_authorized_key).provide(
5
- :parsed,
6
- :parent => Puppet::Provider::ParsedFile,
7
- :filetype => :flat,
8
-
2
+ Puppet::Type.type(:ssh_authorized_key).provide(
3
+ :parsed,
4
+ :parent => Puppet::Provider::ParsedFile,
5
+ :filetype => :flat,
9
6
  :default_target => ''
10
7
  ) do
11
8
  desc "Parse and generate authorized_keys files for SSH."
12
9
 
13
- text_line :comment, :match => /^#/
14
- text_line :blank, :match => /^\s+/
10
+ text_line :comment, :match => /^\s*#/
11
+ text_line :blank, :match => /^\s*$/
15
12
 
16
13
  record_line :parsed,
17
14
  :fields => %w{options type key name},
@@ -7,7 +7,7 @@ Puppet::Reports.register_report(:http) do
7
7
  desc <<-DESC
8
8
  Send report information via HTTP to the `reporturl`. Each host sends
9
9
  its report as a YAML dump and this sends this YAML to a client via HTTP POST.
10
- The YAML is the `report` parameter of the request."
10
+ The YAML is the body of the request.
11
11
  DESC
12
12
 
13
13
  def process
@@ -125,7 +125,7 @@ Puppet::Reports.register_report(:tagmail) do
125
125
  # Now find any appropriately tagged messages.
126
126
  reports = match(taglists)
127
127
 
128
- send(reports)
128
+ send(reports) unless reports.empty?
129
129
  end
130
130
 
131
131
  # Send the email reports.
@@ -358,6 +358,11 @@ Puppet::Type.newtype(:cron) do
358
358
  }
359
359
  end
360
360
 
361
+ # Autorequire the owner of the crontab entry.
362
+ autorequire(:user) do
363
+ self[:user]
364
+ end
365
+
361
366
  newproperty(:target) do
362
367
  desc "Where the cron job should be stored. For crontab-style
363
368
  entries this is the same as the user and defaults that way.
@@ -61,6 +61,18 @@ module Puppet
61
61
  can be specified to set the remote server."
62
62
 
63
63
  defaultto { Puppet[:clientbucketdir] }
64
+
65
+ validate do |value|
66
+ if value.is_a? Array
67
+ raise ArgumentError, "You can only have one filebucket path"
68
+ end
69
+
70
+ if value.is_a? String and not Puppet::Util.absolute_path?(value)
71
+ raise ArgumentError, "Filebucket paths must be absolute"
72
+ end
73
+
74
+ true
75
+ end
64
76
  end
65
77
 
66
78
  # Create a default filebucket.