Class: Train::Extras::LinuxCommand

Inherits:
CommandWrapperBase show all
Defined in:
lib/train/extras/command_wrapper.rb

Overview

Wrap linux commands and add functionality like sudo.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(backend, options) ⇒ LinuxCommand

Returns a new instance of LinuxCommand.



41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/train/extras/command_wrapper.rb', line 41

def initialize(backend, options)
  @backend = backend
  validate_options(options)

  @shell         = options[:shell]
  @shell_options = options[:shell_options] # e.g. '--login'
  @shell_command = options[:shell_command] # e.g. '/bin/sh'
  @sudo          = options[:sudo]
  @sudo_options  = options[:sudo_options]
  @sudo_password = options[:sudo_password]
  @sudo_command  = options[:sudo_command]
  @user          = options[:user]
end

Instance Attribute Details

#backendObject (readonly)

Returns the value of attribute backend.



39
40
41
# File 'lib/train/extras/command_wrapper.rb', line 39

def backend
  @backend
end

Class Method Details

.active?(options) ⇒ Boolean

Returns:

  • (Boolean)


104
105
106
107
108
109
# File 'lib/train/extras/command_wrapper.rb', line 104

def self.active?(options)
  options.is_a?(Hash) && (
    options[:sudo] ||
    options[:shell]
  )
end

Instance Method Details

#run(command) ⇒ Object



100
101
102
# File 'lib/train/extras/command_wrapper.rb', line 100

def run(command)
  shell_wrap(sudo_wrap(command))
end

#verifyObject



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
# File 'lib/train/extras/command_wrapper.rb', line 56

def verify
  # Do nothing, successfully. Don't use "true", that's not available on Windows.
  cmd = if @sudo
          # Wrap it up. It needs /dev/null on the outside to disable stdin
          "sh -c '(#{run("echo")}) < /dev/null'"
        else
          run("echo")
        end

  # rubocop:disable Style/BlockDelimiters
  res = @backend.with_sudo_pty {
    @backend.run_command(cmd)
  }
  return nil if res.exit_status == 0

  rawerr = "#{res.stdout} #{res.stderr}".strip

  case rawerr
  when /Sorry, try again/
    ["Wrong sudo password.", :bad_sudo_password]
  when /sudo: no tty present and no askpass program specified/
    ["Sudo requires a password, please configure it.", :sudo_password_required]
  when /sudo: command not found/
    ["Can't find sudo command. Please either install and "\
      "configure it on the target or deactivate sudo.", :sudo_command_not_found]
  when /sudo: sorry, you must have a tty to run sudo/
    ["Sudo requires a TTY. Please see the README on how to configure "\
      "sudo to allow for non-interactive usage.", :sudo_no_tty]
  when /sudo: a terminal is required to read the password; either use/
    ["Sudo cannot prompt for password because there is no terminal. "\
        "Please provide the sudo password directly", :sudo_missing_terminal]
  else
    [rawerr, nil]
  end
end

#verify!Object

Raises:



92
93
94
95
96
97
# File 'lib/train/extras/command_wrapper.rb', line 92

def verify!
  msg, reason = verify
  return nil unless msg

  raise Train::UserError.new("Sudo failed: #{msg}", reason)
end