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



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/pleaserun/cli.rb', line 117

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



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
105
# File 'lib/pleaserun/cli.rb', line 65

def help # rubocop:disable MethodLength
  return <<-HELP
Welcome to pleaserun version #{PleaseRun::VERSION}!

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



220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/pleaserun/cli.rb', line 220

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(args) ⇒ Object



107
108
109
110
111
112
113
114
115
# File 'lib/pleaserun/cli.rb', line 107

def run(args)
  # Short circuit for a `fpm --version` or `fpm -v` short invocation that 
  # is the user asking us for the version of fpm.
  if args == [ "-v" ] || args == [ "--version" ]
    puts PleaseRun::VERSION
    return 0
  end
  super
end

#run_human(runner) ⇒ Object

def run_json



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/pleaserun/cli.rb', line 183

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
    PleaseRun::Installer.install_files(runner, target, overwrite?)

    if install_actions?
      actions_script = File.join(target, "install_actions.sh")
      PleaseRun::Installer.write_actions(runner, actions_script)
    end
  end
  return 0
end

#run_json(runner) ⇒ Object

def setup_defaults



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/pleaserun/cli.rb', line 165

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



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/pleaserun/cli.rb', line 149

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



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/pleaserun/cli.rb', line 199

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