Module: Lxc::Helpers

Included in:
Lxc, Lxc, Clone, Ephemeral, Storage::OverlayDirectory, Storage::OverlayMount, Storage::VirtualDevice
Defined in:
lib/elecksee/helpers.rb,
lib/elecksee/helpers/copies.rb,
lib/elecksee/helpers/options.rb

Overview

Helper modules

Defined Under Namespace

Modules: Copies, Options

Class Attribute Summary collapse

Instance Method Summary collapse

Class Attribute Details

.child_process_lockObject

Returns the value of attribute child_process_lock.



8
9
10
# File 'lib/elecksee/helpers.rb', line 8

def child_process_lock
  @child_process_lock
end

Instance Method Details

#child_process_command(cmd, args) ⇒ ChildProcess::AbstractProcess

Shellout using childprocess

Parameters:

  • cmd (String)
  • args (Hash)

Options Hash (args):

  • :allow_failure_retry (Integer)

    number of retries

  • :timeout (Numeric)

    max execution time

  • :sudo (TrueClass, FalseClass)

    use sudo

  • :allow_failure (TrueClass, FalseClass)

    don’t raise on error

Returns:

  • (ChildProcess::AbstractProcess)


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/elecksee/helpers.rb', line 55

def child_process_command(cmd, args)
  retries = args[:allow_failure_retry].to_i
  cmd = [sudo, cmd].join(' ') if args[:sudo]
  begin
    s_out = Tempfile.new('stdout')
    s_err = Tempfile.new('stderr')
    s_out.sync
    s_err.sync
    c_proc = nil
    Lxc::Helpers.child_process_lock.synchronize do
      c_proc = ChildProcess.build(*Shellwords.split(cmd))
      c_proc.environment.merge('HOME' => detect_home)
      c_proc.io.stdout = s_out
      c_proc.io.stderr = s_err
      c_proc.start
    end
    begin
      c_proc.poll_for_exit(args[:timeout] || 1200)
    rescue ChildProcess::TimeoutError
      c_proc.stop
    ensure
      raise CommandFailed.new("Command failed: #{cmd}", CommandResult.new(c_proc)) if c_proc.crashed?
    end
    c_proc
  rescue CommandFailed
    if(retries > 0)
      log.warn "LXC run command failed: #{cmd}"
      log.warn "Retrying command. #{args[:allow_failure_retry].to_i - retries} of #{args[:allow_failure_retry].to_i} retries remain"
      sleep(0.3)
      retries -= 1
      retry
    elsif(args[:allow_failure])
      false
    else
      raise
    end
  end
end

#detect_home(set_if_missing = false) ⇒ String

Note:

if detection fails, first writeable path is used from /root or /tmp

Detect HOME if environment variable is not set

Parameters:

  • set_if_missing (TrueClass, FalseClass) (defaults to: false)

    set environment variable if missing

Returns:

  • (String)

    value detected



151
152
153
154
155
156
157
158
159
160
161
# File 'lib/elecksee/helpers.rb', line 151

def detect_home(set_if_missing=false)
  if(ENV['HOME'] && Pathname.new(ENV['HOME']).absolute?)
    ENV['HOME']
  else
    home = File.directory?('/root') && File.writable?('/root') ? '/root' : '/tmp'
    if(set_if_missing)
      ENV['HOME'] = home
    end
    home
  end
end

#logLogger

Returns logger instance.

Returns:

  • (Logger)

    logger instance



134
135
136
137
138
139
140
141
142
143
144
# File 'lib/elecksee/helpers.rb', line 134

def log
  if(defined?(Chef))
    Chef::Log
  else
    unless(@logger)
      require 'logger'
      @logger = Logger.new('/dev/null')
    end
    @logger
  end
end

#mixlib_shellout_command(cmd, args) ⇒ Mixlib::ShellOut

Shellout using mixlib shellout

Parameters:

  • cmd (String)
  • args (Hash)

Options Hash (args):

  • :allow_failure_retry (Integer)

    number of retries

  • :timeout (Numeric)

    max execution time

  • :sudo (TrueClass, FalseClass)

    use sudo

  • :allow_failure (TrueClass, FalseClass)

    don’t raise on error

Returns:

  • (Mixlib::ShellOut)


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/elecksee/helpers.rb', line 103

def mixlib_shellout_command(cmd, args)
  retries = args[:allow_failure_retry].to_i
  cmd = [sudo, cmd].join(' ') if args[:sudo]
  shlout = nil
  begin
    shlout = Mixlib::ShellOut.new(cmd,
      :logger => defined?(Chef) && defined?(Chef::Log) ? Chef::Log.logger : log,
      :live_stream => args[:livestream] ? STDOUT : nil,
      :timeout => args[:timeout] || 1200,
      :environment => {'HOME' => detect_home}
    )
    shlout.run_command
    shlout.error!
    shlout
  rescue Mixlib::ShellOut::ShellCommandFailed, CommandFailed, Mixlib::ShellOut::CommandTimeout => e
    if(retries > 0)
      log.warn "LXC run command failed: #{cmd}"
      log.warn "Retrying command. #{args[:allow_failure_retry].to_i - retries} of #{args[:allow_failure_retry].to_i} retries remain"
      sleep(0.3)
      retries -= 1
      retry
    elsif(args[:allow_failure])
      false
    else
      raise CommandFailed.new(e, CommandResult.new(shlout))
    end
  end
end

#run_command(cmd, args = {}) ⇒ CommandResult Also known as: command

Shellout wrapper

Parameters:

  • cmd (String)
  • args (Hash) (defaults to: {})

Options Hash (args):

  • :allow_failure_retry (Integer)

    number of retries

  • :timeout (Numeric)

    max execution time

  • :sudo (TrueClass, FalseClass)

    use sudo

  • :allow_failure (TrueClass, FalseClass)

    don’t raise on error

Returns:



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/elecksee/helpers.rb', line 28

def run_command(cmd, args={})
  result = nil
  cmd_type = :childprocess
  com_block = nil
  case cmd_type
  when :childprocess
    require 'tempfile'
    com_block = lambda{ child_process_command(cmd, args) }
  when :mixlib_shellout
    require 'mixlib/shellout'
    com_block = lambda{ mixlib_shellout_command(cmd, args) }
  else
    raise ArgumentError.new("Unknown shellout helper provided: #{cmd_type}")
  end
  result = defined?(Bundler) ? Bundler.with_clean_env{ com_block.call } : com_block.call
  result == false ? false : CommandResult.new(result)
end

#sudoString

Returns sudo command string.

Returns:

  • (String)

    sudo command string



15
16
17
# File 'lib/elecksee/helpers.rb', line 15

def sudo
  Lxc.sudo
end