Class: PleaseRun::CLI

Inherits:
Clamp::Command
  • Object
show all
Defined in:
lib/pleaserun/cli.rb

Overview

The CLI interface to pleaserun.

This is invoked by ‘bin/pleaserun`.

Instance Method Summary collapse

Instance Method Details

#executeObject



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
131
132
133
134
135
136
# File 'lib/pleaserun/cli.rb', line 106

def execute
  setup_logger
  setup_defaults

  # Load the platform implementation
  platform_klass = load_platform(platform)
  runner = platform_klass.new(target_version)

  platform_klass.all_attributes.each do |facet|
    next unless respond_to?(facet.name)
    # Get the value of this attribute
    # The idea here is to translate CLI options to runner settings
    value = send(facet.name)
    next if value.nil?
    @logger.debug("Setting runner attribute", :name => facet.name, :value => value)

    # Set the value in the runner we've selected
    # This is akin to `obj.someattribute = value`
    runner.send("#{facet.name}=", value)
  end

  if json?
    return run_json(runner)
  else
    return run_human(runner)
  end
  return 0
rescue PleaseRun::Error => e
  @logger.error("An error occurred: #{e}")
  return 1
end

#helpObject

rubocop:disable MethodLength



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
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/pleaserun/cli.rb', line 64

def help # rubocop:disable MethodLength
  return <<-HELP
Welcome to pleaserun!

This program aims to help you generate 'init' scripts/configs for various
platforms. The simplest example takes only the command you wish to run.
For example, let's run elasticsearch:

  % pleaserun /opt/elasticsearch/bin/elasticsearch

The above will automatically detect what platform you are running on
and try to use the most sensible init system. For Ubuntu, this means
Upstart. For Debian, this means sysv init scripts. For Fedora, this
means systemd.

You can tune the running environment and settings for your runner with various
flags. By way of example, let's make our elasticsearch service run as the
'elasticsearch' user!

  % pleaserun --user elasticsearch /opt/elasticsearch/bin/elasticsearch

If you don't want the platform autodetected, you can always specify the
exact process launcher to target:

  # Generate a sysv (/etc/init.d) script for LSB 3.1 (Debian uses this)
  % pleaserun -p sysv -v lsb-3.1 /opt/elasticsearch/bin/elasticsearch

Let's do another example. How about running nagios in systemd, but we
want to abort if the nagios config is invalid?

  % pleaserun -p systemd \
    --prestart "/usr/sbin/nagios -v /etc/nagios/nagios.cfg" \
    /usr/sbin/nagios /etc/nagios/nagios.cfg

The above makes 'nagios -v ...' run before any start/restart attempts
are made. If it fails, nagios will not start. Yay!

#{super}
  HELP
  # rubocop:enable MethodLength
end

#load_platform(v) ⇒ Object

def setup_logger



206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/pleaserun/cli.rb', line 206

def load_platform(v)
  @logger.debug("Loading platform", :platform => v)
  platform_lib = "pleaserun/platform/#{v}"
  require(platform_lib)

  const_name = v.downcase.gsub(/-([a-z])/) { |s| s[1] }
  const = PleaseRun::Platform.constants.find { |c| c.to_s.downcase == const_name.downcase }
  raise PleaseRun::PlatformLoadError, "Could not find platform named '#{v}' after loading library '#{platform_lib}' (#{const_name}). This is probably a bug." if const.nil?

  return PleaseRun::Platform.const_get(const)
rescue LoadError => e
  raise PleaseRun::PlatformLoadError, "Failed to find or load platform '#{v}'. This could be a typo or a bug. If it helps, the error is: #{e}"
end

#run_human(runner) ⇒ Object

def run_json



172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/pleaserun/cli.rb', line 172

def run_human(runner)
  if install?
    PleaseRun::Installer.install_files(runner, install_prefix, overwrite?)
    PleaseRun::Installer.install_actions(runner) if install_actions?
  else
    target = install_prefix || Stud::Temporary.directory
    actions_script = File.join(target, "install_actions.sh")
    PleaseRun::Installer.install_files(runner, target, overwrite?)
    PleaseRun::Installer.write_actions(runner, actions_script)
  end
  return 0
end

#run_json(runner) ⇒ Object

def setup_defaults



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/pleaserun/cli.rb', line 154

def run_json(runner)
  require "json"

  result = {}
  result["files"] = []
  runner.files.each do |path, content, perms|
    result["files"] << {
      "path" => path,
      "content" => content,
      "perms" => perms
    }
  end

  result["install_actions"] = runner.install_actions

  puts JSON.dump(result)
end

#setup_defaultsObject

def execute



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/pleaserun/cli.rb', line 138

def setup_defaults
  # Provide any dynamic defaults if necessary
  if platform.nil?
    require "pleaserun/detector"
    self.platform, self.target_version = PleaseRun::Detector.detect
    @logger.warn("No platform selected. Autodetecting...", :platform => platform, :version => target_version)
  end

  if name.nil?
    self.name = File.basename(program)
    @logger.warn("No name given, setting reasonable default based on the executable", :name => name)
  end

  nil
end

#setup_loggerObject

def run_human



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/pleaserun/cli.rb', line 185

def setup_logger
  @logger = Cabin::Channel.get
  if quiet?
    @logger.level = :error
  elsif verbose?
    @logger.level = :info
  elsif debug?
    @logger.level = :debug
  else
    @logger.level = :warn
  end

  if log
    logfile = File.new(log, "a")
    @logger.subscribe(logfile)
    #STDERR.puts "Sending all logs to #{log}" if STDERR.tty?
  else
    @logger.subscribe(STDERR)
  end
end