elecksee 1.0.2 → 1.0.4
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 +4 -0
- data/bin/lxc-awesome-ephemeral +57 -2
- data/lib/elecksee/clone.rb +15 -0
- data/lib/elecksee/ephemeral.rb +310 -0
- data/lib/elecksee/helpers.rb +70 -0
- data/lib/elecksee/lxc.rb +409 -5
- data/lib/elecksee/lxc_file_config.rb +86 -0
- data/lib/elecksee/storage/overlay_directory.rb +31 -0
- data/lib/elecksee/storage/overlay_mount.rb +60 -0
- data/lib/elecksee/storage/virtual_device.rb +81 -0
- data/lib/elecksee/version.rb +1 -1
- metadata +9 -39
- data/Gemfile.lock +0 -18
- data/lib/elecksee/awesome.rb +0 -14
- data/lib/elecksee/vendor/lxc/CHANGELOG.md +0 -37
- data/lib/elecksee/vendor/lxc/Gemfile +0 -4
- data/lib/elecksee/vendor/lxc/Gemfile.lock +0 -41
- data/lib/elecksee/vendor/lxc/README.md +0 -112
- data/lib/elecksee/vendor/lxc/attributes/default.rb +0 -28
- data/lib/elecksee/vendor/lxc/files/default/knife_lxc +0 -228
- data/lib/elecksee/vendor/lxc/files/default/lxc-awesome-ephemeral +0 -495
- data/lib/elecksee/vendor/lxc/libraries/lxc.rb +0 -366
- data/lib/elecksee/vendor/lxc/libraries/lxc_expanded_resources.rb +0 -40
- data/lib/elecksee/vendor/lxc/libraries/lxc_file_config.rb +0 -84
- data/lib/elecksee/vendor/lxc/libraries/monkey.rb +0 -51
- data/lib/elecksee/vendor/lxc/metadata.rb +0 -12
- data/lib/elecksee/vendor/lxc/providers/config.rb +0 -75
- data/lib/elecksee/vendor/lxc/providers/container.rb +0 -318
- data/lib/elecksee/vendor/lxc/providers/default.rb +0 -57
- data/lib/elecksee/vendor/lxc/providers/ephemeral.rb +0 -40
- data/lib/elecksee/vendor/lxc/providers/fstab.rb +0 -30
- data/lib/elecksee/vendor/lxc/providers/interface.rb +0 -45
- data/lib/elecksee/vendor/lxc/providers/service.rb +0 -53
- data/lib/elecksee/vendor/lxc/recipes/containers.rb +0 -13
- data/lib/elecksee/vendor/lxc/recipes/default.rb +0 -58
- data/lib/elecksee/vendor/lxc/recipes/install_dependencies.rb +0 -15
- data/lib/elecksee/vendor/lxc/recipes/knife.rb +0 -37
- data/lib/elecksee/vendor/lxc/resources/config.rb +0 -19
- data/lib/elecksee/vendor/lxc/resources/container.rb +0 -54
- data/lib/elecksee/vendor/lxc/resources/default.rb +0 -12
- data/lib/elecksee/vendor/lxc/resources/ephemeral.rb +0 -13
- data/lib/elecksee/vendor/lxc/resources/fstab.rb +0 -12
- data/lib/elecksee/vendor/lxc/resources/interface.rb +0 -13
- data/lib/elecksee/vendor/lxc/resources/service.rb +0 -5
- data/lib/elecksee/vendor/lxc/templates/default/client.rb.erb +0 -13
- data/lib/elecksee/vendor/lxc/templates/default/default-lxc.erb +0 -3
- data/lib/elecksee/vendor/lxc/templates/default/file_content.erb +0 -2
- data/lib/elecksee/vendor/lxc/templates/default/fstab.erb +0 -5
- data/lib/elecksee/vendor/lxc/templates/default/interface.erb +0 -27
@@ -1,366 +0,0 @@
|
|
1
|
-
require 'pathname'
|
2
|
-
require 'tmpdir'
|
3
|
-
|
4
|
-
class Lxc
|
5
|
-
class CommandFailed < StandardError
|
6
|
-
end
|
7
|
-
|
8
|
-
# Pathname#join does not act like File#join when joining paths that
|
9
|
-
# begin with '/', and that's dumb. So we'll make our own Pathname,
|
10
|
-
# with a #join that uses File
|
11
|
-
class Pathname < ::Pathname
|
12
|
-
def join(*args)
|
13
|
-
self.class.new(::File.join(self.to_path, *args))
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
attr_reader :name
|
18
|
-
|
19
|
-
class << self
|
20
|
-
|
21
|
-
attr_accessor :use_sudo
|
22
|
-
|
23
|
-
def sudo
|
24
|
-
case use_sudo
|
25
|
-
when TrueClass
|
26
|
-
'sudo '
|
27
|
-
when String
|
28
|
-
"#{use_sudo} "
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# List running containers
|
33
|
-
def running
|
34
|
-
full_list[:running]
|
35
|
-
end
|
36
|
-
|
37
|
-
# List stopped containers
|
38
|
-
def stopped
|
39
|
-
full_list[:stopped]
|
40
|
-
end
|
41
|
-
|
42
|
-
# List frozen containers
|
43
|
-
def frozen
|
44
|
-
full_list[:frozen]
|
45
|
-
end
|
46
|
-
|
47
|
-
# name:: name of container
|
48
|
-
# Returns if container exists
|
49
|
-
def exists?(name)
|
50
|
-
list.include?(name)
|
51
|
-
end
|
52
|
-
|
53
|
-
# List of containers
|
54
|
-
def list
|
55
|
-
%x{#{sudo}lxc-ls}.split("\n").uniq
|
56
|
-
end
|
57
|
-
|
58
|
-
# name:: Name of container
|
59
|
-
# Returns information about given container
|
60
|
-
def info(name)
|
61
|
-
res = {:state => nil, :pid => nil}
|
62
|
-
info = %x{#{sudo}lxc-info -n #{name}}.split("\n")
|
63
|
-
parts = info.first.split(' ')
|
64
|
-
res[:state] = parts.last.downcase.to_sym
|
65
|
-
parts = info.last.split(' ')
|
66
|
-
res[:pid] = parts.last.to_i
|
67
|
-
res
|
68
|
-
end
|
69
|
-
|
70
|
-
# Return full container information list
|
71
|
-
def full_list
|
72
|
-
res = {}
|
73
|
-
list.each do |item|
|
74
|
-
item_info = info(item)
|
75
|
-
res[item_info[:state]] ||= []
|
76
|
-
res[item_info[:state]] << item
|
77
|
-
end
|
78
|
-
res
|
79
|
-
end
|
80
|
-
|
81
|
-
# ip:: IP address
|
82
|
-
# Returns if IP address is alive
|
83
|
-
def connection_alive?(ip)
|
84
|
-
%x{ping -c 1 -W 1 #{ip}}
|
85
|
-
$?.exitstatus == 0
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
# name:: name of container
|
90
|
-
# args:: Argument hash
|
91
|
-
# - :base_path -> path to container directory
|
92
|
-
# - :dnsmasq_lease_file -> path to lease file
|
93
|
-
def initialize(name, args={})
|
94
|
-
@name = name
|
95
|
-
@base_path = args[:base_path] || '/var/lib/lxc'
|
96
|
-
@lease_file = args[:dnsmasq_lease_file] || '/var/lib/misc/dnsmasq.leases'
|
97
|
-
end
|
98
|
-
|
99
|
-
# Returns if container exists
|
100
|
-
def exists?
|
101
|
-
self.class.exists?(name)
|
102
|
-
end
|
103
|
-
|
104
|
-
# Returns if container is running
|
105
|
-
def running?
|
106
|
-
self.class.info(name)[:state] == :running
|
107
|
-
end
|
108
|
-
|
109
|
-
# Returns if container is stopped
|
110
|
-
def stopped?
|
111
|
-
self.class.info(name)[:state] == :stopped
|
112
|
-
end
|
113
|
-
|
114
|
-
# Returns if container is frozen
|
115
|
-
def frozen?
|
116
|
-
self.class.info(name)[:state] == :frozen
|
117
|
-
end
|
118
|
-
|
119
|
-
# retries:: Number of discovery attempt (3 second sleep intervals)
|
120
|
-
# Returns container IP
|
121
|
-
def container_ip(retries=0, raise_on_fail=false)
|
122
|
-
(retries.to_i + 1).times do
|
123
|
-
ip = proc_detected_address || hw_detected_address || leased_address || lxc_stored_address
|
124
|
-
return ip if ip && self.class.connection_alive?(ip)
|
125
|
-
log.warn "LXC IP discovery: Failed to detect live IP"
|
126
|
-
sleep(3) if retries > 0
|
127
|
-
end
|
128
|
-
raise "Failed to detect live IP address for container: #{name}" if raise_on_fail
|
129
|
-
end
|
130
|
-
|
131
|
-
# Container address via lxc config file
|
132
|
-
def lxc_stored_address
|
133
|
-
if(File.exists?(container_config))
|
134
|
-
ip = File.readlines(container_config).detect{|line|
|
135
|
-
line.include?('ipv4')
|
136
|
-
}.to_s.split('=').last.to_s.strip
|
137
|
-
if(ip.to_s.empty?)
|
138
|
-
nil
|
139
|
-
else
|
140
|
-
log.info "LXC Discovery: Found container address via storage: #{ip}"
|
141
|
-
ip
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
# Container address via dnsmasq lease
|
147
|
-
def leased_address
|
148
|
-
ip = nil
|
149
|
-
if(File.exists?(@lease_file))
|
150
|
-
leases = File.readlines(@lease_file).map{|line| line.split(' ')}
|
151
|
-
leases.each do |lease|
|
152
|
-
if(lease.include?(name))
|
153
|
-
ip = lease[2]
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
if(ip.to_s.empty?)
|
158
|
-
nil
|
159
|
-
else
|
160
|
-
log.info "LXC Discovery: Found container address via DHCP lease: #{ip}"
|
161
|
-
ip
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
def hw_detected_address
|
166
|
-
if(container_config.readable?)
|
167
|
-
hw = File.readlines(container_config).detect{|line|
|
168
|
-
line.include?('hwaddr')
|
169
|
-
}.to_s.split('=').last.to_s.downcase
|
170
|
-
if(File.exists?(container_config) && !hw.empty?)
|
171
|
-
running? # need to do a list!
|
172
|
-
ip = File.readlines('/proc/net/arp').detect{|line|
|
173
|
-
line.downcase.include?(hw)
|
174
|
-
}.to_s.split(' ').first.to_s.strip
|
175
|
-
if(ip.to_s.empty?)
|
176
|
-
nil
|
177
|
-
else
|
178
|
-
log.info "LXC Discovery: Found container address via HW addr: #{ip}"
|
179
|
-
ip
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
def proc_detected_address(base='/run/netns')
|
186
|
-
if(pid != -1)
|
187
|
-
Dir.mktmpdir do |t_dir|
|
188
|
-
name = File.basename(t_dir)
|
189
|
-
path = File.join(base, name)
|
190
|
-
system("#{sudo}mkdir -p #{base}")
|
191
|
-
system("#{sudo}ln -s /proc/#{pid}/ns/net #{path}")
|
192
|
-
res = %x{#{sudo}ip netns exec #{name} ip -4 addr show scope global | grep inet}
|
193
|
-
system("#{sudo}rm -f #{path}")
|
194
|
-
ip = res.strip.split(' ')[1].to_s.sub(%r{/.*$}, '').strip
|
195
|
-
ip.empty? ? nil : ip
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
def sudo
|
201
|
-
self.class.sudo
|
202
|
-
end
|
203
|
-
|
204
|
-
# Full path to container
|
205
|
-
def container_path
|
206
|
-
Pathname.new(@base_path).join(name)
|
207
|
-
end
|
208
|
-
alias_method :path, :container_path
|
209
|
-
|
210
|
-
# Full path to container configuration file
|
211
|
-
def container_config
|
212
|
-
container_path.join('config')
|
213
|
-
end
|
214
|
-
alias_method :config, :container_config
|
215
|
-
|
216
|
-
def container_rootfs
|
217
|
-
container_path.join('rootfs')
|
218
|
-
end
|
219
|
-
alias_method :rootfs, :container_rootfs
|
220
|
-
|
221
|
-
def expand_path(path)
|
222
|
-
container_rootfs.join(path)
|
223
|
-
end
|
224
|
-
|
225
|
-
def state
|
226
|
-
self.class.info(name)[:state]
|
227
|
-
end
|
228
|
-
|
229
|
-
def pid
|
230
|
-
self.class.info(name)[:pid]
|
231
|
-
end
|
232
|
-
|
233
|
-
# Start the container
|
234
|
-
def start
|
235
|
-
run_command("#{sudo}lxc-start -n #{name} -d")
|
236
|
-
run_command("#{sudo}lxc-wait -n #{name} -s RUNNING", :allow_failure_retry => 2)
|
237
|
-
end
|
238
|
-
|
239
|
-
# Stop the container
|
240
|
-
def stop
|
241
|
-
run_command("#{sudo}lxc-stop -n #{name}", :allow_failure_retry => 3)
|
242
|
-
run_command("#{sudo}lxc-wait -n #{name} -s STOPPED", :allow_failure_retry => 2)
|
243
|
-
end
|
244
|
-
|
245
|
-
# Freeze the container
|
246
|
-
def freeze
|
247
|
-
run_command("#{sudo}lxc-freeze -n #{name}")
|
248
|
-
run_command("#{sudo}lxc-wait -n #{name} -s FROZEN", :allow_failure_retry => 2)
|
249
|
-
end
|
250
|
-
|
251
|
-
# Unfreeze the container
|
252
|
-
def unfreeze
|
253
|
-
run_command("#{sudo}lxc-unfreeze -n #{name}")
|
254
|
-
run_command("#{sudo}lxc-wait -n #{name} -s RUNNING", :allow_failure_retry => 2)
|
255
|
-
end
|
256
|
-
|
257
|
-
# Shutdown the container
|
258
|
-
def shutdown
|
259
|
-
run_command("#{sudo}lxc-shutdown -n #{name}")
|
260
|
-
run_command("#{sudo}lxc-wait -n #{name} -s STOPPED", :allow_failure => true, :timeout => 120)
|
261
|
-
# This block is for fedora/centos/anyone else that does not like lxc-shutdown
|
262
|
-
if(running?)
|
263
|
-
container_command('shutdown -h now')
|
264
|
-
run_command("#{sudo}lxc-wait -n #{name} -s STOPPED", :allow_failure => true)
|
265
|
-
# If still running here, something is wrong
|
266
|
-
if(running?)
|
267
|
-
raise "Failed to shutdown container: #{name}"
|
268
|
-
end
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
def direct_container_command(command, args={})
|
273
|
-
com = "#{sudo}ssh root@#{args[:ip] || container_ip} -i /opt/hw-lxc-config/id_rsa -oStrictHostKeyChecking=no '#{command}'"
|
274
|
-
begin
|
275
|
-
cmd = Mixlib::ShellOut.new(com,
|
276
|
-
:live_stream => args[:live_stream],
|
277
|
-
:timeout => args[:timeout] || 1200
|
278
|
-
)
|
279
|
-
cmd.run_command
|
280
|
-
cmd.error!
|
281
|
-
true
|
282
|
-
rescue
|
283
|
-
raise if args[:raise_on_failure]
|
284
|
-
false
|
285
|
-
end
|
286
|
-
end
|
287
|
-
alias_method :knife_container, :direct_container_command
|
288
|
-
|
289
|
-
# Simple helper to shell out
|
290
|
-
def run_command(cmd, args={})
|
291
|
-
retries = args[:allow_failure_retry].to_i
|
292
|
-
begin
|
293
|
-
shlout = Mixlib::ShellOut.new(cmd,
|
294
|
-
:logger => defined?(Chef) ? Chef::Log.logger : log,
|
295
|
-
:live_stream => STDOUT,
|
296
|
-
:timeout => args[:timeout] || 1200,
|
297
|
-
:environment => {'HOME' => detect_home}
|
298
|
-
)
|
299
|
-
shlout.run_command
|
300
|
-
shlout.error!
|
301
|
-
rescue Mixlib::ShellOut::ShellCommandFailed, CommandFailed, Mixlib::ShellOut::CommandTimeout
|
302
|
-
if(retries > 0)
|
303
|
-
log.warn "LXC run command failed: #{cmd}"
|
304
|
-
log.warn "Retrying command. #{args[:allow_failure_retry].to_i - retries} of #{args[:allow_failure_retry].to_i} retries remain"
|
305
|
-
sleep(0.3)
|
306
|
-
retries -= 1
|
307
|
-
retry
|
308
|
-
elsif(args[:allow_failure])
|
309
|
-
true
|
310
|
-
else
|
311
|
-
raise
|
312
|
-
end
|
313
|
-
end
|
314
|
-
end
|
315
|
-
|
316
|
-
# Detect HOME environment variable. If not an acceptable
|
317
|
-
# value, set to /root or /tmp
|
318
|
-
def detect_home(set_if_missing=false)
|
319
|
-
if(ENV['HOME'] && Pathname.new(ENV['HOME']).absolute?)
|
320
|
-
ENV['HOME']
|
321
|
-
else
|
322
|
-
home = File.directory?('/root') && File.writable?('/root') ? '/root' : '/tmp'
|
323
|
-
if(set_if_missing)
|
324
|
-
ENV['HOME'] = home
|
325
|
-
end
|
326
|
-
home
|
327
|
-
end
|
328
|
-
end
|
329
|
-
|
330
|
-
# cmd:: Shell command string
|
331
|
-
# retries:: Number of retry attempts (1 second sleep interval)
|
332
|
-
# Runs command in container via ssh
|
333
|
-
def container_command(cmd, retries=1)
|
334
|
-
begin
|
335
|
-
detect_home(true)
|
336
|
-
direct_container_command(cmd,
|
337
|
-
:ip => container_ip(5),
|
338
|
-
:live_stream => STDOUT,
|
339
|
-
:raise_on_failure => true
|
340
|
-
)
|
341
|
-
rescue => e
|
342
|
-
if(retries.to_i > 0)
|
343
|
-
log.info "Encountered error running container command (#{cmd}): #{e}"
|
344
|
-
log.info "Retrying command..."
|
345
|
-
retries = retries.to_i - 1
|
346
|
-
sleep(1)
|
347
|
-
retry
|
348
|
-
else
|
349
|
-
raise e
|
350
|
-
end
|
351
|
-
end
|
352
|
-
end
|
353
|
-
|
354
|
-
def log
|
355
|
-
if(defined?(Chef))
|
356
|
-
Chef::Log
|
357
|
-
else
|
358
|
-
unless(@logger)
|
359
|
-
require 'logger'
|
360
|
-
@logger = Logger.new('/dev/null')
|
361
|
-
end
|
362
|
-
@logger
|
363
|
-
end
|
364
|
-
end
|
365
|
-
|
366
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module ChefLxc
|
2
|
-
module Resource
|
3
|
-
|
4
|
-
def container(arg=nil)
|
5
|
-
set_or_return(:container, arg, :kind_of => [String], :required => true)
|
6
|
-
end
|
7
|
-
|
8
|
-
def lxc
|
9
|
-
@lxc ||= Lxc.new(
|
10
|
-
@container,
|
11
|
-
:base_dir => node[:lxc][:container_directory]
|
12
|
-
)
|
13
|
-
end
|
14
|
-
|
15
|
-
def path(arg=nil)
|
16
|
-
arg ? super(arg) : lxc.expand_path(super(arg))
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.included(base)
|
20
|
-
base.class_eval do
|
21
|
-
def initialize(*args)
|
22
|
-
super
|
23
|
-
@container = nil
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
class Chef
|
31
|
-
class Resource
|
32
|
-
class LxcTemplate < Template
|
33
|
-
include ChefLxc::Resource
|
34
|
-
end
|
35
|
-
|
36
|
-
class LxcFile < File
|
37
|
-
include ChefLxc::Resource
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,84 +0,0 @@
|
|
1
|
-
class LxcFileConfig
|
2
|
-
|
3
|
-
attr_reader :network
|
4
|
-
attr_reader :base
|
5
|
-
|
6
|
-
class << self
|
7
|
-
def generate_config(resource)
|
8
|
-
config = []
|
9
|
-
config << "lxc.utsname = #{resource.utsname}"
|
10
|
-
if(resource.aa_profile)
|
11
|
-
config << "lxc.aa_profile = #{resource.aa_profile}"
|
12
|
-
end
|
13
|
-
[resource.network].flatten.each do |net_hash|
|
14
|
-
nhsh = Mash.new(net_hash)
|
15
|
-
flags = nhsh.delete(:flags)
|
16
|
-
%w(type link).each do |k|
|
17
|
-
config << "lxc.network.#{k} = #{nhsh.delete(k)}" if nhsh[k]
|
18
|
-
end
|
19
|
-
nhsh.each_pair do |k,v|
|
20
|
-
config << "lxc.network.#{k} = #{v}"
|
21
|
-
end
|
22
|
-
if(flags)
|
23
|
-
config << "lxc.network.flags = #{flags}"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
if(resource.cap_drop)
|
27
|
-
config << "lxc.cap.drop = #{Array(resource.cap_drop).join(' ')}"
|
28
|
-
end
|
29
|
-
%w(pts tty arch devttydir mount mount_entry rootfs rootfs_mount pivotdir).each do |k|
|
30
|
-
config << "lxc.#{k.sub('_', '.')} = #{resource.send(k)}" if resource.send(k)
|
31
|
-
end
|
32
|
-
prefix = 'lxc.cgroup'
|
33
|
-
resource.cgroup.each_pair do |key, value|
|
34
|
-
if(value.is_a?(Array))
|
35
|
-
value.each do |val|
|
36
|
-
config << "#{prefix}.#{key} = #{val}"
|
37
|
-
end
|
38
|
-
else
|
39
|
-
config << "#{prefix}.#{key} = #{value}"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
config.join("\n") + "\n"
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
def initialize(path)
|
48
|
-
raise 'LXC config file not found' unless File.exists?(path)
|
49
|
-
@path = path
|
50
|
-
@network = []
|
51
|
-
@base = Mash.new
|
52
|
-
parse!
|
53
|
-
end
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
def parse!
|
58
|
-
cur_net = nil
|
59
|
-
File.readlines(@path).each do |line|
|
60
|
-
if(line.start_with?('lxc.network'))
|
61
|
-
parts = line.split('=')
|
62
|
-
name = parts.first.split('.').last.strip
|
63
|
-
if(name.to_sym == :type)
|
64
|
-
@network << cur_net if cur_net
|
65
|
-
cur_net = Mash.new
|
66
|
-
end
|
67
|
-
if(cur_net)
|
68
|
-
cur_net[name] = parts.last.strip
|
69
|
-
else
|
70
|
-
raise "Expecting 'lxc.network.type' to start network config block. Found: 'lxc.network.#{name}'"
|
71
|
-
end
|
72
|
-
else
|
73
|
-
parts = line.split('=')
|
74
|
-
name = parts.first.sub('lxc.', '').strip
|
75
|
-
if(@base[name])
|
76
|
-
@base[name] = [@base[name], parts.last.strip].flatten
|
77
|
-
else
|
78
|
-
@base[name] = parts.last
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
@network << cur_net if cur_net
|
83
|
-
end
|
84
|
-
end
|
@@ -1,51 +0,0 @@
|
|
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
|
@@ -1,12 +0,0 @@
|
|
1
|
-
name 'lxc'
|
2
|
-
maintainer 'Chris Roberts'
|
3
|
-
maintainer_email 'chrisroberts.code@gmail.com'
|
4
|
-
license 'Apache 2.0'
|
5
|
-
description 'Chef driven Linux Containers'
|
6
|
-
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
|
7
|
-
version '1.0.1'
|
8
|
-
|
9
|
-
supports 'ubuntu'
|
10
|
-
|
11
|
-
suggests 'omnibus_updater'
|
12
|
-
suggests 'bridger'
|
@@ -1,75 +0,0 @@
|
|
1
|
-
require 'securerandom'
|
2
|
-
|
3
|
-
def load_current_resource
|
4
|
-
@lxc = ::Lxc.new(
|
5
|
-
new_resource.name,
|
6
|
-
:base_dir => node[:lxc][:container_directory],
|
7
|
-
:dnsmasq_lease_file => node[:lxc][:dnsmasq_lease_file]
|
8
|
-
)
|
9
|
-
new_resource.utsname new_resource.name unless new_resource.utsname
|
10
|
-
new_resource.rootfs @lxc.rootfs.to_path unless new_resource.rootfs
|
11
|
-
new_resource.default_bridge node[:lxc][:bridge] unless new_resource.default_bridge
|
12
|
-
new_resource.mount @lxc.path.join('fstab').to_path unless new_resource.mount
|
13
|
-
config = LxcFileConfig.new(@lxc.container_config)
|
14
|
-
if((new_resource.network.nil? || new_resource.network.empty?))
|
15
|
-
if(config.network.empty?)
|
16
|
-
default_net = {
|
17
|
-
:type => :veth,
|
18
|
-
:link => new_resource.default_bridge,
|
19
|
-
:flags => :up,
|
20
|
-
:hwaddr => "00:16:3e#{SecureRandom.hex(3).gsub(/(..)/, ':\1')}"
|
21
|
-
}
|
22
|
-
else
|
23
|
-
default_net = config.network.first
|
24
|
-
default_net.delete(:ipv4) if default_net.has_key?(:ipv4)
|
25
|
-
default_net.merge!(:link => new_resource.default_bridge)
|
26
|
-
end
|
27
|
-
new_resource.network(default_net)
|
28
|
-
else
|
29
|
-
[new_resource.network].flatten.each_with_index do |net_hash, idx|
|
30
|
-
if(config.network[idx].nil? || config.network[idx][:hwaddr].nil?)
|
31
|
-
net_hash[:hwaddr] ||= "00:16:3e#{SecureRandom.hex(3).gsub(/(..)/, ':\1')}"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
new_resource.cgroup(
|
36
|
-
Chef::Mixin::DeepMerge.merge(
|
37
|
-
Mash.new(
|
38
|
-
'devices.deny' => 'a',
|
39
|
-
'devices.allow' => [
|
40
|
-
'c *:* m',
|
41
|
-
'b *:* m',
|
42
|
-
'c 1:3 rwm',
|
43
|
-
'c 1:5 rwm',
|
44
|
-
'c 5:1 rwm',
|
45
|
-
'c 5:0 rwm',
|
46
|
-
'c 1:9 rwm',
|
47
|
-
'c 1:8 rwm',
|
48
|
-
'c 136:* rwm',
|
49
|
-
'c 5:2 rwm',
|
50
|
-
'c 254:0 rwm',
|
51
|
-
'c 10:229 rwm',
|
52
|
-
'c 10:200 rwm',
|
53
|
-
'c 1:7 rwm',
|
54
|
-
'c 10:228 rwm',
|
55
|
-
'c 10:232 rwm'
|
56
|
-
]
|
57
|
-
),
|
58
|
-
new_resource.cgroup
|
59
|
-
)
|
60
|
-
)
|
61
|
-
end
|
62
|
-
|
63
|
-
action :create do
|
64
|
-
_lxc = @lxc
|
65
|
-
|
66
|
-
directory @lxc.path.to_path do
|
67
|
-
action :create
|
68
|
-
end
|
69
|
-
|
70
|
-
file "lxc update_config[#{new_resource.utsname}]" do
|
71
|
-
path _lxc.container_config.to_path
|
72
|
-
content LxcFileConfig.generate_config(new_resource)
|
73
|
-
mode 0644
|
74
|
-
end
|
75
|
-
end
|