vagabond 0.2.8 → 0.2.10
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +16 -0
- data/DEVELOP.md +38 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +33 -0
- data/README.md +55 -21
- data/USAGE.md +28 -3
- data/Vagabondfile.sample +47 -0
- data/Vagrantfile +17 -5
- data/bin/vagabond +5 -0
- data/lib/vagabond/Cheffile +7 -0
- data/lib/vagabond/Cheffile.dev +7 -0
- data/lib/vagabond/actions/cluster.rb +22 -8
- data/lib/vagabond/actions/create.rb +7 -4
- data/lib/vagabond/actions/destroy.rb +24 -14
- data/lib/vagabond/actions/freeze.rb +1 -0
- data/lib/vagabond/actions/init.rb +8 -11
- data/lib/vagabond/actions/provision.rb +16 -8
- data/lib/vagabond/actions/rebuild.rb +4 -9
- data/lib/vagabond/actions/ssh.rb +9 -1
- data/lib/vagabond/actions/start.rb +1 -0
- data/lib/vagabond/actions/status.rb +1 -0
- data/lib/vagabond/actions/thaw.rb +1 -0
- data/lib/vagabond/actions/up.rb +22 -7
- data/lib/vagabond/bootstraps/chef_10_compat_config.erb +62 -0
- data/lib/vagabond/bootstraps/no_lazy_load.erb +63 -0
- data/lib/vagabond/bootstraps/server-zero.erb +1 -8
- data/lib/vagabond/bootstraps/server.erb +9 -6
- data/lib/vagabond/constants.rb +1 -6
- data/lib/vagabond/core.rb +209 -0
- data/lib/vagabond/errors.rb +3 -0
- data/lib/vagabond/helpers.rb +11 -99
- data/lib/vagabond/helpers/base.rb +134 -0
- data/lib/vagabond/helpers/callbacks.rb +47 -0
- data/lib/vagabond/helpers/chains.rb +23 -0
- data/lib/vagabond/helpers/commands.rb +49 -0
- data/lib/vagabond/helpers/knife.rb +47 -0
- data/lib/vagabond/helpers/naming.rb +39 -0
- data/lib/vagabond/helpers/server.rb +30 -0
- data/lib/vagabond/internal_configuration.rb +186 -32
- data/lib/vagabond/kitchen.rb +110 -60
- data/lib/vagabond/knife.rb +5 -1
- data/lib/vagabond/layout.rb +1 -0
- data/lib/vagabond/monkey/kitchen_config.rb +1 -0
- data/lib/vagabond/notify_mash.rb +25 -0
- data/lib/vagabond/server.rb +81 -49
- data/lib/vagabond/settings.rb +17 -0
- data/lib/vagabond/spec.rb +125 -99
- data/lib/vagabond/uploader.rb +4 -1
- data/lib/vagabond/uploader/berkshelf.rb +2 -1
- data/lib/vagabond/uploader/knife.rb +3 -9
- data/lib/vagabond/uploader/librarian.rb +2 -5
- data/lib/vagabond/vagabond.rb +77 -93
- data/lib/vagabond/vagabondfile.rb +73 -9
- data/lib/vagabond/version.rb +2 -1
- data/vagabond.gemspec +7 -5
- metadata +58 -81
- data/lib/vagabond/cookbooks/apt/Berksfile +0 -8
- data/lib/vagabond/cookbooks/apt/CHANGELOG.md +0 -97
- data/lib/vagabond/cookbooks/apt/CONTRIBUTING +0 -29
- data/lib/vagabond/cookbooks/apt/LICENSE +0 -201
- data/lib/vagabond/cookbooks/apt/README.md +0 -243
- data/lib/vagabond/cookbooks/apt/TESTING.md +0 -25
- data/lib/vagabond/cookbooks/apt/attributes/default.rb +0 -4
- data/lib/vagabond/cookbooks/apt/files/default/apt-proxy-v2.conf +0 -50
- data/lib/vagabond/cookbooks/apt/metadata.rb +0 -30
- data/lib/vagabond/cookbooks/apt/providers/preference.rb +0 -61
- data/lib/vagabond/cookbooks/apt/providers/repository.rb +0 -132
- data/lib/vagabond/cookbooks/apt/recipes/cacher-client.rb +0 -59
- data/lib/vagabond/cookbooks/apt/recipes/cacher-ng.rb +0 -40
- data/lib/vagabond/cookbooks/apt/recipes/default.rb +0 -68
- data/lib/vagabond/cookbooks/apt/resources/preference.rb +0 -30
- data/lib/vagabond/cookbooks/apt/resources/repository.rb +0 -40
- data/lib/vagabond/cookbooks/apt/templates/debian-6.0/acng.conf.erb +0 -174
- data/lib/vagabond/cookbooks/apt/templates/default/01proxy.erb +0 -2
- data/lib/vagabond/cookbooks/apt/templates/default/acng.conf.erb +0 -276
- data/lib/vagabond/cookbooks/apt/templates/ubuntu-10.04/acng.conf.erb +0 -270
- data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/README.md +0 -1
- data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/files/default/tests/minitest/cacher-ng_test.rb +0 -28
- data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/files/default/tests/minitest/default_test.rb +0 -28
- data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/files/default/tests/minitest/lwrps_test.rb +0 -48
- data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/files/default/tests/minitest/support/helpers.rb +0 -29
- data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/metadata.rb +0 -6
- data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/recipes/cacher-ng.rb +0 -20
- data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/recipes/default.rb +0 -20
- data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/recipes/lwrps.rb +0 -66
- data/lib/vagabond/cookbooks/lxc/CHANGELOG.md +0 -37
- data/lib/vagabond/cookbooks/lxc/Gemfile +0 -4
- data/lib/vagabond/cookbooks/lxc/Gemfile.lock +0 -41
- data/lib/vagabond/cookbooks/lxc/README.md +0 -112
- data/lib/vagabond/cookbooks/lxc/attributes/default.rb +0 -26
- data/lib/vagabond/cookbooks/lxc/files/default/knife_lxc +0 -228
- data/lib/vagabond/cookbooks/lxc/files/default/lxc-awesome-ephemeral +0 -499
- data/lib/vagabond/cookbooks/lxc/libraries/lxc.rb +0 -477
- data/lib/vagabond/cookbooks/lxc/libraries/lxc_expanded_resources.rb +0 -40
- data/lib/vagabond/cookbooks/lxc/libraries/lxc_file_config.rb +0 -84
- data/lib/vagabond/cookbooks/lxc/libraries/monkey.rb +0 -51
- data/lib/vagabond/cookbooks/lxc/metadata.rb +0 -12
- data/lib/vagabond/cookbooks/lxc/providers/config.rb +0 -75
- data/lib/vagabond/cookbooks/lxc/providers/container.rb +0 -354
- data/lib/vagabond/cookbooks/lxc/providers/default.rb +0 -57
- data/lib/vagabond/cookbooks/lxc/providers/ephemeral.rb +0 -40
- data/lib/vagabond/cookbooks/lxc/providers/fstab.rb +0 -30
- data/lib/vagabond/cookbooks/lxc/providers/interface.rb +0 -45
- data/lib/vagabond/cookbooks/lxc/providers/service.rb +0 -53
- data/lib/vagabond/cookbooks/lxc/recipes/containers.rb +0 -13
- data/lib/vagabond/cookbooks/lxc/recipes/default.rb +0 -58
- data/lib/vagabond/cookbooks/lxc/recipes/install_dependencies.rb +0 -15
- data/lib/vagabond/cookbooks/lxc/recipes/knife.rb +0 -37
- data/lib/vagabond/cookbooks/lxc/resources/config.rb +0 -19
- data/lib/vagabond/cookbooks/lxc/resources/container.rb +0 -54
- data/lib/vagabond/cookbooks/lxc/resources/default.rb +0 -12
- data/lib/vagabond/cookbooks/lxc/resources/ephemeral.rb +0 -13
- data/lib/vagabond/cookbooks/lxc/resources/fstab.rb +0 -12
- data/lib/vagabond/cookbooks/lxc/resources/interface.rb +0 -13
- data/lib/vagabond/cookbooks/lxc/resources/service.rb +0 -5
- data/lib/vagabond/cookbooks/lxc/templates/default/client.rb.erb +0 -13
- data/lib/vagabond/cookbooks/lxc/templates/default/default-lxc.erb +0 -3
- data/lib/vagabond/cookbooks/lxc/templates/default/file_content.erb +0 -2
- data/lib/vagabond/cookbooks/lxc/templates/default/fstab.erb +0 -5
- data/lib/vagabond/cookbooks/lxc/templates/default/interface.erb +0 -27
- data/lib/vagabond/cookbooks/vagabond/README.md +0 -10
- data/lib/vagabond/cookbooks/vagabond/attributes/default.rb +0 -18
- data/lib/vagabond/cookbooks/vagabond/files/default/lxc-centos +0 -460
- data/lib/vagabond/cookbooks/vagabond/libraries/vagabond.rb +0 -10
- data/lib/vagabond/cookbooks/vagabond/metadata.rb +0 -8
- data/lib/vagabond/cookbooks/vagabond/recipes/default.rb +0 -132
- data/lib/vagabond/cookbooks/vagabond/recipes/zero.rb +0 -9
- data/lib/vagabond/helpers/cheffile_loader.rb +0 -20
- data/vagabond-0.2.6.gem +0 -0
data/lib/vagabond/spec.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
+
#encoding: utf-8
|
1
2
|
require 'thor'
|
2
|
-
require
|
3
|
+
require 'elecksee/lxc'
|
3
4
|
|
4
|
-
%w(
|
5
|
+
%w(vagabond server helpers vagabondfile internal_configuration actions/status).each do |dep|
|
5
6
|
require "vagabond/#{dep}"
|
6
7
|
end
|
7
8
|
|
@@ -12,8 +13,6 @@ module Vagabond
|
|
12
13
|
include Helpers
|
13
14
|
include Actions::Status
|
14
15
|
|
15
|
-
attr_accessor :layout
|
16
|
-
|
17
16
|
self.class_exec(&Vagabond::CLI_OPTIONS)
|
18
17
|
|
19
18
|
def self.basename
|
@@ -23,6 +22,7 @@ module Vagabond
|
|
23
22
|
def initialize(*args)
|
24
23
|
@name = nil
|
25
24
|
super
|
25
|
+
base_setup(:no_configure, :no_validate)
|
26
26
|
end
|
27
27
|
|
28
28
|
method_option(:irl,
|
@@ -30,6 +30,11 @@ module Vagabond
|
|
30
30
|
:default => false,
|
31
31
|
:desc => 'Test In Real Life'
|
32
32
|
)
|
33
|
+
method_option(:irl_connect,
|
34
|
+
:type => :string,
|
35
|
+
:default => 'ipaddress',
|
36
|
+
:desc => 'Attribute to use for ssh connection'
|
37
|
+
)
|
33
38
|
method_option(:environment,
|
34
39
|
:type => :string,
|
35
40
|
:desc => 'Specify environment to restrict node detection'
|
@@ -41,18 +46,19 @@ module Vagabond
|
|
41
46
|
)
|
42
47
|
desc 'start [CLUSTER]', 'Run specs for cluster'
|
43
48
|
def start(cluster=nil)
|
44
|
-
@options = options.dup
|
45
|
-
setup_ui(nil, :no_class_set)
|
46
49
|
error = nil
|
47
50
|
begin
|
48
51
|
if(options[:irl])
|
49
52
|
irl_spec(cluster)
|
50
53
|
else
|
51
54
|
cluster_spec(cluster)
|
55
|
+
cluster_destroy(cluster) if options[:auto_destroy]
|
52
56
|
end
|
53
57
|
rescue => error
|
58
|
+
ui.error "Unexpected error encountered: #{error}"
|
59
|
+
debug("#{error.class}: #{error}\n#{error.backtrace.join("\n")}")
|
60
|
+
raise
|
54
61
|
ensure
|
55
|
-
cluster_destroy(cluster) if options[:auto_destroy] && !options[:irl]
|
56
62
|
result = error ? ui.color('FAILED', :red, :bold) : ui.color('PASSED', :green, :bold)
|
57
63
|
ui.info "--> Specs for cluster #{cluster}: #{result}"
|
58
64
|
raise VagabondError::SpecFailed.new(error) if error
|
@@ -65,23 +71,19 @@ module Vagabond
|
|
65
71
|
)
|
66
72
|
desc 'destroy NAME', 'Destroy the given cluster/node'
|
67
73
|
def destroy(cluster)
|
68
|
-
base_setup
|
69
74
|
options[:node] ? node_destroy(cluster, options[:node]) : cluster_destroy(cluster)
|
70
75
|
end
|
71
76
|
|
72
77
|
desc 'status [NAME]', 'Show status of existing nodes'
|
73
78
|
def status(name=nil)
|
74
|
-
base_setup
|
75
79
|
_status
|
76
80
|
end
|
77
81
|
|
78
82
|
desc 'init', 'Initalize spec configuration'
|
79
83
|
def init
|
80
|
-
setup_ui(nil, :no_class_set)
|
81
84
|
ui.info "Initializing spec configuration..."
|
82
85
|
make_spec_directory
|
83
86
|
populate_spec_directory
|
84
|
-
# - dump empty layout
|
85
87
|
ui.info " -> #{ui.color('COMPLETE!', :green)}"
|
86
88
|
end
|
87
89
|
|
@@ -112,7 +114,6 @@ module Vagabond
|
|
112
114
|
end
|
113
115
|
|
114
116
|
def populate_spec_directory
|
115
|
-
write_default_file('Layout')
|
116
117
|
write_default_file('spec_helper.rb')
|
117
118
|
end
|
118
119
|
|
@@ -140,26 +141,25 @@ module Vagabond
|
|
140
141
|
end
|
141
142
|
|
142
143
|
def irl_spec(cluster)
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
i.
|
153
|
-
end
|
154
|
-
terms = roles.map{|r| "role:#{r.name}"} + recipes.map{|r| "recipes:#{r.name}"}
|
155
|
-
query = terms.join(' AND ')
|
156
|
-
if(options[:environment])
|
157
|
-
query = "chef_environment:#{options[:environment]} AND (#{query})"
|
144
|
+
# TODO: Clean up this inject and spit error when nil returned
|
145
|
+
address = options[:irl_connect].split('.').inject(node){|k,m| m[k] || {}}
|
146
|
+
if(cluster && vagabondfile[:clusters][cluster])
|
147
|
+
nodes = vagabondfile[:clusters][cluster].map do |item_name|
|
148
|
+
vagabondfile.for_node(item_name, :allow_missing_node)
|
149
|
+
end
|
150
|
+
valid_runlists = nodes.map do |node|
|
151
|
+
node[:run_list].map do |runlist_item|
|
152
|
+
i = Chef::RunList::RunListItem.new(runlist_item)
|
153
|
+
[i, "#{i.role? ? 'roles' : 'recipes'}:#{i.name}"]
|
158
154
|
end
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
155
|
+
end
|
156
|
+
valid_runlists.each do |rl|
|
157
|
+
query = rl.map(&:last)
|
158
|
+
query.push("chef_environment:#{options[:environment]}") if options[:environment]
|
159
|
+
search(:node, query.join(' AND ')).each do |node|
|
160
|
+
node_runlist = node.run_list.map(&:to_s)
|
161
|
+
next unless node_runlist.size == rl.size && (node_runlist - rl.map(&:first)).empty?
|
162
|
+
test_node!(node.name, address, node.run_list)
|
163
163
|
end
|
164
164
|
end
|
165
165
|
else
|
@@ -169,74 +169,118 @@ module Vagabond
|
|
169
169
|
end
|
170
170
|
Chef::Search::Query.new(:node, query.join(' AND ')) do |nodes|
|
171
171
|
nodes.each do |node|
|
172
|
-
test_node!(node.name,
|
172
|
+
test_node!(node.name, address, node.run_list)
|
173
173
|
end
|
174
174
|
end
|
175
175
|
end
|
176
176
|
end
|
177
177
|
|
178
|
-
def
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
178
|
+
def get_cluster(name)
|
179
|
+
clusters = vagabondfile[:specs][:clusters] || Mash.new
|
180
|
+
cluster = clusters[name] || Mash.new
|
181
|
+
cluster[:nodes] = (vagabondfile[:clusters][name] || []) + (cluster[:nodes] || [])
|
182
|
+
cluster
|
183
183
|
end
|
184
184
|
|
185
185
|
def cluster_spec(cluster)
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
@internal_config = InternalConfiguration.new(vagabondfile, nil, options)
|
190
|
-
# First, setup server
|
191
|
-
if(vagabondfile[:local_chef_server][:enabled])
|
192
|
-
require 'vagabond/server'
|
193
|
-
srv = ::Vagabond::Server.new
|
194
|
-
srv.send(:setup, 'up')
|
195
|
-
srv.send(:execute)
|
196
|
-
end
|
186
|
+
cluster = get_cluster(cluster)
|
187
|
+
|
188
|
+
setup_server_if_needed
|
197
189
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
v_n = vagabond_instance(:up,
|
190
|
+
index = 0
|
191
|
+
test_nodes = cluster[:nodes].map do |node_name|
|
192
|
+
config = vagabondfile.for_node(node_name, :allow_missing)
|
193
|
+
config = vagabondfile.for_definition(node_name) unless config
|
194
|
+
if(cluster[:overrides])
|
195
|
+
config = Chef::Mixin::DeepMerge.merge(config, cluster[:overrides])
|
196
|
+
end
|
197
|
+
v_n = vagabond_instance(:create,
|
207
198
|
:platform => config[:platform],
|
208
199
|
:cluster => cluster,
|
209
|
-
:base_name => "s-#{
|
200
|
+
:base_name => "s-#{node_name}-#{index}"
|
210
201
|
)
|
211
202
|
v_n.config = Chef::Mixin::DeepMerge.merge(v_n.config, config)
|
212
203
|
v_n.send(:execute)
|
213
|
-
|
204
|
+
index += 1
|
205
|
+
[v_n, v_n.lxc.name, config]
|
214
206
|
end
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
207
|
+
run_specs = [cluster[:provision] || :every].flatten.compact.map(&:to_sym)
|
208
|
+
after = cluster[:after] || Mash.new
|
209
|
+
(cluster[:provision] || 1).to_i.times do |i|
|
210
|
+
count = i + 1
|
211
|
+
test_nodes.each do |node|
|
212
|
+
node_inst, lxc_name, config = node
|
213
|
+
node_inst._provision
|
214
|
+
## specs
|
215
|
+
if(run_specs.include?(:every) || run_specs.include?("after_#{count}".to_sym))
|
216
|
+
test_node!(node_inst.name, node_inst.lxc.container_ip, config)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
if(after[:every])
|
220
|
+
process_after(after[:every], test_nodes.map(&:first), cluster)
|
221
|
+
end
|
222
|
+
if(after[count.to_s])
|
223
|
+
process_after(after[count.to_s], test_nodes.map(&:first), cluster)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
destroy_server_if_needed
|
228
|
+
end
|
229
|
+
|
230
|
+
def process_after(after, nodes, cluster_config)
|
231
|
+
if(after[:pause])
|
232
|
+
ui.info ui.color(" Pause run... (#{after[:pause]} seconds)")
|
233
|
+
sleep(after[:pause].to_f)
|
234
|
+
end
|
235
|
+
if(after[:run])
|
236
|
+
run_coms = []
|
237
|
+
if(after[:run].is_a?(String))
|
238
|
+
run_coms << [after[:run], nodes]
|
239
|
+
else
|
240
|
+
if(after[:run][:on])
|
241
|
+
after[:run][:on].each do |dest, com|
|
242
|
+
on_nodes = dest.map do |n|
|
243
|
+
nodes[cluster_config[:nodes].index(n)]
|
244
|
+
end.compact
|
245
|
+
run_coms << [com, on_nodes]
|
246
|
+
end
|
247
|
+
after[:run].delete(:on)
|
248
|
+
end
|
249
|
+
# NOTE: This is just for where `:on` key is missed or people
|
250
|
+
# just want to be lazy
|
251
|
+
after[:run].each_pair do |dest, com|
|
252
|
+
on_nodes = dest.map do |n|
|
253
|
+
nodes[cluster_config[:nodes].index(n)]
|
254
|
+
end.compact
|
255
|
+
run_coms << [com, on_nodes]
|
256
|
+
end
|
257
|
+
end
|
258
|
+
run_coms.each do |com_pair|
|
259
|
+
com_pair.last.each do |node_inst|
|
260
|
+
node_inst.direct_container_command(com_pair.first, :live_stream => STDOUT)
|
261
|
+
end
|
262
|
+
end
|
219
263
|
end
|
220
264
|
end
|
221
265
|
|
222
|
-
def test_node!(name, ip_address,
|
223
|
-
|
266
|
+
def test_node!(name, ip_address, node_config)
|
267
|
+
test_files = []
|
268
|
+
Array(node_config[:run_list]).each do |item|
|
224
269
|
r_item = item.is_a?(Chef::RunList::RunListItem) ? item : Chef::RunList::RunListItem.new(item)
|
225
270
|
dir = File.join(File.dirname(vagabondfile.path), "spec/#{r_item.type}/#{r_item.name.sub('::', '/')}")
|
226
271
|
dir << '/default' if r_item.type.to_sym == :recipe && !r_item.name.include?('::')
|
227
|
-
Dir.glob(File.join(dir, '*.rb')).
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
272
|
+
test_files += Dir.glob(File.join(dir, '*.rb')).map(&:to_s)
|
273
|
+
end
|
274
|
+
Array(node_config[:custom_specs]).each do |custom|
|
275
|
+
dir = File.join(vagabondfile.directory, 'spec/custom', File.join(*custom.split('::')))
|
276
|
+
test_files += Dir.glob(File.join(dir, '*.rb')).map(&:to_s)
|
277
|
+
end
|
278
|
+
test_files.flatten.compact.each do |path|
|
279
|
+
ui.info "\n#{ui.color('**', :green, :bold)} Running spec: #{path.sub("#{vagabondfile.directory}/", '')}"
|
280
|
+
cmd = build_command("rspec #{path}", :live_stream => STDOUT, :shellout => {:env => {'VAGABOND_TEST_HOST' => ip_address}})
|
281
|
+
cmd.run_command
|
282
|
+
cmd.error!
|
234
283
|
end
|
235
|
-
end
|
236
|
-
|
237
|
-
def load_layout
|
238
|
-
# Load up layouts and set defaults
|
239
|
-
@layout = Layout.new(File.dirname(vagabondfile.path))
|
240
284
|
end
|
241
285
|
|
242
286
|
def vagabond_instance(action, args={})
|
@@ -270,8 +314,10 @@ module Vagabond
|
|
270
314
|
if(name)
|
271
315
|
clusters = [name]
|
272
316
|
else
|
273
|
-
|
274
|
-
clusters
|
317
|
+
clusters = Mash.new
|
318
|
+
clusters.merge!(vagabondfile[:clusters] || Mash.new)
|
319
|
+
clusters.merge!(vagabondfile[:specs][:clusters] || Mash.new)
|
320
|
+
clusters = clusters.keys.sort
|
275
321
|
end
|
276
322
|
clusters.each do |cluster|
|
277
323
|
ui.info "#{ui.color('Status of spec cluster:', :bold)} #{ui.color(cluster, :yellow)}"
|
@@ -301,24 +347,6 @@ module Vagabond
|
|
301
347
|
internal_config.save
|
302
348
|
end
|
303
349
|
|
304
|
-
CONTENT_DEFAULT_LAYOUT = <<-EOF
|
305
|
-
{
|
306
|
-
:defaults => {
|
307
|
-
:platform => 'ubuntu_1204',
|
308
|
-
:environment => nil
|
309
|
-
},
|
310
|
-
:definitions => {
|
311
|
-
:example_node => {
|
312
|
-
:run_list => %w(role[example])
|
313
|
-
}
|
314
|
-
},
|
315
|
-
:clusters => {
|
316
|
-
:example_cluster => {
|
317
|
-
:nodes => ['example_node']
|
318
|
-
}
|
319
|
-
}
|
320
|
-
}
|
321
|
-
EOF
|
322
350
|
CONTENT_DEFAULT_SPEC_HELPER = <<-EOF
|
323
351
|
require 'serverspec'
|
324
352
|
require 'pathname'
|
@@ -341,5 +369,3 @@ EOF
|
|
341
369
|
|
342
370
|
end
|
343
371
|
end
|
344
|
-
|
345
|
-
|
data/lib/vagabond/uploader.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
#encoding: utf-8
|
1
2
|
Dir.new(File.join(File.dirname(__FILE__), 'uploader')).each do |file|
|
2
3
|
next if file.start_with?('.') || !file.end_with?('.rb')
|
3
4
|
require "vagabond/uploader/#{file}"
|
@@ -11,13 +12,15 @@ module Vagabond
|
|
11
12
|
attr_reader :store
|
12
13
|
attr_reader :options
|
13
14
|
attr_reader :ui
|
15
|
+
attr_reader :vagabondfile
|
14
16
|
|
15
17
|
include Helpers
|
16
18
|
|
17
|
-
def initialize(base_directory, options={})
|
19
|
+
def initialize(vagabondfile, base_directory, options={})
|
18
20
|
@store = base_directory
|
19
21
|
@options = Mash.new(options)
|
20
22
|
@ui = options[:ui]
|
23
|
+
@vagabondfile = vagabondfile
|
21
24
|
end
|
22
25
|
|
23
26
|
def prepare
|
@@ -1,3 +1,4 @@
|
|
1
|
+
#encoding: utf-8
|
1
2
|
require 'vagabond/uploader/knife'
|
2
3
|
|
3
4
|
module Vagabond
|
@@ -34,7 +35,7 @@ module Vagabond
|
|
34
35
|
|
35
36
|
def vendor(*args)
|
36
37
|
FileUtils.mkdir_p(ckbk_store = File.join(store, 'cookbooks'))
|
37
|
-
com = "berks install -b #{options[:berksfile]} -p #{ckbk_store}"
|
38
|
+
com = "berks install -b #{options[:berksfile]} -p #{ckbk_store} #{Array(options[:berks_opts]).compact.flatten.join(' ')}"
|
38
39
|
debug(com)
|
39
40
|
cmd = Mixlib::ShellOut.new(com, :live_stream => options[:debug])
|
40
41
|
cmd.run_command
|
@@ -1,3 +1,4 @@
|
|
1
|
+
#encoding: utf-8
|
1
2
|
require 'vagabond/uploader'
|
2
3
|
|
3
4
|
module Vagabond
|
@@ -6,18 +7,11 @@ module Vagabond
|
|
6
7
|
|
7
8
|
def upload(*args)
|
8
9
|
prepare unless args.include?(:no_prepare)
|
9
|
-
com = "
|
10
|
+
com = "cookbook upload#{options[:knife_opts]} --all"
|
10
11
|
if(options[:cookbook_paths])
|
11
12
|
com << " --cookbook-path #{Array(options[:cookbook_paths]).join(':')}"
|
12
13
|
end
|
13
|
-
|
14
|
-
com << " --config #{knife_config}"
|
15
|
-
end
|
16
|
-
debug(com)
|
17
|
-
cmd = Mixlib::ShellOut.new(com,
|
18
|
-
:live_stream => options[:debug],
|
19
|
-
:cwd => store
|
20
|
-
)
|
14
|
+
cmd = knife_command(com, :cwd => store)
|
21
15
|
cmd.run_command
|
22
16
|
cmd.error!
|
23
17
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
#encoding: utf-8
|
1
2
|
require 'vagabond/uploader/knife'
|
2
3
|
|
3
4
|
module Vagabond
|
@@ -20,11 +21,7 @@ module Vagabond
|
|
20
21
|
else
|
21
22
|
com = "librarian-chef install --path=#{File.join(store, 'cookbooks')}"
|
22
23
|
end
|
23
|
-
|
24
|
-
cmd = Mixlib::ShellOut.new(com,
|
25
|
-
:live_stream => options[:debug],
|
26
|
-
:cwd => File.dirname(options[:cheffile])
|
27
|
-
)
|
24
|
+
cmd = build_command(com, :shellout => {:cwd => File.dirname(options[:cheffile])})
|
28
25
|
cmd.run_command
|
29
26
|
cmd.error!
|
30
27
|
options[:cookbook_paths] = [File.join(store, 'cookbooks')]
|
data/lib/vagabond/vagabond.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
+
#encoding: utf-8
|
1
2
|
require 'thor'
|
2
3
|
require 'chef/knife/core/ui'
|
3
4
|
require 'vagabond/uploader'
|
4
|
-
require
|
5
|
+
require 'elecksee/lxc'
|
5
6
|
|
6
7
|
%w(constants errors vagabondfile internal_configuration helpers).each do |dep|
|
7
8
|
require "vagabond/#{dep}"
|
@@ -17,6 +18,8 @@ end
|
|
17
18
|
|
18
19
|
module Vagabond
|
19
20
|
class Vagabond < Thor
|
21
|
+
|
22
|
+
DISABLE_HOST_SOLO_ON = %w(status init)
|
20
23
|
|
21
24
|
include Thor::Actions
|
22
25
|
include Helpers
|
@@ -26,52 +29,51 @@ module Vagabond
|
|
26
29
|
include klass if klass.is_a?(Module)
|
27
30
|
end
|
28
31
|
|
29
|
-
attr_reader :name
|
30
|
-
attr_reader :vagabondfile
|
31
|
-
attr_reader :internal_config
|
32
|
-
attr_reader :ui
|
33
|
-
attr_reader :options
|
34
|
-
|
35
32
|
attr_accessor :mappings_key
|
36
33
|
attr_accessor :lxc
|
37
34
|
attr_accessor :config
|
38
35
|
attr_accessor :action
|
39
36
|
|
40
37
|
CLI_OPTIONS = lambda do
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
38
|
+
class_option(:debug,
|
39
|
+
:type => :boolean,
|
40
|
+
:default => false
|
41
|
+
)
|
42
|
+
|
43
|
+
class_option(:force_solo,
|
44
|
+
:aliases => '--force-configure',
|
45
|
+
:type => :boolean,
|
46
|
+
:default => false,
|
47
|
+
:desc => 'Force configuration of system'
|
48
|
+
)
|
49
|
+
|
50
|
+
class_option(:color,
|
51
|
+
:type => :boolean,
|
52
|
+
:default => true,
|
53
|
+
:desc => 'Enable/disable colorized output'
|
54
|
+
)
|
55
|
+
|
56
|
+
class_option(:vagabond_file,
|
57
|
+
:aliases => '-f',
|
58
|
+
:type => :string,
|
59
|
+
:desc => 'Provide path to Vagabondfile'
|
60
|
+
)
|
61
|
+
|
62
|
+
class_option(:local_server,
|
63
|
+
:type => :boolean,
|
64
|
+
:default => true,
|
65
|
+
:desc => 'Enable/disable local Chef server usage if available'
|
66
|
+
)
|
67
|
+
|
68
|
+
class_option(:callbacks,
|
69
|
+
:type => :boolean,
|
70
|
+
:default => true,
|
71
|
+
:desc => 'Enable/disable action callbacks'
|
72
|
+
)
|
70
73
|
end
|
71
74
|
|
72
75
|
CLI_OPTIONS.call
|
73
76
|
|
74
|
-
|
75
77
|
# action:: Action to perform
|
76
78
|
# name:: Name of vagabond
|
77
79
|
# config:: Hash configuration
|
@@ -101,8 +103,14 @@ module Vagabond
|
|
101
103
|
end
|
102
104
|
end
|
103
105
|
define_method meth do |*args|
|
104
|
-
|
105
|
-
|
106
|
+
@original_args = args.dup
|
107
|
+
unless(args.include?(:no_setup))
|
108
|
+
setup(meth, *args)
|
109
|
+
end
|
110
|
+
result = execute
|
111
|
+
callbacks(meth)
|
112
|
+
chain!
|
113
|
+
result
|
106
114
|
end
|
107
115
|
end
|
108
116
|
end
|
@@ -111,6 +119,16 @@ module Vagabond
|
|
111
119
|
|
112
120
|
protected
|
113
121
|
|
122
|
+
def attributes
|
123
|
+
if(config[:attributes])
|
124
|
+
if(config[:attributes].is_a?(Hash))
|
125
|
+
JSON.dump(config[:attributes])
|
126
|
+
else
|
127
|
+
config[:attributes].to_s
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
114
132
|
def version
|
115
133
|
setup_ui
|
116
134
|
ui.info "#{ui.color('Vagabond:', :yellow, :bold)} - Advocating idleness and work-shyness"
|
@@ -119,25 +137,22 @@ module Vagabond
|
|
119
137
|
end
|
120
138
|
|
121
139
|
def execute
|
122
|
-
self.send("_#{
|
140
|
+
self.send("_#{action}")
|
123
141
|
end
|
124
142
|
|
125
143
|
def setup(action, name=nil, *args)
|
126
144
|
@action = action
|
127
145
|
@name = name
|
128
|
-
|
129
|
-
if(
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
setup_ui(_ui)
|
135
|
-
load_configurations
|
136
|
-
if(respond_to?(check = "#{action}_validate?".to_sym))
|
137
|
-
validate! if send(check)
|
146
|
+
hash_args = args.detect{|x|x.is_a?(Hash)}
|
147
|
+
if(hash_args)
|
148
|
+
args.delete(hash_args)
|
149
|
+
_ui = hash_args.delete(:ui)
|
150
|
+
base_setup(_ui)
|
151
|
+
config.merge!(hash_args)
|
138
152
|
else
|
139
|
-
|
153
|
+
base_setup
|
140
154
|
end
|
155
|
+
@leftover_args = args
|
141
156
|
end
|
142
157
|
|
143
158
|
def name_required!
|
@@ -150,45 +165,17 @@ module Vagabond
|
|
150
165
|
def provision_solo(dir)
|
151
166
|
ui.info "#{ui.color('Vagabond:', :bold)} Provisioning node: #{ui.color(name, :magenta)}"
|
152
167
|
lxc.container_ip(20) # force wait for container to appear and do so quietly
|
153
|
-
direct_container_command(
|
168
|
+
cmd = direct_container_command(
|
154
169
|
"chef-solo -c #{File.join(dir, 'solo.rb')} -j #{File.join(dir, 'dna.json')}",
|
155
170
|
:live_stream => STDOUT
|
156
171
|
)
|
172
|
+
raise VagabondError::NodeProvisionFailed.new("Failed to provision: #{name}") unless cmd
|
157
173
|
end
|
158
174
|
|
159
|
-
def load_configurations
|
160
|
-
@vagabondfile = Vagabondfile.new(options[:vagabond_file], :allow_missing)
|
161
|
-
options[:sudo] = sudo
|
162
|
-
# TODO: provide action call back for full or partial solo disable
|
163
|
-
if((@action.to_s == 'status' && lxc_installed?) || @action.to_s == 'init')
|
164
|
-
options[:disable_solo] = true
|
165
|
-
end
|
166
|
-
Chef::Log.init('/dev/null') unless options[:debug]
|
167
|
-
Lxc.use_sudo = @vagabondfile[:sudo].nil? ? true : @vagabondfile[:sudo]
|
168
|
-
@internal_config = InternalConfiguration.new(@vagabondfile, ui, options)
|
169
|
-
options[:disable_solo] = false if @action.to_s == 'init'
|
170
|
-
@config = @vagabondfile[:boxes][name]
|
171
|
-
@lxc = Lxc.new(@internal_config[mappings_key][name] || '____nonreal____')
|
172
|
-
if(options[:local_server] && lxc_installed?)
|
173
|
-
if(@vagabondfile[:local_chef_server] && @vagabondfile[:local_chef_server][:enabled])
|
174
|
-
srv_name = @internal_config[:mappings][:server]
|
175
|
-
srv = Lxc.new(srv_name) if srv_name
|
176
|
-
if(srv_name && srv.running?)
|
177
|
-
proto = @vagabondfile[:local_chef_server][:zero] ? 'http' : 'https'
|
178
|
-
options[:knife_opts] = " --server-url #{proto}://#{srv.container_ip(10, true)}"
|
179
|
-
else
|
180
|
-
unless(@action.to_sym == :status || name.to_s =='server')
|
181
|
-
ui.warn 'Local chef server is not currently running!' unless @action.to_sym == :status
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
175
|
def validate!
|
189
176
|
if(name.to_s == 'server')
|
190
177
|
ui.fatal "RESERVED node name supplied: #{ui.color(name, :red)}"
|
191
|
-
ui.info ui.color(" -> Try: vagabond server #{
|
178
|
+
ui.info ui.color(" -> Try: vagabond server #{action}", :cyan)
|
192
179
|
raise VagabondError::ReservedName.new(name)
|
193
180
|
end
|
194
181
|
if(name && config.nil? && !options[:disable_name_validate])
|
@@ -199,7 +186,7 @@ module Vagabond
|
|
199
186
|
end
|
200
187
|
|
201
188
|
def check_existing!
|
202
|
-
if(
|
189
|
+
if(lxc.exists?)
|
203
190
|
ui.error "LXC: #{name} already exists!"
|
204
191
|
true
|
205
192
|
end
|
@@ -213,20 +200,17 @@ module Vagabond
|
|
213
200
|
File.join(base_dir, '.vagabond')
|
214
201
|
end
|
215
202
|
|
216
|
-
def lxc_installed?
|
217
|
-
system('which lxc-info > /dev/null')
|
218
|
-
end
|
219
|
-
|
220
203
|
def wait_for_completion(type=nil)
|
204
|
+
@threads ||= []
|
221
205
|
if(type)
|
222
|
-
Array(@threads[
|
206
|
+
Array(@threads[type]).collect{|hsh| hsh[:thread]}.map(&:join)
|
223
207
|
else
|
224
|
-
@threads.values.
|
225
|
-
threads.each do |thread_set|
|
226
|
-
Array(thread_set).map(&:join)
|
227
|
-
end
|
228
|
-
end
|
208
|
+
@threads.values.flatten.collect{|hsh| hsh[:thread]}.map(&:join)
|
229
209
|
end
|
230
210
|
end
|
211
|
+
|
212
|
+
def tasks(type=nil)
|
213
|
+
type ? @threads[type] : @threads
|
214
|
+
end
|
231
215
|
end
|
232
216
|
end
|