spiceweasel 0.7 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +7 -1
- data/README.md +86 -58
- data/bin/spiceweasel +27 -15
- data/example.json +2 -2
- data/example.yml +2 -2
- data/lib/spiceweasel/version.rb +1 -1
- metadata +4 -3
data/CHANGELOG.md
CHANGED
@@ -35,7 +35,7 @@ This is the current, previous and future development milestones and contains the
|
|
35
35
|
===
|
36
36
|
* add support for cookbook options
|
37
37
|
|
38
|
-
0.7
|
38
|
+
0.7
|
39
39
|
=============
|
40
40
|
* add support for environments
|
41
41
|
* rescue from parser errors
|
@@ -44,6 +44,12 @@ This is the current, previous and future development milestones and contains the
|
|
44
44
|
* add support for encrypted data bags
|
45
45
|
* wildcard support for data bag items
|
46
46
|
|
47
|
+
0.7.1 *CURRENT*
|
48
|
+
===============
|
49
|
+
* fixed run list parsing
|
50
|
+
* updated examples for Chef 0.10
|
51
|
+
* relaxed validation on existing cookbooks
|
52
|
+
|
47
53
|
BACKLOG
|
48
54
|
=======
|
49
55
|
Next
|
data/README.md
CHANGED
@@ -18,6 +18,54 @@ File Syntax
|
|
18
18
|
===========
|
19
19
|
The syntax for the spiceweasel file may be either JSON or YAML format of Chef primitives describing what is to be instantiated. Below or 2 examples describing the same infrastructure.
|
20
20
|
|
21
|
+
YAML
|
22
|
+
----
|
23
|
+
From the `example.yml`:
|
24
|
+
|
25
|
+
``` yaml
|
26
|
+
cookbooks:
|
27
|
+
- apache2:
|
28
|
+
- apt:
|
29
|
+
- 1.1.1
|
30
|
+
- mysql:
|
31
|
+
|
32
|
+
environments:
|
33
|
+
- development:
|
34
|
+
- qa:
|
35
|
+
- production:
|
36
|
+
|
37
|
+
roles:
|
38
|
+
- base:
|
39
|
+
- monitoring:
|
40
|
+
- webserver:
|
41
|
+
|
42
|
+
data bags:
|
43
|
+
- users:
|
44
|
+
- alice
|
45
|
+
- bob
|
46
|
+
- chuck
|
47
|
+
- data:
|
48
|
+
- *
|
49
|
+
- passwords:
|
50
|
+
- secret secret_key
|
51
|
+
- mysql
|
52
|
+
- rabbitmq
|
53
|
+
|
54
|
+
nodes:
|
55
|
+
- serverA:
|
56
|
+
- role[base]
|
57
|
+
- -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems
|
58
|
+
- serverB serverC:
|
59
|
+
- role[base]
|
60
|
+
- -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems
|
61
|
+
- ec2 3:
|
62
|
+
- role[webserver] recipe[mysql::client]
|
63
|
+
- -S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small
|
64
|
+
- rackspace 3:
|
65
|
+
- recipe[mysql],role[monitoring]
|
66
|
+
- --image 49 --flavor 2
|
67
|
+
```
|
68
|
+
|
21
69
|
JSON
|
22
70
|
----
|
23
71
|
From the `example.json`:
|
@@ -29,7 +77,7 @@ From the `example.json`:
|
|
29
77
|
{"apache2":[]},
|
30
78
|
{"apt":
|
31
79
|
[
|
32
|
-
"1.1.
|
80
|
+
"1.1.1"
|
33
81
|
]
|
34
82
|
},
|
35
83
|
{"mysql":[]}
|
@@ -55,7 +103,18 @@ From the `example.json`:
|
|
55
103
|
"chuck"
|
56
104
|
]
|
57
105
|
},
|
58
|
-
{"data":
|
106
|
+
{"data":
|
107
|
+
[
|
108
|
+
"*"
|
109
|
+
]
|
110
|
+
},
|
111
|
+
{"passwords":
|
112
|
+
[
|
113
|
+
"secret secret_key",
|
114
|
+
"mysql",
|
115
|
+
"rabbitmq"
|
116
|
+
]
|
117
|
+
}
|
59
118
|
],
|
60
119
|
"nodes":
|
61
120
|
[
|
@@ -65,15 +124,21 @@ From the `example.json`:
|
|
65
124
|
"-i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems"
|
66
125
|
]
|
67
126
|
},
|
68
|
-
{"
|
127
|
+
{"serverB serverC":
|
128
|
+
[
|
129
|
+
"role[base]",
|
130
|
+
"-i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems"
|
131
|
+
]
|
132
|
+
},
|
133
|
+
{"ec2 3":
|
69
134
|
[
|
70
135
|
"role[webserver] recipe[mysql::client]",
|
71
|
-
"-S mray -
|
136
|
+
"-S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small"
|
72
137
|
]
|
73
138
|
},
|
74
139
|
{"rackspace 3":
|
75
140
|
[
|
76
|
-
"recipe[mysql]
|
141
|
+
"recipe[mysql],role[monitoring]",
|
77
142
|
"--image 49 --flavor 2"
|
78
143
|
]
|
79
144
|
}
|
@@ -81,49 +146,9 @@ From the `example.json`:
|
|
81
146
|
}
|
82
147
|
```
|
83
148
|
|
84
|
-
YAML
|
85
|
-
----
|
86
|
-
From the `example.yml`:
|
87
|
-
|
88
|
-
``` yaml
|
89
|
-
cookbooks:
|
90
|
-
- apache2:
|
91
|
-
- apt:
|
92
|
-
- 1.1.0
|
93
|
-
- mysql:
|
94
|
-
|
95
|
-
environments:
|
96
|
-
- development:
|
97
|
-
- qa:
|
98
|
-
- production:
|
99
|
-
|
100
|
-
roles:
|
101
|
-
- base:
|
102
|
-
- monitoring:
|
103
|
-
- webserver:
|
104
|
-
|
105
|
-
data bags:
|
106
|
-
- users:
|
107
|
-
- alice
|
108
|
-
- bob
|
109
|
-
- chuck
|
110
|
-
- data:
|
111
|
-
|
112
|
-
nodes:
|
113
|
-
- serverA:
|
114
|
-
- role[base]
|
115
|
-
- -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems
|
116
|
-
- ec2 5:
|
117
|
-
- role[webserver] recipe[mysql::client]
|
118
|
-
- -S mray -I ~/.ssh/mray.pem -x ubuntu -G default -i ami-a403f7cd -f m1.small
|
119
|
-
- rackspace 3:
|
120
|
-
- recipe[mysql] role[monitoring]
|
121
|
-
- --image 49 --flavor 2
|
122
|
-
```
|
123
|
-
|
124
149
|
Cookbooks
|
125
150
|
---------
|
126
|
-
The `cookbooks` section of the JSON or YAML file currently supports `knife cookbook upload FOO` where `FOO` is the name of the cookbook in the `cookbooks` directory. If a version is passed, it is validated against an existing cookbook `metadata.rb` and if none is found, the missing cookbook is downloaded (without touching version control) and the command to untar it is provided. You may pass any additional arguments if necessary. The YAML snippet
|
151
|
+
The `cookbooks` section of the JSON or YAML file currently supports `knife cookbook upload FOO` where `FOO` is the name of the cookbook in the `cookbooks` directory. If a version is passed, it is validated against an existing cookbook `metadata.rb` (it must match the `metadata.rb` string exactly) and if none is found, the missing cookbook is downloaded (without touching version control) and the command to untar it is provided. You may pass any additional arguments if necessary. The YAML snippet
|
127
152
|
|
128
153
|
``` yaml
|
129
154
|
cookbooks:
|
@@ -216,18 +241,21 @@ knife data bag from file passwords data_bags/passwords/rabbitmq.json --secret-fi
|
|
216
241
|
|
217
242
|
Nodes
|
218
243
|
-----
|
219
|
-
The `nodes` section of the JSON or YAML file bootstraps a node for each entry where the entry is a hostname or provider and count. Each node requires 2 items after it in a sequence. The first item is the run_list and the second the CLI options used. Validation is performed on the run_list components to ensure that only recipes and roles listed in the file are used. A shortcut syntax for bulk-creating nodes with various providers where the line starts with the provider and ends with the number of nodes to be provisioned. The YAML snippet
|
244
|
+
The `nodes` section of the JSON or YAML file bootstraps a node for each entry where the entry is a hostname or provider and count. Each node requires 2 items after it in a sequence. The first item is the run_list and the second the CLI options used. The run_list may be space or comma-delimited. Validation is performed on the run_list components to ensure that only recipes and roles listed in the file are used. A shortcut syntax for bulk-creating nodes with various providers where the line starts with the provider and ends with the number of nodes to be provisioned. The YAML snippet
|
220
245
|
|
221
246
|
``` yaml
|
222
247
|
nodes:
|
223
248
|
- serverA:
|
224
249
|
- role[base]
|
225
250
|
- -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems
|
226
|
-
-
|
251
|
+
- serverB serverC:
|
252
|
+
- role[base]
|
253
|
+
- -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems
|
254
|
+
- ec2 3:
|
227
255
|
- role[webserver] recipe[mysql::client]
|
228
|
-
- -S mray -
|
256
|
+
- -S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small
|
229
257
|
- rackspace 3:
|
230
|
-
- recipe[mysql]
|
258
|
+
- recipe[mysql],role[monitoring]
|
231
259
|
- --image 49 --flavor 2
|
232
260
|
```
|
233
261
|
|
@@ -235,14 +263,14 @@ produces the knife commands
|
|
235
263
|
|
236
264
|
```
|
237
265
|
knife bootstrap serverA 'role[base]' -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems
|
238
|
-
knife
|
239
|
-
knife
|
240
|
-
knife ec2 server create 'role[webserver]
|
241
|
-
knife ec2 server create 'role[webserver]
|
242
|
-
knife ec2 server create 'role[webserver]
|
243
|
-
knife rackspace server create 'recipe[mysql]
|
244
|
-
knife rackspace server create 'recipe[mysql]
|
245
|
-
knife rackspace server create 'recipe[mysql]
|
266
|
+
knife bootstrap serverB 'role[base]' -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems
|
267
|
+
knife bootstrap serverC 'role[base]' -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems
|
268
|
+
knife ec2 server create 'role[webserver],recipe[mysql::client]' -S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small
|
269
|
+
knife ec2 server create 'role[webserver],recipe[mysql::client]' -S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small
|
270
|
+
knife ec2 server create 'role[webserver],recipe[mysql::client]' -S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small
|
271
|
+
knife rackspace server create 'recipe[mysql],role[monitoring]' --image 49 --flavor 2
|
272
|
+
knife rackspace server create 'recipe[mysql],role[monitoring]' --image 49 --flavor 2
|
273
|
+
knife rackspace server create 'recipe[mysql],role[monitoring]' --image 49 --flavor 2
|
246
274
|
```
|
247
275
|
|
248
276
|
Usage
|
data/bin/spiceweasel
CHANGED
@@ -41,6 +41,11 @@ class SpiceweaselCLI
|
|
41
41
|
|
42
42
|
banner("Usage: spiceweasel [option] file")
|
43
43
|
|
44
|
+
option :debug,
|
45
|
+
:long => "--debug",
|
46
|
+
:description => "Verbose debugging messages.",
|
47
|
+
:boolean => true
|
48
|
+
|
44
49
|
option :delete,
|
45
50
|
:short => "-d",
|
46
51
|
:long => "--delete",
|
@@ -89,6 +94,7 @@ end
|
|
89
94
|
|
90
95
|
begin
|
91
96
|
file = ARGV.last
|
97
|
+
STDOUT.puts "DEBUG: file: #{file}" if cli.config[:debug]
|
92
98
|
if (file.end_with?(".yml"))
|
93
99
|
input = YAML.load_file ARGV.last
|
94
100
|
elsif (file.end_with?(".json"))
|
@@ -116,16 +122,17 @@ cookbook_list = []
|
|
116
122
|
cookbooks.each do |cookbook|
|
117
123
|
cb = cookbook.keys.first
|
118
124
|
if cookbook[cb] and cookbook[cb].length > 0
|
119
|
-
version = cookbook[cb][0] || ""
|
125
|
+
version = cookbook[cb][0].to_s || ""
|
120
126
|
args = cookbook[cb][1] || ""
|
121
127
|
end
|
128
|
+
STDOUT.puts "DEBUG: cookbook: #{cb} #{version}" if cli.config[:debug]
|
122
129
|
delete += "knife cookbook delete #{cb} #{version} -y\n"
|
123
130
|
if File.directory?("cookbooks")
|
124
131
|
if version and File.directory?("cookbooks/#{cb}")
|
125
132
|
#check metadata.rb for requested version
|
126
|
-
metadata = File.open("cookbooks/#{cb}/metadata.rb").grep(/^version/)[0].split()[1].gsub(/"/,'')
|
127
|
-
if (metadata != version
|
128
|
-
raise "Invalid version
|
133
|
+
metadata = File.open("cookbooks/#{cb}/metadata.rb").grep(/^version/)[0].split()[1].gsub(/"/,'').to_s
|
134
|
+
if (metadata != version)
|
135
|
+
raise "Invalid version #{version} of '#{cb}' requested, #{metadata} is already in the cookbooks directory."
|
129
136
|
exit(-1)
|
130
137
|
end
|
131
138
|
elsif !File.directory?("cookbooks/#{cb}")
|
@@ -144,6 +151,7 @@ end
|
|
144
151
|
environments = input['environments'] || []
|
145
152
|
environment_list = []
|
146
153
|
environments.each do |environment|
|
154
|
+
STDOUT.puts "DEBUG: environment: #{environment.keys[0]}" if cli.config[:debug]
|
147
155
|
delete += "knife environment delete #{environment.keys[0]} -y\n"
|
148
156
|
create += "knife environment from file #{environment.keys[0]}.rb\n"
|
149
157
|
#flatten list of environments for validation later
|
@@ -154,6 +162,7 @@ end
|
|
154
162
|
roles = input['roles'] || []
|
155
163
|
role_list = []
|
156
164
|
roles.each do |role|
|
165
|
+
STDOUT.puts "DEBUG: role: #{role.keys[0]}" if cli.config[:debug]
|
157
166
|
delete += "knife role delete #{role.keys[0]} -y\n"
|
158
167
|
create += "knife role from file #{role.keys[0]}.rb\n"
|
159
168
|
#flatten list of roles for validation later
|
@@ -163,11 +172,13 @@ end
|
|
163
172
|
#data bags
|
164
173
|
bags = input['data bags'] || []
|
165
174
|
bags.each do |bag|
|
175
|
+
STDOUT.puts "DEBUG: data bag: #{bag.keys[0]}" if cli.config[:debug]
|
166
176
|
delete += "knife data bag delete #{bag.keys[0]} -y\n"
|
167
177
|
create += "knife data bag create #{bag.keys[0]}\n"
|
168
178
|
items = bag[bag.keys[0]] || []
|
169
179
|
secret = nil
|
170
180
|
while item = items.shift
|
181
|
+
STDOUT.puts "DEBUG: data bag #{bag.keys[0]} item: #{item}" if cli.config[:debug]
|
171
182
|
if item.start_with?("secret")
|
172
183
|
secret = item.split()[1]
|
173
184
|
next
|
@@ -190,30 +201,31 @@ nodes = input['nodes'] || []
|
|
190
201
|
#currently use bulk_delete for deleting, add provider support real soon
|
191
202
|
delete += "knife node bulk_delete .* -y\n"
|
192
203
|
nodes.each do |node|
|
204
|
+
STDOUT.puts "DEBUG: node: #{node.keys[0]}" if cli.config[:debug]
|
193
205
|
# delete += "knife node delete #{node[node.keys[0]}\n"
|
194
|
-
run_list = node[node.keys[0]][0].split()
|
206
|
+
run_list = node[node.keys[0]][0].gsub(/ /,',').split(',')
|
207
|
+
STDOUT.puts "DEBUG: node run_list: #{run_list}" if cli.config[:debug]
|
195
208
|
validate_run_list(run_list, cookbook_list, environment_list, role_list)
|
209
|
+
#provider support
|
196
210
|
if node.keys[0].start_with?("bluebox","ec2","openstack","rackspace","slicehost","terremark")
|
197
211
|
provider = node.keys[0].split()
|
198
212
|
count = 1
|
199
213
|
if (provider.length == 2)
|
200
214
|
count = provider[1]
|
201
215
|
end
|
216
|
+
#create the instances
|
202
217
|
count.to_i.times do
|
203
|
-
create += "knife #{provider[0]} server create "
|
204
|
-
run_list.
|
205
|
-
create += "
|
218
|
+
create += "knife #{provider[0]} server create #{node[node.keys[0]][1]}"
|
219
|
+
if run_list.length > 0
|
220
|
+
create += " -r '#{node[node.keys[0]][0].gsub(/ /,',')}'\n"
|
206
221
|
end
|
207
|
-
create +="#{node[node.keys[0]][1]}\n"
|
208
222
|
end
|
209
|
-
else
|
210
|
-
#multinode support
|
223
|
+
else #multinode support
|
211
224
|
node.keys[0].split.each do |server|
|
212
|
-
create += "knife bootstrap #{server} "
|
213
|
-
run_list.
|
214
|
-
create += "
|
225
|
+
create += "knife bootstrap #{server} #{node[node.keys[0]][1]}"
|
226
|
+
if run_list.length > 0
|
227
|
+
create += " -r '#{node[node.keys[0]][0].gsub(/ /,',')}'\n"
|
215
228
|
end
|
216
|
-
create +="#{node[node.keys[0]][1]}\n"
|
217
229
|
end
|
218
230
|
end
|
219
231
|
end
|
data/example.json
CHANGED
@@ -60,12 +60,12 @@
|
|
60
60
|
{"ec2 3":
|
61
61
|
[
|
62
62
|
"role[webserver] recipe[mysql::client]",
|
63
|
-
"-S mray -
|
63
|
+
"-S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small"
|
64
64
|
]
|
65
65
|
},
|
66
66
|
{"rackspace 3":
|
67
67
|
[
|
68
|
-
"recipe[mysql]
|
68
|
+
"recipe[mysql],role[monitoring]",
|
69
69
|
"--image 49 --flavor 2"
|
70
70
|
]
|
71
71
|
}
|
data/example.yml
CHANGED
@@ -35,7 +35,7 @@ nodes:
|
|
35
35
|
- -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems
|
36
36
|
- ec2 3:
|
37
37
|
- role[webserver] recipe[mysql::client]
|
38
|
-
- -S mray -
|
38
|
+
- -S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small
|
39
39
|
- rackspace 3:
|
40
|
-
- recipe[mysql]
|
40
|
+
- recipe[mysql],role[monitoring]
|
41
41
|
- --image 49 --flavor 2
|
data/lib/spiceweasel/version.rb
CHANGED
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spiceweasel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 1
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 7
|
9
|
-
|
9
|
+
- 1
|
10
|
+
version: 0.7.1
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Matt Ray
|
@@ -14,7 +15,7 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2011-05-
|
18
|
+
date: 2011-05-05 00:00:00 -05:00
|
18
19
|
default_executable:
|
19
20
|
dependencies: []
|
20
21
|
|