elecksee 1.0.20 → 1.0.22

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## v1.0.22
2
+ * Update underlying implementation for execute
3
+ * Provide better info interpretation
4
+ * Scrub bundler environment variables if found
5
+
1
6
  ## v1.0.20
2
7
  * Fix `LxcFileConfig` population when using `Chef::Resource` instance
3
8
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- elecksee (1.0.11)
4
+ elecksee (1.0.21)
5
5
  mixlib-shellout
6
6
  net-ssh
7
7
 
@@ -11,7 +11,7 @@ GEM
11
11
  childprocess (0.3.9)
12
12
  ffi (~> 1.0, >= 1.0.11)
13
13
  ffi (1.9.3)
14
- mixlib-shellout (1.2.0)
14
+ mixlib-shellout (1.3.0)
15
15
  net-ssh (2.7.0)
16
16
 
17
17
  PLATFORMS
@@ -49,6 +49,7 @@ class Lxc
49
49
 
50
50
  # Simple helper to shell out
51
51
  def run_command(cmd, args={})
52
+ result = nil
52
53
  cmd_type = Lxc.shellout_helper
53
54
  unless(cmd_type)
54
55
  if(defined?(ChildProcess))
@@ -57,16 +58,18 @@ class Lxc
57
58
  cmd_type = :mixlib_shellout
58
59
  end
59
60
  end
61
+ com_block = nil
60
62
  case cmd_type
61
63
  when :childprocess
62
64
  require 'tempfile'
63
- result = child_process_command(cmd, args)
65
+ com_block = lambda{ child_process_command(cmd, args) }
64
66
  when :mixlib_shellout
65
67
  require 'mixlib/shellout'
66
- result = mixlib_shellout_command(cmd, args)
68
+ com_block = lambda{ mixlib_shellout_command(cmd, args) }
67
69
  else
68
70
  raise ArgumentError.new("Unknown shellout helper provided: #{cmd_type}")
69
71
  end
72
+ result = defined?(Bundler) ? Bundler.with_clean_env{ com_block.call } : com_block.call
70
73
  result == false ? false : CommandResult.new(result)
71
74
  end
72
75
 
data/lib/elecksee/lxc.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require 'elecksee/helpers/base'
2
+ require 'securerandom'
3
+ require 'shellwords'
2
4
  require 'pathname'
3
5
  require 'tmpdir'
4
6
 
@@ -71,18 +73,23 @@ class Lxc
71
73
  # name:: Name of container
72
74
  # Returns information about given container
73
75
  def info(name)
74
- res = {:state => nil, :pid => nil}
75
- info = run_command("#{sudo}lxc-info -n #{name}", :allow_failure_retry => 3).stdout.split("\n")
76
- if(info.first)
77
- parts = info.first.split(' ')
78
- res[:state] = parts.last.downcase.to_sym
79
- parts = info.last.split(' ')
80
- res[:pid] = parts.last.to_i
81
- res
76
+ info = run_command("#{sudo}lxc-info -n #{name}", :allow_failure_retry => 3, :allow_failure => true)
77
+ if(info)
78
+ Hash[
79
+ info.stdout.split("\n").map do |string|
80
+ string.split(': ').map(&:strip)
81
+ end.map do |key, value|
82
+ key = key.tr(' ', '_').downcase.to_sym
83
+ if(key == :state)
84
+ value = value.downcase.to_sym
85
+ elsif(value.to_i.to_s == value)
86
+ value = value.to_i
87
+ end
88
+ [key, value]
89
+ end
90
+ ]
82
91
  else
83
- res[:state] = :unknown
84
- res[:pid] = -1
85
- res
92
+ Hash[:state, :unknown, :pid, -1]
86
93
  end
87
94
  end
88
95
 
@@ -270,34 +277,34 @@ class Lxc
270
277
  # Start the container
271
278
  def start(*args)
272
279
  if(args.include?(:no_daemon))
273
- run_command("#{sudo}lxc-start -n #{name}")
280
+ run_command("lxc-start -n #{name}", :sudo => true)
274
281
  else
275
- run_command("#{sudo}lxc-start -n #{name} -d")
282
+ run_command("lxc-start -n #{name} -d", :sudo => true)
276
283
  wait_for_state(:running)
277
284
  end
278
285
  end
279
286
 
280
287
  # Stop the container
281
288
  def stop
282
- run_command("#{sudo}lxc-stop -n #{name}", :allow_failure_retry => 3)
289
+ run_command("lxc-stop -n #{name}", :allow_failure_retry => 3, :sudo => true)
283
290
  wait_for_state(:stopped)
284
291
  end
285
292
 
286
293
  # Freeze the container
287
294
  def freeze
288
- run_command("#{sudo}lxc-freeze -n #{name}")
295
+ run_command("lxc-freeze -n #{name}", :sudo => true)
289
296
  wait_for_state(:frozen)
290
297
  end
291
298
 
292
299
  # Unfreeze the container
293
300
  def unfreeze
294
- run_command("#{sudo}lxc-unfreeze -n #{name}")
301
+ run_command("lxc-unfreeze -n #{name}", :sudo => true)
295
302
  wait_for_state(:running)
296
303
  end
297
304
 
298
305
  # Shutdown the container
299
306
  def shutdown
300
- run_command("#{sudo}lxc-shutdown -n #{name}")
307
+ run_command("lxc-shutdown -n #{name}", :sudo => true)
301
308
  wait_for_state(:stopped, :timeout => 120)
302
309
  # This block is for fedora/centos/anyone else that does not like lxc-shutdown
303
310
  if(running?)
@@ -315,7 +322,29 @@ class Lxc
315
322
  unless stopped?
316
323
  stop
317
324
  end
318
- run_command("#{sudo}lxc-destroy -n #{name}")
325
+ run_command("lxc-destroy -n #{name}", :sudo => true)
326
+ end
327
+
328
+ # command:: command string
329
+ # opts:: option hash (:networking)
330
+ # Execute command string within container
331
+ def execute(command, opts={})
332
+ if(stopped?)
333
+ cmd = Shellwords.split(command)
334
+ result = nil
335
+ begin
336
+ tmp_execute_script(command, opts) do |script_path|
337
+ result = run_command("lxc-execute -n #{name} -- #{script_path}", :sudo => true)
338
+ end
339
+ rescue => e
340
+ if(e.result.stderr.downcase.include?('failed to find an lxc-init'))
341
+ $stderr.puts "ERROR: Missing `lxc-init` installation on container (#{name}). Install lxc-init on container before using `#execute`!"
342
+ end
343
+ raise
344
+ end
345
+ else
346
+ raise "Cannot execute against running container (#{name})"
347
+ end
319
348
  end
320
349
 
321
350
  def direct_container_command(command, args={})
@@ -333,35 +362,7 @@ class Lxc
333
362
  end
334
363
  end
335
364
  alias_method :knife_container, :direct_container_command
336
- =begin
337
- # Simple helper to shell out
338
- def run_command(cmd, args={})
339
- retries = args[:allow_failure_retry].to_i
340
- begin
341
- shlout = Mixlib::ShellOut.new(cmd,
342
- :logger => defined?(Chef) ? Chef::Log.logger : log,
343
- :live_stream => args[:livestream] ? nil : STDOUT,
344
- :timeout => args[:timeout] || 1200,
345
- :environment => {'HOME' => detect_home}
346
- )
347
- shlout.run_command
348
- shlout.error!
349
- shlout
350
- rescue Mixlib::ShellOut::ShellCommandFailed, CommandFailed, Mixlib::ShellOut::CommandTimeout
351
- if(retries > 0)
352
- log.warn "LXC run command failed: #{cmd}"
353
- log.warn "Retrying command. #{args[:allow_failure_retry].to_i - retries} of #{args[:allow_failure_retry].to_i} retries remain"
354
- sleep(0.3)
355
- retries -= 1
356
- retry
357
- elsif(args[:allow_failure])
358
- true
359
- else
360
- raise
361
- end
362
- end
363
- end
364
- =end
365
+
365
366
  def wait_for_state(desired_state, args={})
366
367
  args[:sleep_interval] ||= 1.0
367
368
  wait_total = 0.0
@@ -371,6 +372,34 @@ class Lxc
371
372
  end
372
373
  end
373
374
 
375
+ # command:: command string
376
+ # Write command to temporary script with networking support wrap
377
+ def tmp_execute_script(command, opts)
378
+ script_path = "tmp/#{SecureRandom.uuid}"
379
+ File.open(rootfs.join(script_path), 'w') do |file|
380
+ file.puts '#!/bin/sh'
381
+ unless(opts[:networking] == false)
382
+ file.write <<-EOS
383
+ /etc/network/if-pre-up.d/bridge > /dev/null 2>&1
384
+ ifdown eth0 > /dev/null 2>&1
385
+ ifup eth0 > /dev/null 2>&1
386
+ EOS
387
+ end
388
+ file.puts command
389
+ file.puts "RESULT=$?"
390
+ unless(opts[:networking] == false)
391
+ file.puts "ifdown eth0 > /dev/null 2>&1"
392
+ end
393
+ file.puts "exit $RESULT"
394
+ end
395
+ FileUtils.chmod(0755, rootfs.join(script_path))
396
+ begin
397
+ yield "/#{script_path}"
398
+ ensure
399
+ FileUtils.rm(rootfs.join(script_path))
400
+ end
401
+ end
402
+
374
403
  # Detect HOME environment variable. If not an acceptable
375
404
  # value, set to /root or /tmp
376
405
  def detect_home(set_if_missing=false)
@@ -1,17 +1,17 @@
1
1
  require 'elecksee/helpers/base'
2
2
 
3
3
  class Lxc
4
-
4
+
5
5
  class VirtualDevice
6
6
 
7
7
  include Helpers
8
-
8
+
9
9
  attr_reader :name
10
10
  attr_reader :tmp_dir
11
11
  attr_reader :size
12
12
  attr_reader :tmp_fs
13
13
  attr_reader :fs_type
14
-
14
+
15
15
  def initialize(name, args={})
16
16
  @name = name
17
17
  @tmp_dir = args[:tmp_dir] || '/tmp/lxc/ephemerals'
@@ -23,7 +23,7 @@ class Lxc
23
23
  end
24
24
 
25
25
  def device_path
26
- tmp_fs ? 'none' : File.join(tmp_dir, 'virt-imgs', name)
26
+ tmp_fs ? :none : File.join(tmp_dir, 'virt-imgs', name)
27
27
  end
28
28
 
29
29
  def mount_path
@@ -42,7 +42,7 @@ class Lxc
42
42
  def mounted?
43
43
  command("mount").stdout.include?(mount_path)
44
44
  end
45
-
45
+
46
46
  def mount
47
47
  unless(mounted?)
48
48
  command("mount -t #{fs_type}#{mount_options} #{device_path} #{mount_path}", :sudo => true)
@@ -59,9 +59,11 @@ class Lxc
59
59
 
60
60
  def destroy
61
61
  unmount
62
- File.delete(device_path) if File.file?(device_path)
63
- FileUtils.rm_rf(device_path) if File.directory?(device_path)
64
- FileUtils.rmdir(mount_path) if File.directory?(mount_path)
62
+ unless(device_path == :none)
63
+ File.delete(device_path) if File.file?(device_path)
64
+ FileUtils.rm_rf(device_path) if File.directory?(device_path)
65
+ end
66
+ FileUtils.rmdir(mount_path) if File.directory?(mount_path) unless mount_path == :none
65
67
  end
66
68
 
67
69
  private
@@ -69,9 +71,10 @@ class Lxc
69
71
  def mount_options
70
72
  ' -o loop' unless tmp_fs
71
73
  end
72
-
74
+
73
75
  def make_directories!
74
76
  [device_path, mount_path].each do |path|
77
+ next if path == :none
75
78
  unless(File.directory?(path))
76
79
  FileUtils.mkdir_p(path)
77
80
  end
@@ -1,6 +1,3 @@
1
1
  module Elecksee
2
- class Version < Gem::Version
3
- end
4
-
5
- VERSION = Version.new('1.0.20')
2
+ VERSION = Gem::Version.new('1.0.22')
6
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elecksee
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.20
4
+ version: 1.0.22
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-01-08 00:00:00.000000000 Z
12
+ date: 2014-06-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mixlib-shellout