devstructure 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -176,7 +176,7 @@ EOF
176
176
  return if manager == package
177
177
  io.printf "#{command}\n", package, version
178
178
  if "apt" == manager && package =~ /^rubygems(\d+\.\d+(?:\.\d+)?)$/
179
- io.puts "/usr/bin/gem#{$1} install rubygems-update"
179
+ io.puts "/usr/bin/gem#{$1} install --no-rdoc --no-ri rubygems-update"
180
180
  io.puts "/usr/bin/ruby#{$1} $(PATH=\"$PATH:/var/lib/gems/#{
181
181
  $1}/bin\" which update_rubygems)"
182
182
  end
@@ -187,25 +187,35 @@ EOF
187
187
  # and heredoc syntax. Binary files are written using `base64`(1) and
188
188
  # symbolic links are placed using `ln`(1). Shocking stuff.
189
189
  files.sort.each do |pathname, content|
190
- if Hash == content.class
190
+ io.puts "mkdir -p #{File.dirname(pathname)}"
191
+ owner = group = mode = nil
192
+ command = "cat"
193
+ if Hash === content
194
+ owner = content["_owner"]
195
+ group = content["_group"]
191
196
  if content["_target"]
192
197
  io.puts "ln -s #{content["_target"]} #{pathname}"
193
198
  next
194
- elsif content["_base64"]
195
- content = content["_base64"]
196
- command = "base64 --decode"
199
+ else
200
+ mode = content["_mode"]
201
+ if content["_base64"]
202
+ content = content["_base64"]
203
+ command = "base64 --decode"
204
+ else
205
+ content = content["_content"]
206
+ end
197
207
  end
198
- else
199
- content.gsub!(/\\/, "\\\\\\\\")
200
- content.gsub!(/\$/, "\\$")
201
- command = "cat"
202
208
  end
209
+ content.gsub!(/\\/, "\\\\\\\\")
210
+ content.gsub!(/\$/, "\\$")
203
211
  eof = "EOF"
204
212
  eof << "EOF" while content =~ /^#{eof}$/
205
- io.puts "mkdir -p #{File.dirname(pathname)}"
206
213
  io.puts "#{command} >#{pathname} <<#{eof}"
207
214
  io.puts content
208
215
  io.puts eof
216
+ io.puts "chown #{owner} #{pathname}" if owner
217
+ io.puts "chgrp #{group} #{pathname}" if group
218
+ io.puts "chmod #{mode} #{pathname}" if mode
209
219
  end if files
210
220
 
211
221
  # Source tarballs are downloaded, extracted, and removed. Generally,
@@ -231,7 +241,7 @@ EOF
231
241
 
232
242
  # We need a pre-built map of each manager to its own manager so we can
233
243
  # easily declare dependencies within the Puppet manifest tree.
234
- managers = {}
244
+ managers = {"apt" => nil}
235
245
  walk(:package => lambda { |manager, command, package, version|
236
246
  managers[package] = manager if packages[package] && manager != package
237
247
  })
@@ -277,7 +287,7 @@ EOF
277
287
  :provider => :gem,
278
288
  :ensure => :latest
279
289
  )
280
- Puppet::Package["rubygems1.8"]
290
+ Puppet::Package["rubygems-update"]
281
291
  else
282
292
  manifest[manager] << Puppet::Exec.new(
283
293
  "/usr/bin/gem#{v} install --no-rdoc --no-ri rubygems-update",
@@ -287,8 +297,8 @@ EOF
287
297
  Puppet::Exec["rubygems-update-#{v}"]
288
298
  end
289
299
  manifest[manager] << Puppet::Exec.new(
290
- "/usr/bin/ruby#{v} /usr/bin/update_rubygems",
291
- :path => %W(/usr/bin /var/lib/gems/#{v}/bin),
300
+ "/bin/sh -c '/usr/bin/ruby#{v} $(PATH=$PATH:/var/lib/gems/#{
301
+ v}/bin which update_rubygems)'",
292
302
  :require => prereq
293
303
  )
294
304
  end
@@ -354,35 +364,55 @@ EOF
354
364
  #
355
365
  # File content is handled much like the shell version except base 64
356
366
  # decoding takes place here in Ruby rather than in the `base64`(1)
357
- # tool. Resources for all parent directories are created ahead of
358
- # any file. Puppet's autorequire mechanism will ensure that a file's
359
- # parent directories are realized before the file itself.
367
+ # tool.
360
368
  if files && 0 < files.length
361
- manifest << Puppet::Package.defaults(
362
- :before => files.sort.map { |pathname, content|
363
- Puppet::File[pathname]
364
- }
365
- )
369
+ classes = managers.keys.
370
+ reject { |manager| 0 == packages[manager]["_packages"].length }.
371
+ map { |manager| Puppet::Class[manager] }
372
+ if 0 < classes.length
373
+ manifest << Puppet::File.defaults(:require => classes)
374
+ end
366
375
  files.sort.each do |pathname, content|
376
+
377
+ # Resources for all parent directories are created ahead of
378
+ # any file. Puppet's autorequire mechanism will ensure that a
379
+ # file's parent directories are realized before the file itself.
367
380
  dirnames = File.dirname(pathname).split("/")
368
381
  dirnames.shift
369
382
  (0..(dirnames.length - 1)).each do |i|
370
383
  manifest << Puppet::File.new("/#{dirnames[0..i].join("/")}",
371
384
  :ensure => :directory)
372
385
  end
373
- if Hash == content.class
386
+
387
+ # Convert the blueprint file attributes to those that Puppet
388
+ # understands. Everything's optional.
389
+ options = {}
390
+ if Hash === content
391
+ options[:owner] = content["_owner"] if content["_owner"]
392
+ options[:group] = content["_group"] if content["_group"]
374
393
  if content["_target"]
375
- manifest << Puppet::File.new(pathname,
376
- :ensure => content["_target"])
377
- next
378
- elsif content["_base64"]
379
- content = Base64.decode64(content["_base64"])
394
+ options[:ensure] = content["_target"]
395
+ else
396
+ options[:mode] = content["_mode"] if content["_mode"]
397
+ options[:ensure] = :file
398
+ options[:content] = if content["_base64"]
399
+ Base64.decode64(content["_base64"])
400
+ else
401
+ content["_content"]
402
+ end
380
403
  end
404
+
405
+ # The easiest way to specify a file is to include just the
406
+ # content. The owner and group will be `root` and the mode will
407
+ # be set according to the `umask`.
408
+ else
409
+ options = {
410
+ :content => content,
411
+ :ensure => :file,
412
+ }
381
413
  end
382
- manifest << Puppet::File.new(pathname,
383
- :content => content,
384
- :ensure => :file
385
- )
414
+
415
+ manifest << Puppet::File.new(pathname, options)
386
416
  end
387
417
  end
388
418
 
@@ -391,11 +421,6 @@ EOF
391
421
  # such as this in a shell invocation. This is a pretty direct Puppet
392
422
  # equivalent to the shell version above.
393
423
  if sources && 0 < sources.length
394
- manifest << Puppet::Package.defaults(
395
- :before => sources.sort.map { |dirname, filename|
396
- Puppet::Exec[pathname]
397
- }
398
- )
399
424
  sources.sort.each do |dirname, filename|
400
425
  manifest << Puppet::Exec.new(filename,
401
426
  :command => "/bin/sh -c 'wget http://s3.amazonaws.com/blueprint-sources/#{filename}; tar xf #{filename}; rm #{filename}'",
@@ -473,22 +498,30 @@ EOF
473
498
  :mode => "755",
474
499
  :owner => "root",
475
500
  :recursive => true
476
- if Hash == content.class
501
+ owner = group = mode = nil
502
+ if Hash === content
503
+ owner = content["_owner"]
504
+ group = content["_group"]
477
505
  if content["_target"]
478
506
  cookbook.link pathname,
479
- :group => "root",
480
- :owner => "root",
507
+ :group => group || "root",
508
+ :owner => owner || "root",
481
509
  :to => content["_target"]
482
510
  next
483
- elsif content["_base64"]
484
- content = content["_base64"]
511
+ else
512
+ mode = content["_mode"]
513
+ if content["_base64"]
514
+ content = content["_base64"]
515
+ else
516
+ content = content["_content"]
517
+ end
485
518
  end
486
519
  end
487
520
  cookbook.cookbook_file pathname, content,
488
521
  :backup => false,
489
- :group => "root",
490
- :mode => "644",
491
- :owner => "root",
522
+ :group => group || "root",
523
+ :mode => mode || "644",
524
+ :owner => owner || "root",
492
525
  :source => pathname[1..-1]
493
526
  end if files
494
527
 
@@ -14,13 +14,18 @@
14
14
  # [sandbox-blueprint]: http://devstructure.github.com/contractor/sandbox-blueprint.1.html
15
15
  require 'devstructure'
16
16
 
17
- # Make `Symbol`s `Comparable` so we can sort each list of resource
17
+ # Make `Symbol`s and `nil`s `Comparable` so we can sort each list of resource
18
18
  # attributes before converting to a string.
19
19
  class Symbol
20
20
  def <=>(other)
21
21
  to_s <=> other.to_s
22
22
  end
23
23
  end
24
+ class NilClass
25
+ def <=>(other)
26
+ other.nil? ? 0 : 1
27
+ end
28
+ end
24
29
 
25
30
  module DevStructure::Puppet
26
31
 
@@ -48,19 +53,31 @@ module DevStructure::Puppet
48
53
  end
49
54
 
50
55
  # Add a resource to this manifest. Order is never important in Puppet
51
- # since all dependencies must be declared.
56
+ # since all dependencies must be declared. Normal resources that have
57
+ # names are just added to the tree. Resources that are declaring
58
+ # defaults for an entire type have `nil` names so they behave more
59
+ # cumulatively.
52
60
  def <<(resource)
53
61
  @resources[resource.type] ||= {}
54
- @resources[resource.type][resource.name] = resource
62
+ if resource.name
63
+ @resources[resource.type][resource.name] = resource
64
+ elsif @resources[resource.type][resource.name]
65
+ @resources[resource.type][resource.name].merge!(resource)
66
+ else
67
+ @resources[resource.type][resource.name] = resource
68
+ end
55
69
  end
56
70
 
57
71
  # Turn this manifest into a Puppet class. We start with a base level
58
72
  # of indentation that we carry through our resources and manifests.
59
73
  # Order is again not important so we don't make much effort. The
60
74
  # Puppet grammar prohibits dots in class names so we replace `.` with
61
- # `--`. Resources are grouped by type to reduce the total number of
62
- # lines required. If this manifest has a parent, the last thing we
63
- # do is include ourselves in the parent.
75
+ # `--`.
76
+ #
77
+ # Defaults for the entire type are handled first. Normal resources
78
+ # are grouped by type to reduce the total number of lines required.
79
+ # If this manifest has a parent, the last thing we do is include
80
+ # ourselves in the parent.
64
81
  def to_s(tab="")
65
82
  out = []
66
83
  out << "#{tab}class #{@name.gsub(".", "--")} {"
@@ -68,6 +85,9 @@ module DevStructure::Puppet
68
85
  out << manifest.to_s("#{tab}\t")
69
86
  end
70
87
  @resources.sort.each do |type, resources|
88
+ if resource = resources.delete(nil)
89
+ out << resource.to_s("#{tab}\t")
90
+ end
71
91
  if 1 < resources.length
72
92
  out << "#{tab}\t#{type} {"
73
93
  resources.sort.each do |name, resource|
@@ -75,7 +95,7 @@ module DevStructure::Puppet
75
95
  out << resource.to_s("#{tab}\t")
76
96
  end
77
97
  out << "#{tab}\t}"
78
- else
98
+ elsif 1 == resources.length
79
99
  out << resources.values.first.to_s("#{tab}\t")
80
100
  end
81
101
  end
@@ -100,7 +120,7 @@ module DevStructure::Puppet
100
120
  clear
101
121
  options.each { |k, v| self[k.to_s] = v }
102
122
  @type = self.class.to_s.downcase[/[^:]+$/]
103
- @name = name.to_s.downcase
123
+ @name = name && name.to_s
104
124
  @style = :complete
105
125
  end
106
126
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devstructure
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- - 0
10
- version: 0.3.0
9
+ - 1
10
+ version: 0.3.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Richard Crowley
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-09-01 00:00:00 +00:00
18
+ date: 2010-09-02 00:00:00 +00:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency