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.
- data/lib/devstructure/blueprint.rb +78 -45
- data/lib/devstructure/puppet.rb +28 -8
- metadata +4 -4
@@ -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
|
-
|
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
|
-
|
195
|
-
|
196
|
-
|
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["
|
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} /
|
291
|
-
|
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.
|
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
|
-
|
362
|
-
|
363
|
-
|
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
|
-
|
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
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
content =
|
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
|
-
|
383
|
-
|
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
|
-
|
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
|
-
|
484
|
-
|
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
|
|
data/lib/devstructure/puppet.rb
CHANGED
@@ -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
|
-
|
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
|
-
# `--`.
|
62
|
-
#
|
63
|
-
#
|
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
|
-
|
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
|
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:
|
4
|
+
hash: 17
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
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-
|
18
|
+
date: 2010-09-02 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|