devstructure 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|