vagabond 0.2.0 → 0.2.2
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/CHANGELOG.md +18 -0
- data/README.md +125 -4
- data/bin/vagabond +43 -16
- data/lib/vagabond/actions/cluster.rb +66 -0
- data/lib/vagabond/actions/create.rb +12 -7
- data/lib/vagabond/actions/destroy.rb +69 -15
- data/lib/vagabond/actions/init.rb +75 -0
- data/lib/vagabond/actions/provision.rb +4 -2
- data/lib/vagabond/actions/status.rb +33 -22
- data/lib/vagabond/actions/up.rb +8 -1
- data/lib/vagabond/bootstraps/server-zero.erb +20 -0
- data/lib/vagabond/bootstraps/server.erb +3 -2
- data/lib/vagabond/constants.rb +0 -15
- data/lib/vagabond/cookbooks/lxc/CHANGELOG.md +16 -0
- data/lib/vagabond/cookbooks/lxc/Gemfile +3 -2
- data/lib/vagabond/cookbooks/lxc/Gemfile.lock +30 -121
- data/lib/vagabond/cookbooks/lxc/README.md +43 -14
- data/lib/vagabond/cookbooks/lxc/attributes/default.rb +3 -3
- data/lib/vagabond/cookbooks/lxc/files/default/lxc-awesome-ephemeral +499 -0
- data/lib/vagabond/cookbooks/lxc/libraries/lxc.rb +223 -58
- data/lib/vagabond/cookbooks/lxc/libraries/lxc_file_config.rb +3 -0
- data/lib/vagabond/cookbooks/lxc/libraries/monkey.rb +51 -0
- data/lib/vagabond/cookbooks/lxc/metadata.rb +6 -5
- data/lib/vagabond/cookbooks/lxc/providers/config.rb +9 -16
- data/lib/vagabond/cookbooks/lxc/providers/container.rb +241 -229
- data/lib/vagabond/cookbooks/lxc/providers/default.rb +57 -0
- data/lib/vagabond/cookbooks/lxc/providers/ephemeral.rb +40 -0
- data/lib/vagabond/cookbooks/lxc/providers/fstab.rb +13 -54
- data/lib/vagabond/cookbooks/lxc/providers/interface.rb +13 -67
- data/lib/vagabond/cookbooks/lxc/providers/service.rb +14 -14
- data/lib/vagabond/cookbooks/lxc/recipes/default.rb +17 -4
- data/lib/vagabond/cookbooks/lxc/recipes/install_dependencies.rb +1 -1
- data/lib/vagabond/cookbooks/lxc/resources/config.rb +2 -2
- data/lib/vagabond/cookbooks/lxc/resources/container.rb +31 -6
- data/lib/vagabond/cookbooks/lxc/resources/default.rb +12 -0
- data/lib/vagabond/cookbooks/lxc/resources/ephemeral.rb +13 -0
- data/lib/vagabond/cookbooks/lxc/resources/fstab.rb +2 -1
- data/lib/vagabond/cookbooks/lxc/resources/interface.rb +6 -3
- data/lib/vagabond/cookbooks/lxc/resources/service.rb +1 -1
- data/lib/vagabond/cookbooks/lxc/templates/default/file_content.erb +2 -0
- data/lib/vagabond/cookbooks/lxc/templates/default/interface.erb +9 -3
- data/lib/vagabond/cookbooks/vagabond/README.md +10 -0
- data/lib/vagabond/cookbooks/vagabond/attributes/default.rb +1 -0
- data/lib/vagabond/cookbooks/vagabond/files/default/lxc-centos +13 -6
- data/lib/vagabond/cookbooks/vagabond/metadata.rb +1 -0
- data/lib/vagabond/cookbooks/vagabond/recipes/default.rb +46 -4
- data/lib/vagabond/cookbooks/vagabond/recipes/zero.rb +9 -0
- data/lib/vagabond/errors.rb +23 -0
- data/lib/vagabond/helpers.rb +41 -14
- data/lib/vagabond/internal_configuration.rb +120 -27
- data/lib/vagabond/kitchen.rb +143 -63
- data/lib/vagabond/knife.rb +8 -5
- data/lib/vagabond/layout.rb +16 -0
- data/lib/vagabond/monkey/kitchen_config.rb +23 -0
- data/lib/vagabond/server.rb +79 -63
- data/lib/vagabond/spec.rb +345 -0
- data/lib/vagabond/uploader.rb +30 -0
- data/lib/vagabond/uploader/berkshelf.rb +53 -0
- data/lib/vagabond/uploader/knife.rb +24 -0
- data/lib/vagabond/uploader/librarian.rb +31 -0
- data/lib/vagabond/vagabond.rb +30 -11
- data/lib/vagabond/vagabondfile.rb +40 -5
- data/lib/vagabond/version.rb +1 -1
- data/vagabond.gemspec +5 -2
- metadata +75 -15
- data/lib/vagabond/cookbooks/lxc/resources/#container.rb# +0 -28
- data/lib/vagabond/cookbooks/lxc/test/kitchen/Kitchenfile +0 -7
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/metadata.rb +0 -2
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/centos_lxc.rb +0 -0
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/chef-bootstrap.rb +0 -0
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/lxc_files.rb +0 -0
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/lxc_templates.rb +0 -0
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/ubuntu_lxc.rb +0 -0
@@ -1,12 +1,95 @@
|
|
1
|
+
require 'mixlib/shellout'
|
2
|
+
require 'pathname'
|
3
|
+
require 'tmpdir'
|
4
|
+
|
1
5
|
class Lxc
|
2
6
|
class CommandFailed < StandardError
|
3
7
|
end
|
8
|
+
|
9
|
+
module Helpers
|
10
|
+
|
11
|
+
# Simple helper to shell out
|
12
|
+
def run_command(cmd, args={})
|
13
|
+
retries = args[:allow_failure_retry].to_i
|
14
|
+
begin
|
15
|
+
shlout = Mixlib::ShellOut.new(cmd,
|
16
|
+
:logger => defined?(Chef::Log) ? Chef::Log.logger : log,
|
17
|
+
:live_stream => args[:livestream] ? STDOUT : nil,
|
18
|
+
:timeout => args[:timeout] || 1200,
|
19
|
+
:environment => {'HOME' => detect_home}
|
20
|
+
)
|
21
|
+
shlout.run_command
|
22
|
+
shlout.error!
|
23
|
+
shlout
|
24
|
+
rescue Mixlib::ShellOut::ShellCommandFailed, CommandFailed, Mixlib::ShellOut::CommandTimeout
|
25
|
+
if(retries > 0)
|
26
|
+
log.warn "LXC run command failed: #{cmd}"
|
27
|
+
log.warn "Retrying command. #{args[:allow_failure_retry].to_i - retries} of #{args[:allow_failure_retry].to_i} retries remain"
|
28
|
+
sleep(0.3)
|
29
|
+
retries -= 1
|
30
|
+
retry
|
31
|
+
elsif(args[:allow_failure])
|
32
|
+
true
|
33
|
+
else
|
34
|
+
raise
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def command(*args)
|
40
|
+
run_command(*args)
|
41
|
+
end
|
42
|
+
|
43
|
+
def log
|
44
|
+
if(defined?(Chef::Log))
|
45
|
+
Chef::Log
|
46
|
+
else
|
47
|
+
unless(@logger)
|
48
|
+
require 'logger'
|
49
|
+
@logger = Logger.new('/dev/null')
|
50
|
+
end
|
51
|
+
@logger
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Detect HOME environment variable. If not an acceptable
|
56
|
+
# value, set to /root or /tmp
|
57
|
+
def detect_home(set_if_missing=false)
|
58
|
+
if(ENV['HOME'] && Pathname.new(ENV['HOME']).absolute?)
|
59
|
+
ENV['HOME']
|
60
|
+
else
|
61
|
+
home = File.directory?('/root') && File.writable?('/root') ? '/root' : '/tmp'
|
62
|
+
if(set_if_missing)
|
63
|
+
ENV['HOME'] = home
|
64
|
+
end
|
65
|
+
home
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Pathname#join does not act like File#join when joining paths that
|
71
|
+
# begin with '/', and that's dumb. So we'll make our own Pathname,
|
72
|
+
# with a #join that uses File
|
73
|
+
class Pathname < ::Pathname
|
74
|
+
def join(*args)
|
75
|
+
self.class.new(::File.join(self.to_path, *args))
|
76
|
+
end
|
77
|
+
end
|
4
78
|
|
5
|
-
|
79
|
+
include Helpers
|
80
|
+
|
81
|
+
attr_reader :name, :base_path, :lease_file, :preferred_device
|
6
82
|
|
7
83
|
class << self
|
8
84
|
|
85
|
+
include Helpers
|
86
|
+
|
9
87
|
attr_accessor :use_sudo
|
88
|
+
attr_accessor :base_path
|
89
|
+
|
90
|
+
def base_path
|
91
|
+
@base_path || '/var/lib/lxc'
|
92
|
+
end
|
10
93
|
|
11
94
|
def sudo
|
12
95
|
case use_sudo
|
@@ -40,19 +123,28 @@ class Lxc
|
|
40
123
|
|
41
124
|
# List of containers
|
42
125
|
def list
|
43
|
-
|
126
|
+
Dir.glob(File.join(base_path, '*')).map do |item|
|
127
|
+
if(File.directory?(item) && File.exists?(File.join(item, 'config')))
|
128
|
+
File.basename(item)
|
129
|
+
end
|
130
|
+
end.compact
|
44
131
|
end
|
45
|
-
|
132
|
+
|
46
133
|
# name:: Name of container
|
47
134
|
# Returns information about given container
|
48
135
|
def info(name)
|
49
136
|
res = {:state => nil, :pid => nil}
|
50
|
-
info =
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
137
|
+
info = run_command("#{sudo}lxc-info -n #{name}").stdout.split("\n")
|
138
|
+
if(info.first)
|
139
|
+
parts = info.first.split(' ')
|
140
|
+
res[:state] = parts.last.downcase.to_sym
|
141
|
+
parts = info.last.split(' ')
|
142
|
+
res[:pid] = parts.last.to_i
|
143
|
+
res
|
144
|
+
else
|
145
|
+
res[:state] = :unknown
|
146
|
+
res[:pid] = -1
|
147
|
+
end
|
56
148
|
end
|
57
149
|
|
58
150
|
# Return full container information list
|
@@ -78,10 +170,12 @@ class Lxc
|
|
78
170
|
# args:: Argument hash
|
79
171
|
# - :base_path -> path to container directory
|
80
172
|
# - :dnsmasq_lease_file -> path to lease file
|
173
|
+
# - :net_device -> network device to use within container for ssh connection
|
81
174
|
def initialize(name, args={})
|
82
175
|
@name = name
|
83
|
-
@base_path = args[:base_path] ||
|
176
|
+
@base_path = args[:base_path] || self.class.base_path
|
84
177
|
@lease_file = args[:dnsmasq_lease_file] || '/var/lib/misc/dnsmasq.leases'
|
178
|
+
@preferred_device = args[:net_device]
|
85
179
|
end
|
86
180
|
|
87
181
|
# Returns if container exists
|
@@ -109,8 +203,20 @@ class Lxc
|
|
109
203
|
def container_ip(retries=0, raise_on_fail=false)
|
110
204
|
(retries.to_i + 1).times do
|
111
205
|
ip = proc_detected_address || hw_detected_address || leased_address || lxc_stored_address
|
206
|
+
if(ip.is_a?(Array))
|
207
|
+
# Filter any found loopbacks
|
208
|
+
ip.delete_if{|info| info[:device].start_with?('lo') }
|
209
|
+
ip = ip.detect do |info|
|
210
|
+
if(@preferred_device)
|
211
|
+
info[:device] == @preferred_device
|
212
|
+
else
|
213
|
+
true
|
214
|
+
end
|
215
|
+
end
|
216
|
+
ip = ip[:address] if ip
|
217
|
+
end
|
112
218
|
return ip if ip && self.class.connection_alive?(ip)
|
113
|
-
|
219
|
+
log.warn "LXC IP discovery: Failed to detect live IP"
|
114
220
|
sleep(3) if retries > 0
|
115
221
|
end
|
116
222
|
raise "Failed to detect live IP address for container: #{name}" if raise_on_fail
|
@@ -125,7 +231,7 @@ class Lxc
|
|
125
231
|
if(ip.to_s.empty?)
|
126
232
|
nil
|
127
233
|
else
|
128
|
-
|
234
|
+
log.info "LXC Discovery: Found container address via storage: #{ip}"
|
129
235
|
ip
|
130
236
|
end
|
131
237
|
end
|
@@ -145,25 +251,27 @@ class Lxc
|
|
145
251
|
if(ip.to_s.empty?)
|
146
252
|
nil
|
147
253
|
else
|
148
|
-
|
254
|
+
log.info "LXC Discovery: Found container address via DHCP lease: #{ip}"
|
149
255
|
ip
|
150
256
|
end
|
151
257
|
end
|
152
258
|
|
153
259
|
def hw_detected_address
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
260
|
+
if(container_config.readable?)
|
261
|
+
hw = File.readlines(container_config).detect{|line|
|
262
|
+
line.include?('hwaddr')
|
263
|
+
}.to_s.split('=').last.to_s.downcase
|
264
|
+
if(File.exists?(container_config) && !hw.empty?)
|
265
|
+
running? # need to do a list!
|
266
|
+
ip = File.readlines('/proc/net/arp').detect{|line|
|
267
|
+
line.downcase.include?(hw)
|
268
|
+
}.to_s.split(' ').first.to_s.strip
|
269
|
+
if(ip.to_s.empty?)
|
270
|
+
nil
|
271
|
+
else
|
272
|
+
log.info "LXC Discovery: Found container address via HW addr: #{ip}"
|
273
|
+
ip
|
274
|
+
end
|
167
275
|
end
|
168
276
|
end
|
169
277
|
end
|
@@ -177,8 +285,11 @@ class Lxc
|
|
177
285
|
system("#{sudo}ln -s /proc/#{pid}/ns/net #{path}")
|
178
286
|
res = %x{#{sudo}ip netns exec #{name} ip -4 addr show scope global | grep inet}
|
179
287
|
system("#{sudo}rm -f #{path}")
|
180
|
-
|
181
|
-
|
288
|
+
ips = res.split("\n").map do |line|
|
289
|
+
parts = line.split(' ')
|
290
|
+
{:address => parts[1].to_s.sub(%r{/.+$}, ''), :device => parts.last}
|
291
|
+
end
|
292
|
+
ips.empty? ? nil : ips
|
182
293
|
end
|
183
294
|
end
|
184
295
|
end
|
@@ -189,23 +300,23 @@ class Lxc
|
|
189
300
|
|
190
301
|
# Full path to container
|
191
302
|
def container_path
|
192
|
-
|
303
|
+
Pathname.new(@base_path).join(name)
|
193
304
|
end
|
194
305
|
alias_method :path, :container_path
|
195
306
|
|
196
307
|
# Full path to container configuration file
|
197
308
|
def container_config
|
198
|
-
|
309
|
+
container_path.join('config')
|
199
310
|
end
|
200
311
|
alias_method :config, :container_config
|
201
312
|
|
202
313
|
def container_rootfs
|
203
|
-
|
314
|
+
container_path.join('rootfs')
|
204
315
|
end
|
205
316
|
alias_method :rootfs, :container_rootfs
|
206
317
|
|
207
318
|
def expand_path(path)
|
208
|
-
|
319
|
+
container_rootfs.join(path)
|
209
320
|
end
|
210
321
|
|
211
322
|
def state
|
@@ -217,68 +328,82 @@ class Lxc
|
|
217
328
|
end
|
218
329
|
|
219
330
|
# Start the container
|
220
|
-
def start
|
221
|
-
|
222
|
-
|
331
|
+
def start(*args)
|
332
|
+
if(args.include?(:no_daemon))
|
333
|
+
run_command("#{sudo}lxc-start -n #{name}")
|
334
|
+
else
|
335
|
+
run_command("#{sudo}lxc-start -n #{name} -d")
|
336
|
+
wait_for_state(:running)
|
337
|
+
end
|
223
338
|
end
|
224
339
|
|
225
340
|
# Stop the container
|
226
341
|
def stop
|
227
342
|
run_command("#{sudo}lxc-stop -n #{name}", :allow_failure_retry => 3)
|
228
|
-
|
343
|
+
wait_for_state(:stopped)
|
229
344
|
end
|
230
345
|
|
231
346
|
# Freeze the container
|
232
347
|
def freeze
|
233
348
|
run_command("#{sudo}lxc-freeze -n #{name}")
|
234
|
-
|
349
|
+
wait_for_state(:frozen)
|
235
350
|
end
|
236
351
|
|
237
352
|
# Unfreeze the container
|
238
353
|
def unfreeze
|
239
354
|
run_command("#{sudo}lxc-unfreeze -n #{name}")
|
240
|
-
|
355
|
+
wait_for_state(:running)
|
241
356
|
end
|
242
357
|
|
243
358
|
# Shutdown the container
|
244
359
|
def shutdown
|
245
360
|
run_command("#{sudo}lxc-shutdown -n #{name}")
|
246
|
-
|
361
|
+
wait_for_state(:stopped, :timeout => 120)
|
362
|
+
# This block is for fedora/centos/anyone else that does not like lxc-shutdown
|
247
363
|
if(running?)
|
248
364
|
container_command('shutdown -h now')
|
249
|
-
|
365
|
+
wait_for_state(:stopped, :timeout => 120)
|
366
|
+
# If still running here, something is wrong
|
367
|
+
if(running?)
|
368
|
+
raise "Failed to shutdown container: #{name}"
|
369
|
+
end
|
250
370
|
end
|
251
371
|
end
|
252
372
|
|
253
|
-
def
|
254
|
-
|
255
|
-
Chef::Knife::Ssh.load_deps
|
256
|
-
k = Chef::Knife::Ssh.new([
|
257
|
-
ip, '-m', '-i', '/opt/hw-lxc-config/id_rsa', '--no-host-key-verify', cmd
|
258
|
-
])
|
259
|
-
e = nil
|
373
|
+
def direct_container_command(command, args={})
|
374
|
+
com = "#{sudo}ssh root@#{args[:ip] || container_ip} -i /opt/hw-lxc-config/id_rsa -oStrictHostKeyChecking=no '#{command}'"
|
260
375
|
begin
|
261
|
-
|
262
|
-
|
376
|
+
cmd = Mixlib::ShellOut.new(com,
|
377
|
+
:live_stream => args[:live_stream],
|
378
|
+
:timeout => args[:timeout] || 1200
|
379
|
+
)
|
380
|
+
cmd.run_command
|
381
|
+
cmd.error!
|
382
|
+
true
|
383
|
+
rescue
|
384
|
+
raise if args[:raise_on_failure]
|
385
|
+
false
|
263
386
|
end
|
264
|
-
raise CommandFailed.new(cmd) if e.nil? || e != 0
|
265
387
|
end
|
388
|
+
alias_method :knife_container, :direct_container_command
|
266
389
|
|
267
390
|
# Simple helper to shell out
|
268
391
|
def run_command(cmd, args={})
|
269
392
|
retries = args[:allow_failure_retry].to_i
|
270
393
|
begin
|
271
394
|
shlout = Mixlib::ShellOut.new(cmd,
|
272
|
-
:logger => Chef::Log.logger,
|
273
|
-
:live_stream => STDOUT,
|
274
|
-
:timeout => args[:timeout] || 1200
|
395
|
+
:logger => defined?(Chef::Log) ? Chef::Log.logger : log,
|
396
|
+
:live_stream => args[:livestream] ? nil : STDOUT,
|
397
|
+
:timeout => args[:timeout] || 1200,
|
398
|
+
:environment => {'HOME' => detect_home}
|
275
399
|
)
|
276
400
|
shlout.run_command
|
277
401
|
shlout.error!
|
402
|
+
shlout
|
278
403
|
rescue Mixlib::ShellOut::ShellCommandFailed, CommandFailed, Mixlib::ShellOut::CommandTimeout
|
279
404
|
if(retries > 0)
|
280
|
-
|
281
|
-
|
405
|
+
log.warn "LXC run command failed: #{cmd}"
|
406
|
+
log.warn "Retrying command. #{args[:allow_failure_retry].to_i - retries} of #{args[:allow_failure_retry].to_i} retries remain"
|
282
407
|
sleep(0.3)
|
283
408
|
retries -= 1
|
284
409
|
retry
|
@@ -290,16 +415,44 @@ class Lxc
|
|
290
415
|
end
|
291
416
|
end
|
292
417
|
|
418
|
+
def wait_for_state(desired_state, args={})
|
419
|
+
args[:sleep_interval] ||= 1.0
|
420
|
+
wait_total = 0.0
|
421
|
+
until(state == desired_state.to_sym || (args[:timeout].to_i > 0 && wait_total.to_i > args[:timeout].to_i))
|
422
|
+
sleep(args[:sleep_interval])
|
423
|
+
wait_total += args[:sleep_interval]
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
# Detect HOME environment variable. If not an acceptable
|
428
|
+
# value, set to /root or /tmp
|
429
|
+
def detect_home(set_if_missing=false)
|
430
|
+
if(ENV['HOME'] && Pathname.new(ENV['HOME']).absolute?)
|
431
|
+
ENV['HOME']
|
432
|
+
else
|
433
|
+
home = File.directory?('/root') && File.writable?('/root') ? '/root' : '/tmp'
|
434
|
+
if(set_if_missing)
|
435
|
+
ENV['HOME'] = home
|
436
|
+
end
|
437
|
+
home
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
293
441
|
# cmd:: Shell command string
|
294
442
|
# retries:: Number of retry attempts (1 second sleep interval)
|
295
443
|
# Runs command in container via ssh
|
296
444
|
def container_command(cmd, retries=1)
|
297
445
|
begin
|
298
|
-
|
446
|
+
detect_home(true)
|
447
|
+
direct_container_command(cmd,
|
448
|
+
:ip => container_ip(5),
|
449
|
+
:live_stream => STDOUT,
|
450
|
+
:raise_on_failure => true
|
451
|
+
)
|
299
452
|
rescue => e
|
300
453
|
if(retries.to_i > 0)
|
301
|
-
|
302
|
-
|
454
|
+
log.info "Encountered error running container command (#{cmd}): #{e}"
|
455
|
+
log.info "Retrying command..."
|
303
456
|
retries = retries.to_i - 1
|
304
457
|
sleep(1)
|
305
458
|
retry
|
@@ -309,4 +462,16 @@ class Lxc
|
|
309
462
|
end
|
310
463
|
end
|
311
464
|
|
465
|
+
def log
|
466
|
+
if(defined?(Chef::Log))
|
467
|
+
Chef::Log
|
468
|
+
else
|
469
|
+
unless(@logger)
|
470
|
+
require 'logger'
|
471
|
+
@logger = Logger.new('/dev/null')
|
472
|
+
end
|
473
|
+
@logger
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
312
477
|
end
|
@@ -7,6 +7,9 @@ class LxcFileConfig
|
|
7
7
|
def generate_config(resource)
|
8
8
|
config = []
|
9
9
|
config << "lxc.utsname = #{resource.utsname}"
|
10
|
+
if(resource.aa_profile)
|
11
|
+
config << "lxc.aa_profile = #{resource.aa_profile}"
|
12
|
+
end
|
10
13
|
[resource.network].flatten.each do |net_hash|
|
11
14
|
nhsh = Mash.new(net_hash)
|
12
15
|
flags = nhsh.delete(:flags)
|
@@ -0,0 +1,51 @@
|
|
1
|
+
unless(defined?(LxcMonkey))
|
2
|
+
require 'chef/resource/execute'
|
3
|
+
require 'chef/provider/execute'
|
4
|
+
|
5
|
+
module LxcMonkey
|
6
|
+
module Provider
|
7
|
+
class << self
|
8
|
+
def included(klass)
|
9
|
+
klass.class_eval do
|
10
|
+
alias_method :non_monkey_shell_out!, :shell_out!
|
11
|
+
alias_method :shell_out!, :monkey_shell_out!
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def monkey_shell_out!(com, opts)
|
17
|
+
if(str = @new_resource.stream_output)
|
18
|
+
opts[:live_stream] = str.kind_of?(IO) ? str : STDOUT
|
19
|
+
end
|
20
|
+
non_monkey_shell_out!(com, opts)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
module Resource
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def included(klass)
|
27
|
+
klass.class_eval do
|
28
|
+
alias_method :non_monkey_initialize, :initialize
|
29
|
+
alias_method :initialize, :monkey_initialize
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def monkey_initialize(*args)
|
35
|
+
non_monkey_initialize(*args)
|
36
|
+
@stream_output = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def stream_output(arg=nil)
|
40
|
+
set_or_return(
|
41
|
+
:stream_output,
|
42
|
+
arg,
|
43
|
+
:kind_of => [TrueClass,FalseClass,IO]
|
44
|
+
)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
Chef::Resource::Execute.send(:include, LxcMonkey::Resource)
|
50
|
+
Chef::Provider::Execute.send(:include, LxcMonkey::Provider)
|
51
|
+
end
|