Parent

Class/Module Index [+]

Quicksearch

Omnibus::Ctl

Attributes

base_path[RW]
command_map[RW]
data_path[RW]
display_name[RW]
etc_path[RW]
fh_output[RW]
kill_users[RW]
log_exclude[RW]
log_path[RW]
name[RW]
service_path[RW]
sv_path[RW]

Public Class Methods

new(name) click to toggle source
# File lib/omnibus-ctl.rb, line 33
def initialize(name)
  @name = name
  @display_name = name
  @base_path = "/opt/#{name}"
  @sv_path = File.join(@base_path, "sv")
  @service_path = File.join(@base_path, "service")
  @log_path = "/var/log/#{name}"
  @data_path = "/var/opt/#{name}"
  @etc_path = "/etc/#{name}"
  @log_exclude = '(lock|@)'
  @fh_output = STDOUT
  @kill_users = []
  @command_map = {
    "show-config" => {
      :desc => "Show the configuration that would be generated by reconfigure.",
      :arity => 1
    },
    "reconfigure" => {
      :desc => "Reconfigure the application.",
      :arity => 1
    },
    "cleanse" => {
      :desc => "Delete *all* private chef data, and start from scratch.",
      :arity => 2
    },
    "uninstall" => {
      :arity => 1,
      :desc => "Kill all processes and uninstall the process supervisor (data will be preserved)."
    },
    "service-list" => {
      :arity => 1,
      :desc => "List all the services (enabled services appear with a *.)"
    },
    "status" => {
      :desc => "Show the status of all the services.",
      :arity => 2
    },
    "tail" => {
      :desc => "Watch the service logs of all enabled services.",
      :arity => 2
    },
    "start" => {
      :desc => "Start services if they are down, and restart them if they stop.",
      :arity => 2
    },
    "stop" => {
      :desc => "Stop the services, and do not restart them.",
      :arity => 2
    },
    "restart" => {
      :desc => "Stop the services if they are running, then start them again.",
      :arity => 2
    },
    "once" => {
      :desc => "Start the services if they are down. Do not restart them if they stop.",
      :arity => 2
    },
    "hup" => {
      :desc => "Send the services a HUP.",
      :arity => 2
    },
    "term" => {
      :desc => "Send the services a TERM.",
      :arity => 2
    },
    "int" => {
      :desc => "Send the services an INT.",
      :arity => 2
    },
    "kill" => {
      :desc => "Send the services a KILL.",
      :arity => 2
    },
    "graceful-kill" => {
      :desc => "Attempt a graceful stop, then SIGKILL the entire process group.",
      :arity => 2
    },
    "help" => {
      :arity => 1,
      :desc => "Print this help message."
    }
  }
end

Public Instance Methods

add_command(name, description, arity=1, &block) click to toggle source
# File lib/omnibus-ctl.rb, line 132
def add_command(name, description, arity=1, &block)
  @command_map[name] = { :desc => description, :arity => arity }
  metaclass = class << self; self; end
  # Ruby does not like dashes in method names
  method_name = name.gsub(/-/, "_")
  metaclass.send(:define_method, method_name.to_sym) { |*args| block.call(*args) }
end
cleanse(*args) click to toggle source
# File lib/omnibus-ctl.rb, line 219
def cleanse(*args)
  log "This will delete *all* configuration, log, and variable data associated with this application.\n\n*** You have 60 seconds to hit CTRL-C ***\n\n"
  unless args[1] == "yes"
    sleep 60
  end
  cleanup_procs_and_nuke("#{service_path}/* /tmp/opt #{data_path} #{etc_path} #{log_path}")
end
cleanup_procs_and_nuke(filestr) click to toggle source
# File lib/omnibus-ctl.rb, line 177
def cleanup_procs_and_nuke(filestr)
  begin
    run_sv_command("stop")
  rescue SystemExit
  end

  FileUtils.rm_f("/etc/init/#{name}-runsvdir.conf") if File.exists?("/etc/init/#{name}-runsvdir.conf")
  run_command("egrep -v '#{base_path}/embedded/bin/runsvdir-start' /etc/inittab > /etc/inittab.new && mv /etc/inittab.new /etc/inittab") if File.exists?("/etc/inittab")
  run_command("kill -1 1")

  backup_dir = Time.now.strftime("/root/#{name}-cleanse-%FT%R")
  FileUtils.mkdir_p("/root") unless File.exists?("/root")
  FileUtils.rm_rf(backup_dir)
  FileUtils.cp_r(etc_path, backup_dir) if File.exists?(etc_path)
  run_command("rm -rf #{filestr}")

  begin
    graceful_kill
  rescue SystemExit
  end

  run_command("pkill -HUP -u #{kill_users.join(',')}") if kill_users.length > 0
  run_command("pkill -HUP -f 'runsvdir -P #{service_path}'")
  sleep 3
  run_command("pkill -TERM -u #{kill_users.join(',')}") if kill_users.length > 0
  run_command("pkill -TERM -f 'runsvdir -P #{service_path}'")
  sleep 3
  run_command("pkill -KILL -u #{kill_users.join(',')}") if kill_users.length > 0
  run_command("pkill -KILL -f 'runsvdir -P #{service_path}'")

  get_all_services.each do |die_daemon_die|
    run_command("pkill -KILL -f 'runsv #{die_daemon_die}'")
  end

  log "Your config files have been backed up to #{backup_dir}."
  exit! 0
end
exit!(error_code) click to toggle source
# File lib/omnibus-ctl.rb, line 140
def exit!(error_code)
  exit error_code
end
get_all_services() click to toggle source
# File lib/omnibus-ctl.rb, line 231
def get_all_services
  get_all_services_files.map { |f| File.basename(f) }.sort
end
get_all_services_files() click to toggle source
# File lib/omnibus-ctl.rb, line 227
def get_all_services_files
  Dir[File.join(sv_path, '*')]
end
get_pgrp_from_pid(pid) click to toggle source
# File lib/omnibus-ctl.rb, line 148
def get_pgrp_from_pid(pid)
  ps=`which ps`.chomp
  `#{ps} -p #{pid} -o pgrp=`.chomp
end
get_pids_from_pgrp(pgrp) click to toggle source
# File lib/omnibus-ctl.rb, line 153
def get_pids_from_pgrp(pgrp)
  pgrep=`which pgrep`.chomp
  `#{pgrep} -g #{pgrp}`.split(/\n/).join(" ")
end
graceful_kill(*args) click to toggle source
# File lib/omnibus-ctl.rb, line 292
def graceful_kill(*args)
  service = args[1]
  exit_status = 0
  get_all_services.each do |service_name|
    next if !service.nil? && service_name != service
    if service_enabled?(service_name)
      pidfile="#{sv_path}/#{service_name}/supervise/pid"
      pid=File.read(pidfile).chomp if File.exists?(pidfile)
      if pid.nil? || !is_integer?(pid)
        log "could not find #{service_name} runit pidfile (service already stopped?), cannot attempt SIGKILL..."
        status = run_command("#{base_path}/init/#{service_name} stop")
        exit_status = status.exitstatus if exit_status == 0 && !status.success?
        next
      end
      pgrp=get_pgrp_from_pid(pid)
      if pgrp.nil? || !is_integer?(pgrp)
        log "could not find pgrp of pid #{pid} (not running?), cannot attempt SIGKILL..."
        status = run_command("#{base_path}/init/#{service_name} stop")
        exit_status = status.exitstatus if exit_status == 0 && !status.success?
        next
      end
      run_command("#{base_path}/init/#{service_name} stop")
      pids=get_pids_from_pgrp(pgrp)
      if !pids.empty?
        log "found stuck pids still running in process group: #{pids}, sending SIGKILL" unless pids.empty?
        sigkill_pgrp(pgrp)
      end
    else
      log "#{service_name} disabled, not stopping"
      exit_status = 1
    end
  end
  exit! exit_status
end
help(*args) click to toggle source
# File lib/omnibus-ctl.rb, line 327
def help(*args)
  log "#{$0}: command (subcommand)\n"
  command_map.keys.sort.each do |command|
    log command
    log "  #{command_map[command][:desc]}"
  end
  exit! 1
end
is_integer?(string) click to toggle source
# File lib/omnibus-ctl.rb, line 288
def is_integer?(string)
  return true if Integer(string) rescue false
end
load_files(path) click to toggle source
# File lib/omnibus-ctl.rb, line 126
def load_files(path)
  Dir["#{path}/*.rb"].each do |file|
    eval(IO.read(file))
  end
end
log(msg) click to toggle source
# File lib/omnibus-ctl.rb, line 144
def log(msg)
  fh_output.puts msg
end
reconfigure(exit_on_success=true) click to toggle source
# File lib/omnibus-ctl.rb, line 270
def reconfigure(exit_on_success=true)
  status = run_command("chef-solo -c #{base_path}/embedded/cookbooks/solo.rb -j #{base_path}/embedded/cookbooks/dna.json")
  if status.success?
    log "#{display_name} Reconfigured!"
    exit! 0 if exit_on_success
  else
    exit! 1
  end
end
run(args) click to toggle source
# File lib/omnibus-ctl.rb, line 336
def run(args)
  # Ensure Omnibus related binaries are in the PATH
  ENV["PATH"] = [File.join(base_path, "bin"),
                 File.join(base_path, "embedded","bin"),
                 ENV['PATH']].join(":")

  command_to_run = args[0]

  if !command_map.has_key?(command_to_run)
    log "I don't know that command."
    if args.length == 2
      log "Did you mean: #{$0} #{args[1]} #{args[0]}?"
    end
    help
  end

  if args.length > 1 && command_map[command_to_run][:arity] != 2
    log "The command #{command_to_run} does not accept any arguments"
    exit! 2
  end

  method_to_call = command_to_run.gsub(/-/, '_')
  self.send(method_to_call.to_sym, *args)
end
run_command(command) click to toggle source
# File lib/omnibus-ctl.rb, line 163
def run_command(command)
  system(command)
  $?
end
run_sv_command(sv_cmd, service=nil) click to toggle source
# File lib/omnibus-ctl.rb, line 239
def run_sv_command(sv_cmd, service=nil)
  exit_status = 0
  get_all_services.each do |service_name|
    next if !service.nil? && service_name != service
    if service_enabled?(service_name)
      status = run_command("#{base_path}/init/#{service_name} #{sv_cmd}")
      exit_status = status.exitstatus if exit_status == 0 && !status.success?
    else
      log "#{service_name} disabled" if sv_cmd == "status"
    end
  end
  exit! exit_status
end
running_config() click to toggle source
# File lib/omnibus-ctl.rb, line 253
def running_config
  @running_config ||= begin
    if File.exists?("#{etc_path}/chef-server-running.json")
      JSON.parse(File.read("#{etc_path}/chef-server-running.json"))
    end
  end
end
service_enabled?(service_name) click to toggle source
# File lib/omnibus-ctl.rb, line 235
def service_enabled?(service_name)
  File.symlink?("#{service_path}/#{service_name}")
end
service_list(*args) click to toggle source
# File lib/omnibus-ctl.rb, line 168
def service_list(*args)
  get_all_services.each do |service_name|
    print "#{service_name}"
    print "*" if service_enabled?(service_name)
    print "\n"
  end
  exit! 0
end
show_config(*args) click to toggle source
# File lib/omnibus-ctl.rb, line 261
def show_config(*args)
  status = run_command("chef-solo -c #{base_path}/embedded/cookbooks/solo.rb -j #{base_path}/embedded/cookbooks/show-config.json -l fatal")
  if status.success?
    exit! 0
  else
    exit! 1
  end
end
sigkill_pgrp(pgrp) click to toggle source
# File lib/omnibus-ctl.rb, line 158
def sigkill_pgrp(pgrp)
  pkill=`which pkill`.chomp
  run_command("#{pkill} -9 -g #{pgrp}")
end
tail(*args) click to toggle source
# File lib/omnibus-ctl.rb, line 280
def tail(*args)
  if args[1]
    system("find #{log_path}/#{args[1]} -type f | grep -E -v '#{log_exclude}' | xargs tail --follow=name --retry")
  else
    system("find #{log_path} -type f | grep -E -v '#{log_exclude}' | xargs tail --follow=name --retry")
  end
end
uninstall(*args) click to toggle source
# File lib/omnibus-ctl.rb, line 215
def uninstall(*args)
  cleanup_procs_and_nuke("/tmp/opt")
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.