elecksee 1.0.22 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +10 -0
- data/CONTRIBUTING.md +25 -0
- data/README.md +43 -6
- data/elecksee.gemspec +3 -3
- data/lib/elecksee/clone.rb +47 -16
- data/lib/elecksee/ephemeral.rb +65 -15
- data/lib/elecksee/helpers/copies.rb +36 -5
- data/lib/elecksee/helpers/options.rb +29 -3
- data/lib/elecksee/{helpers/base.rb → helpers.rb} +115 -56
- data/lib/elecksee/lxc.rb +204 -82
- data/lib/elecksee/lxc_file_config.rb +26 -0
- data/lib/elecksee/storage/overlay_directory.rb +68 -37
- data/lib/elecksee/storage/overlay_mount.rb +80 -45
- data/lib/elecksee/storage/virtual_device.rb +104 -60
- data/lib/elecksee/storage.rb +13 -0
- data/lib/elecksee/version.rb +2 -1
- data/lib/elecksee.rb +13 -0
- metadata +26 -33
- data/Gemfile +0 -5
- data/Gemfile.lock +0 -22
- data/lib/elecksee/knife/config.rb +0 -37
data/lib/elecksee/lxc.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
require 'elecksee
|
1
|
+
require 'elecksee'
|
2
2
|
require 'securerandom'
|
3
3
|
require 'shellwords'
|
4
4
|
require 'pathname'
|
5
5
|
require 'tmpdir'
|
6
|
+
require 'rye'
|
6
7
|
|
7
8
|
class Lxc
|
8
9
|
|
@@ -10,6 +11,10 @@ class Lxc
|
|
10
11
|
# begin with '/', and that's dumb. So we'll make our own Pathname,
|
11
12
|
# with a #join that uses File
|
12
13
|
class Pathname < ::Pathname
|
14
|
+
# Join arguments using ::File.join
|
15
|
+
#
|
16
|
+
# @param args [String] argument list
|
17
|
+
# @return [String]
|
13
18
|
def join(*args)
|
14
19
|
self.class.new(::File.join(self.to_path, *args))
|
15
20
|
end
|
@@ -17,16 +22,39 @@ class Lxc
|
|
17
22
|
|
18
23
|
include Helpers
|
19
24
|
|
20
|
-
|
25
|
+
# @return [String] name of container
|
26
|
+
attr_reader :name
|
27
|
+
# @return [String] base path of container
|
28
|
+
attr_reader :base_path
|
29
|
+
# @return [String] path to dnsmasq lease file
|
30
|
+
attr_reader :lease_file
|
31
|
+
# @return [String] network device to use for ssh connection
|
32
|
+
attr_reader :preferred_device
|
33
|
+
# @return [String, NilClass] path to default ssh key
|
34
|
+
attr_accessor :ssh_key
|
35
|
+
# @return [String, NilClass] ssh password
|
36
|
+
attr_accessor :ssh_password
|
37
|
+
# @return [String, NilClass] ssh user
|
38
|
+
attr_accessor :ssh_user
|
21
39
|
|
22
40
|
class << self
|
23
41
|
|
24
42
|
include Helpers
|
25
43
|
|
44
|
+
# @return [Truthy, String] use sudo when required (set to string for custom sudo command)
|
26
45
|
attr_accessor :use_sudo
|
46
|
+
# @return [String] base path for containers
|
27
47
|
attr_accessor :base_path
|
48
|
+
# @return [Symbol] :mixlib_shellout or :childprocess
|
28
49
|
attr_accessor :shellout_helper
|
29
|
-
|
50
|
+
# @return [String, NilClass] path to default ssh key
|
51
|
+
attr_accessor :default_ssh_key
|
52
|
+
# @return [String, NilClass] default ssh password
|
53
|
+
attr_accessor :default_ssh_password
|
54
|
+
# @return [String, NilClass] default ssh user
|
55
|
+
attr_accessor :default_ssh_user
|
56
|
+
|
57
|
+
# @return [String] sudo command
|
30
58
|
def sudo
|
31
59
|
case use_sudo
|
32
60
|
when TrueClass
|
@@ -36,44 +64,56 @@ class Lxc
|
|
36
64
|
end
|
37
65
|
end
|
38
66
|
|
67
|
+
# @return [String] base path for containers
|
39
68
|
def base_path
|
40
69
|
@base_path || '/var/lib/lxc'
|
41
70
|
end
|
42
71
|
|
43
|
-
#
|
72
|
+
# Currently running container names
|
73
|
+
#
|
74
|
+
# @return [Array<String>]
|
44
75
|
def running
|
45
76
|
full_list[:running]
|
46
77
|
end
|
47
78
|
|
48
|
-
#
|
79
|
+
# Currently stopped container names
|
80
|
+
#
|
81
|
+
# @return [Array<String>]
|
49
82
|
def stopped
|
50
83
|
full_list[:stopped]
|
51
84
|
end
|
52
85
|
|
53
|
-
#
|
86
|
+
# Currently frozen container names
|
87
|
+
#
|
88
|
+
# @return [Array<String>]
|
54
89
|
def frozen
|
55
90
|
full_list[:frozen]
|
56
91
|
end
|
57
92
|
|
58
|
-
#
|
59
|
-
#
|
93
|
+
# Container currently exists
|
94
|
+
#
|
95
|
+
# @param name [String] name of container
|
96
|
+
# @return [TrueClass, FalseClass]
|
60
97
|
def exists?(name)
|
61
98
|
list.include?(name)
|
62
99
|
end
|
63
100
|
|
64
|
-
# List of containers
|
101
|
+
# List of all containers
|
102
|
+
#
|
103
|
+
# @return [Array<String>] container names
|
65
104
|
def list
|
66
|
-
|
67
|
-
|
68
|
-
File.basename(item)
|
69
|
-
end
|
70
|
-
end.compact
|
105
|
+
run_command('lxc-ls', :sudo => true).
|
106
|
+
stdout.split(/\s/).map(&:strip).compact
|
71
107
|
end
|
72
108
|
|
73
|
-
#
|
74
|
-
#
|
109
|
+
# Information available for given container
|
110
|
+
#
|
111
|
+
# @param name [String] name of container
|
112
|
+
# @return [Hash]
|
75
113
|
def info(name)
|
76
|
-
|
114
|
+
if(exists?(name))
|
115
|
+
info = run_command("#{sudo}lxc-info -n #{name}", :allow_failure_retry => 3, :allow_failure => true)
|
116
|
+
end
|
77
117
|
if(info)
|
78
118
|
Hash[
|
79
119
|
info.stdout.split("\n").map do |string|
|
@@ -93,7 +133,9 @@ class Lxc
|
|
93
133
|
end
|
94
134
|
end
|
95
135
|
|
96
|
-
#
|
136
|
+
# Full list of containers grouped by state
|
137
|
+
#
|
138
|
+
# @return [Hash]
|
97
139
|
def full_list
|
98
140
|
res = {}
|
99
141
|
list.each do |item|
|
@@ -104,51 +146,69 @@ class Lxc
|
|
104
146
|
res
|
105
147
|
end
|
106
148
|
|
107
|
-
#
|
108
|
-
#
|
149
|
+
# IP address is currently active
|
150
|
+
#
|
151
|
+
# @param ip [String]
|
152
|
+
# @return [TrueClass, FalseClass]
|
109
153
|
def connection_alive?(ip)
|
110
154
|
%x{ping -c 1 -W 1 #{ip}}
|
111
155
|
$?.exitstatus == 0
|
112
156
|
end
|
113
157
|
end
|
114
158
|
|
115
|
-
#
|
116
|
-
#
|
117
|
-
#
|
118
|
-
#
|
119
|
-
#
|
159
|
+
# Create new instance
|
160
|
+
#
|
161
|
+
# @param name [String] container name
|
162
|
+
# @param args [Hash]
|
163
|
+
# @option args [String] :base_path path to container
|
164
|
+
# @option args [String] :dnsmasq_lease_file path to lease file
|
165
|
+
# @option args [String] :net_device network device within container for ssh connection
|
166
|
+
# @option args [String] :ssh_key path to ssh key
|
167
|
+
# @option args [String] :ssh_password ssh password
|
168
|
+
# @option args [String] :ssh_user ssh user
|
120
169
|
def initialize(name, args={})
|
121
170
|
@name = name
|
122
171
|
@base_path = args[:base_path] || self.class.base_path
|
123
172
|
@lease_file = args[:dnsmasq_lease_file] || '/var/lib/misc/dnsmasq.leases'
|
124
173
|
@preferred_device = args[:net_device]
|
174
|
+
@ssh_key = args.fetch(:ssh_key, self.class.default_ssh_key)
|
175
|
+
@ssh_password = args.fetch(:ssh_password, self.class.default_ssh_password)
|
176
|
+
@ssh_user = args.fetch(:ssh_user, self.class.default_ssh_user)
|
125
177
|
end
|
126
178
|
|
127
|
-
#
|
179
|
+
# @return [TrueClass, FalseClass] container exists
|
128
180
|
def exists?
|
129
181
|
self.class.exists?(name)
|
130
182
|
end
|
131
183
|
|
132
|
-
#
|
184
|
+
# @return [TrueClass, FalseClass] container is currently running
|
133
185
|
def running?
|
134
186
|
self.class.info(name)[:state] == :running
|
135
187
|
end
|
136
188
|
|
137
|
-
#
|
189
|
+
# @return [TrueClass, FalseClass] container is currently stopped
|
138
190
|
def stopped?
|
139
191
|
self.class.info(name)[:state] == :stopped
|
140
192
|
end
|
141
193
|
|
142
|
-
#
|
194
|
+
# @return [TrueClass, FalseClass] container is currently frozen
|
143
195
|
def frozen?
|
144
196
|
self.class.info(name)[:state] == :frozen
|
145
197
|
end
|
146
198
|
|
147
|
-
#
|
148
|
-
#
|
199
|
+
# Current IP address of container
|
200
|
+
#
|
201
|
+
# @param retries [Integer] number of times to retry discovery
|
202
|
+
# @param raise_on_fail [TrueClass, FalseClass] raise exception on failure
|
203
|
+
# @return [String, NilClass] IP address
|
204
|
+
# @note retries are executed on 3 second sleep intervals
|
149
205
|
def container_ip(retries=0, raise_on_fail=false)
|
150
206
|
(retries.to_i + 1).times do
|
151
|
-
ip =
|
207
|
+
ip = info_detected_address ||
|
208
|
+
proc_detected_address ||
|
209
|
+
hw_detected_address ||
|
210
|
+
leased_address ||
|
211
|
+
lxc_stored_address
|
152
212
|
if(ip.is_a?(Array))
|
153
213
|
# Filter any found loopbacks
|
154
214
|
ip.delete_if{|info| info[:device].start_with?('lo') }
|
@@ -168,7 +228,9 @@ class Lxc
|
|
168
228
|
raise "Failed to detect live IP address for container: #{name}" if raise_on_fail
|
169
229
|
end
|
170
230
|
|
171
|
-
# Container address
|
231
|
+
# Container address defined within the container's config file
|
232
|
+
#
|
233
|
+
# @return [String, NilClass] IP address
|
172
234
|
def lxc_stored_address
|
173
235
|
if(File.exists?(container_config))
|
174
236
|
ip = File.readlines(container_config).detect{|line|
|
@@ -183,7 +245,9 @@ class Lxc
|
|
183
245
|
end
|
184
246
|
end
|
185
247
|
|
186
|
-
# Container address via dnsmasq lease
|
248
|
+
# Container address discovered via dnsmasq lease
|
249
|
+
#
|
250
|
+
# @return [String, NilClass] IP address
|
187
251
|
def leased_address
|
188
252
|
ip = nil
|
189
253
|
if(File.exists?(@lease_file))
|
@@ -202,6 +266,16 @@ class Lxc
|
|
202
266
|
end
|
203
267
|
end
|
204
268
|
|
269
|
+
# Container address discovered via info
|
270
|
+
#
|
271
|
+
# @return [String, NilClass] IP address
|
272
|
+
def info_detected_address
|
273
|
+
self.class.info(name)[:ip]
|
274
|
+
end
|
275
|
+
|
276
|
+
# Container address discovered via device
|
277
|
+
#
|
278
|
+
# @return [String, NilClass] IP address
|
205
279
|
def hw_detected_address
|
206
280
|
if(container_config.readable?)
|
207
281
|
hw = File.readlines(container_config).detect{|line|
|
@@ -222,6 +296,10 @@ class Lxc
|
|
222
296
|
end
|
223
297
|
end
|
224
298
|
|
299
|
+
# Container address discovered via process
|
300
|
+
#
|
301
|
+
# @param base [String] path to netns
|
302
|
+
# @return [String, NilClass] IP address
|
225
303
|
def proc_detected_address(base='/run/netns')
|
226
304
|
if(pid != -1)
|
227
305
|
Dir.mktmpdir do |t_dir|
|
@@ -240,18 +318,19 @@ class Lxc
|
|
240
318
|
end
|
241
319
|
end
|
242
320
|
|
243
|
-
#
|
321
|
+
# @return [Pathname] path to container
|
244
322
|
def container_path
|
245
323
|
Pathname.new(@base_path).join(name)
|
246
324
|
end
|
247
325
|
alias_method :path, :container_path
|
248
326
|
|
249
|
-
#
|
327
|
+
# @return [Pathname] path to configuration file
|
250
328
|
def container_config
|
251
329
|
container_path.join('config')
|
252
330
|
end
|
253
331
|
alias_method :config, :container_config
|
254
332
|
|
333
|
+
# @return [Pathname] path to rootfs
|
255
334
|
def container_rootfs
|
256
335
|
if(File.exists?(config))
|
257
336
|
r_path = File.readlines(config).detect do |line|
|
@@ -262,19 +341,28 @@ class Lxc
|
|
262
341
|
end
|
263
342
|
alias_method :rootfs, :container_rootfs
|
264
343
|
|
344
|
+
# Expand path within containers rootfs
|
345
|
+
#
|
346
|
+
# @param path [String] relative path
|
347
|
+
# @return [Pathname] full path within container
|
265
348
|
def expand_path(path)
|
266
349
|
container_rootfs.join(path)
|
267
350
|
end
|
268
351
|
|
352
|
+
# @return [Symbol] current state
|
269
353
|
def state
|
270
354
|
self.class.info(name)[:state]
|
271
355
|
end
|
272
356
|
|
357
|
+
# @return [Integer, Symbol] process ID or :unknown
|
273
358
|
def pid
|
274
359
|
self.class.info(name)[:pid]
|
275
360
|
end
|
276
361
|
|
277
362
|
# Start the container
|
363
|
+
#
|
364
|
+
# @param args [Symbol] argument list (:no_daemon to foreground)
|
365
|
+
# @return [self]
|
278
366
|
def start(*args)
|
279
367
|
if(args.include?(:no_daemon))
|
280
368
|
run_command("lxc-start -n #{name}", :sudo => true)
|
@@ -282,52 +370,73 @@ class Lxc
|
|
282
370
|
run_command("lxc-start -n #{name} -d", :sudo => true)
|
283
371
|
wait_for_state(:running)
|
284
372
|
end
|
373
|
+
self
|
285
374
|
end
|
286
375
|
|
287
376
|
# Stop the container
|
377
|
+
#
|
378
|
+
# @return [self]
|
288
379
|
def stop
|
289
380
|
run_command("lxc-stop -n #{name}", :allow_failure_retry => 3, :sudo => true)
|
290
381
|
wait_for_state(:stopped)
|
382
|
+
self
|
291
383
|
end
|
292
384
|
|
293
385
|
# Freeze the container
|
386
|
+
#
|
387
|
+
# @return [self]
|
294
388
|
def freeze
|
295
389
|
run_command("lxc-freeze -n #{name}", :sudo => true)
|
296
390
|
wait_for_state(:frozen)
|
391
|
+
self
|
297
392
|
end
|
298
393
|
|
299
394
|
# Unfreeze the container
|
395
|
+
#
|
396
|
+
# @return [self]
|
300
397
|
def unfreeze
|
301
398
|
run_command("lxc-unfreeze -n #{name}", :sudo => true)
|
302
399
|
wait_for_state(:running)
|
400
|
+
self
|
303
401
|
end
|
304
402
|
|
305
403
|
# Shutdown the container
|
404
|
+
#
|
405
|
+
# @return [self]
|
306
406
|
def shutdown
|
307
|
-
run_command("lxc-shutdown -n #{name}", :sudo => true)
|
308
|
-
wait_for_state(:stopped, :timeout => 120)
|
309
407
|
# This block is for fedora/centos/anyone else that does not like lxc-shutdown
|
310
408
|
if(running?)
|
311
409
|
container_command('shutdown -h now')
|
312
410
|
wait_for_state(:stopped, :timeout => 120)
|
313
411
|
# If still running here, something is wrong
|
314
412
|
if(running?)
|
315
|
-
|
413
|
+
run_command("lxc-stop -n #{name}", :sudo => true)
|
414
|
+
wait_for_state(:stopped, :timeout => 120)
|
415
|
+
if(running?)
|
416
|
+
raise "Failed to shutdown container: #{name}"
|
417
|
+
end
|
316
418
|
end
|
317
419
|
end
|
420
|
+
self
|
318
421
|
end
|
319
422
|
|
320
423
|
# Destroy the container
|
424
|
+
#
|
425
|
+
# @return [self]
|
321
426
|
def destroy
|
322
427
|
unless stopped?
|
323
428
|
stop
|
324
429
|
end
|
325
430
|
run_command("lxc-destroy -n #{name}", :sudo => true)
|
431
|
+
self
|
326
432
|
end
|
327
433
|
|
328
|
-
#
|
329
|
-
#
|
330
|
-
#
|
434
|
+
# Execute command within the container
|
435
|
+
#
|
436
|
+
# @param command [String] command to execute
|
437
|
+
# @param opts [Hash] options passed to #tmp_execute_script
|
438
|
+
# @return [CommandResult]
|
439
|
+
# @note container must be stopped
|
331
440
|
def execute(command, opts={})
|
332
441
|
if(stopped?)
|
333
442
|
cmd = Shellwords.split(command)
|
@@ -347,22 +456,47 @@ class Lxc
|
|
347
456
|
end
|
348
457
|
end
|
349
458
|
|
459
|
+
# Execute command within running container
|
460
|
+
#
|
461
|
+
# @param command [String]
|
462
|
+
# @param args [Hash]
|
463
|
+
# @option args [Integer] :timeout
|
464
|
+
# @option args [TrueClass, FalseClass] :live_stream
|
465
|
+
# @option args [TrueClass, FalseClass] :raise_on_failure
|
466
|
+
# @return [CommandResult]
|
350
467
|
def direct_container_command(command, args={})
|
351
468
|
begin
|
352
|
-
|
353
|
-
|
354
|
-
:
|
355
|
-
:
|
356
|
-
:
|
469
|
+
box = Rye::Box.new(
|
470
|
+
args.fetch(:ip, container_ip(3)),
|
471
|
+
:user => ssh_user,
|
472
|
+
:password => ssh_password,
|
473
|
+
:password_prompt => false,
|
474
|
+
:keys => [ssh_key],
|
475
|
+
:safe => false,
|
476
|
+
:paranoid => false
|
357
477
|
)
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
478
|
+
result = box.execute command
|
479
|
+
CommandResult.new(result)
|
480
|
+
rescue Rye::Err => e
|
481
|
+
if(args[:raise_on_failure])
|
482
|
+
raise CommandFailed.new(
|
483
|
+
"Command failed: #{command}",
|
484
|
+
CommandResult.new(e)
|
485
|
+
)
|
486
|
+
else
|
487
|
+
false
|
488
|
+
end
|
362
489
|
end
|
363
490
|
end
|
364
491
|
alias_method :knife_container, :direct_container_command
|
365
492
|
|
493
|
+
# Wait for container to reach given state
|
494
|
+
#
|
495
|
+
# @param desired_state [Symbol]
|
496
|
+
# @param args [Hash]
|
497
|
+
# @option args [Integer] :timeout
|
498
|
+
# @option args [Numeric] :sleep_interval
|
499
|
+
# @return [self]
|
366
500
|
def wait_for_state(desired_state, args={})
|
367
501
|
args[:sleep_interval] ||= 1.0
|
368
502
|
wait_total = 0.0
|
@@ -370,10 +504,18 @@ class Lxc
|
|
370
504
|
sleep(args[:sleep_interval])
|
371
505
|
wait_total += args[:sleep_interval]
|
372
506
|
end
|
507
|
+
self
|
373
508
|
end
|
374
509
|
|
375
|
-
#
|
376
|
-
#
|
510
|
+
# Write command to temporary file with networking enablement wrapper
|
511
|
+
# and yield relative path
|
512
|
+
#
|
513
|
+
# @param command [String]
|
514
|
+
# @param opts [Hash]
|
515
|
+
# @options opts [TrueClass, FalseClass] enable networking
|
516
|
+
# @yield block to execute
|
517
|
+
# @yieldparam command_script [String] path to file
|
518
|
+
# @return [Object] result of block
|
377
519
|
def tmp_execute_script(command, opts)
|
378
520
|
script_path = "tmp/#{SecureRandom.uuid}"
|
379
521
|
File.open(rootfs.join(script_path), 'w') do |file|
|
@@ -400,23 +542,12 @@ EOS
|
|
400
542
|
end
|
401
543
|
end
|
402
544
|
|
403
|
-
#
|
404
|
-
#
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
home = File.directory?('/root') && File.writable?('/root') ? '/root' : '/tmp'
|
410
|
-
if(set_if_missing)
|
411
|
-
ENV['HOME'] = home
|
412
|
-
end
|
413
|
-
home
|
414
|
-
end
|
415
|
-
end
|
416
|
-
|
417
|
-
# cmd:: Shell command string
|
418
|
-
# retries:: Number of retry attempts (1 second sleep interval)
|
419
|
-
# Runs command in container via ssh
|
545
|
+
# Run command within container
|
546
|
+
#
|
547
|
+
# @param cmd [String] command to run
|
548
|
+
# @param retries [Integer] number of retry attempts
|
549
|
+
# @return [CommandResult]
|
550
|
+
# @note retries are over 1 second intervals
|
420
551
|
def container_command(cmd, retries=1)
|
421
552
|
begin
|
422
553
|
detect_home(true)
|
@@ -438,18 +569,9 @@ EOS
|
|
438
569
|
end
|
439
570
|
end
|
440
571
|
|
441
|
-
def log
|
442
|
-
if(defined?(Chef))
|
443
|
-
Chef::Log
|
444
|
-
else
|
445
|
-
unless(@logger)
|
446
|
-
require 'logger'
|
447
|
-
@logger = Logger.new('/dev/null')
|
448
|
-
end
|
449
|
-
@logger
|
450
|
-
end
|
451
|
-
end
|
452
|
-
|
453
572
|
end
|
454
573
|
|
574
|
+
# Make default settings
|
455
575
|
Lxc.shellout_helper = :mixlib_shellout
|
576
|
+
Lxc.default_ssh_key = '/opt/hw-lxc-config/id_rsa'
|
577
|
+
Lxc.default_ssh_user = 'root'
|
@@ -1,11 +1,21 @@
|
|
1
|
+
require 'elecksee'
|
2
|
+
|
1
3
|
class Lxc
|
4
|
+
# Configuration file interface
|
2
5
|
class FileConfig
|
3
6
|
|
7
|
+
# @return [Array]
|
4
8
|
attr_reader :network
|
9
|
+
# @return [String] path to configuration file
|
5
10
|
attr_reader :base
|
6
11
|
|
7
12
|
class << self
|
8
13
|
|
14
|
+
# Convert object to Hash if possible
|
15
|
+
#
|
16
|
+
# @param thing [Object]
|
17
|
+
# @return [Hash]
|
18
|
+
# @note used mostly for the lxc resource within chef
|
9
19
|
def convert_to_hash(thing)
|
10
20
|
if(defined?(Chef) && thing.is_a?(Chef::Resource))
|
11
21
|
result = Hash[*(
|
@@ -26,6 +36,10 @@ class Lxc
|
|
26
36
|
result || thing
|
27
37
|
end
|
28
38
|
|
39
|
+
# Symbolize keys within hash
|
40
|
+
#
|
41
|
+
# @param thing [Hashish]
|
42
|
+
# @return [Hash]
|
29
43
|
def symbolize_hash(thing)
|
30
44
|
if(defined?(Mash))
|
31
45
|
Mash.new(thing)
|
@@ -38,6 +52,10 @@ class Lxc
|
|
38
52
|
end
|
39
53
|
end
|
40
54
|
|
55
|
+
# Generate configuration file contents
|
56
|
+
#
|
57
|
+
# @param resource [Hashish]
|
58
|
+
# @return [String]
|
41
59
|
def generate_config(resource)
|
42
60
|
resource = symbolize_hash(convert_to_hash(resource))
|
43
61
|
config = []
|
@@ -79,6 +97,9 @@ class Lxc
|
|
79
97
|
|
80
98
|
end
|
81
99
|
|
100
|
+
# Create new instance
|
101
|
+
#
|
102
|
+
# @param path [String]
|
82
103
|
def initialize(path)
|
83
104
|
raise 'LXC config file not found' unless File.exists?(path)
|
84
105
|
@path = path
|
@@ -89,6 +110,9 @@ class Lxc
|
|
89
110
|
|
90
111
|
private
|
91
112
|
|
113
|
+
# Parse the configuration file
|
114
|
+
#
|
115
|
+
# @return [TrueClass]
|
92
116
|
def parse!
|
93
117
|
cur_net = nil
|
94
118
|
File.readlines(@path).each do |line|
|
@@ -115,6 +139,8 @@ class Lxc
|
|
115
139
|
end
|
116
140
|
end
|
117
141
|
@network << cur_net if cur_net
|
142
|
+
true
|
118
143
|
end
|
144
|
+
|
119
145
|
end
|
120
146
|
end
|