class Puma::ControlCLI

Constants

COMMANDS

Public Class Methods

new(argv, stdout=STDOUT, stderr=STDERR) click to toggle source
# File vendor/gems/puma-2.8.2-java/lib/puma/control_cli.rb, line 16
def initialize(argv, stdout=STDOUT, stderr=STDERR)
  @argv = argv
  @stdout = stdout
  @stderr = stderr
  @options = {}

  opts = OptionParser.new do |o|
    o.banner = "Usage: pumactl (-p PID | -P pidfile | -S status_file | -C url -T token | -F config.rb) (#{COMMANDS.join("|")})"

    o.on "-S", "--state PATH", "Where the state file to use is" do |arg|
      @options[:state] = arg
    end

    o.on "-Q", "--quiet", "Not display messages" do |arg|
      @options[:quiet_flag] = true
    end

    o.on "-P", "--pidfile PATH", "Pid file" do |arg|
      @options[:pidfile] = arg
    end

    o.on "-p", "--pid PID", "Pid" do |arg|
      @options[:pid] = arg.to_i
    end

    o.on "-C", "--control-url URL", "The bind url to use for the control server" do |arg|
      @options[:control_url] = arg
    end

    o.on "-T", "--control-token TOKEN", "The token to use as authentication for the control server" do |arg|
      @options[:control_auth_token] = arg
    end

    o.on "-F", "--config-file PATH", "Puma config script" do |arg|
      @options[:config_file] = arg
    end

    o.on_tail("-H", "--help", "Show this message") do
      @stdout.puts o
      exit
    end

    o.on_tail("-V", "--version", "Show version") do
      puts Const::PUMA_VERSION
      exit
    end
  end

  opts.order!(argv) { |a| opts.terminate a }

  command = argv.shift
  @options[:command] = command if command

  Puma::Configuration.new(@options).load if @options[:config_file]

  # check present of command
  unless @options[:command]
    raise "Available commands: #{COMMANDS.join(", ")}"
  end

  unless COMMANDS.include? @options[:command]
    raise "Invalid command: #{@options[:command]}"
  end

rescue => e
  @stdout.puts e.message
  exit 1
end

Public Instance Methods

is_windows?() click to toggle source
# File vendor/gems/puma-2.8.2-java/lib/puma/control_cli.rb, line 12
def is_windows?
  RUBY_PLATFORM =~ /(win|w)32$/ ? true : false
end
message(msg) click to toggle source
# File vendor/gems/puma-2.8.2-java/lib/puma/control_cli.rb, line 85
def message(msg)
  @stdout.puts msg unless @options[:quiet_flag]
end
prepare_configuration() click to toggle source
# File vendor/gems/puma-2.8.2-java/lib/puma/control_cli.rb, line 89
def prepare_configuration
  if @options.has_key? :state
    unless File.exist? @options[:state]
      raise "Status file not found: #{@options[:state]}"
    end

    status = YAML.load File.read(@options[:state])

    if status.kind_of?(Hash) && status.has_key?("config")

      conf = status["config"]

      # get control_url
      if url = conf.options[:control_url]
        @options[:control_url] = url
      end

      # get control_auth_token
      if token = conf.options[:control_auth_token]
        @options[:control_auth_token] = token
      end

      # get pid
      @options[:pid] = status["pid"].to_i
    else
      raise "Invalid status file: #{@options[:state]}"
    end

  elsif @options.has_key? :pidfile
    # get pid from pid_file
    @options[:pid] = File.open(@options[:pidfile]).gets.to_i
  end
end
run() click to toggle source
# File vendor/gems/puma-2.8.2-java/lib/puma/control_cli.rb, line 215
def run
  start if @options[:command] == "start"

  prepare_configuration

  if is_windows?
    send_request
  else
    @options.has_key?(:control_url) ? send_request : send_signal
  end

rescue => e
  message e.message
  exit 1
end
send_request() click to toggle source
# File vendor/gems/puma-2.8.2-java/lib/puma/control_cli.rb, line 123
def send_request
  uri = URI.parse @options[:control_url]

  # create server object by scheme
  @server = case uri.scheme
            when "tcp"
              TCPSocket.new uri.host, uri.port
            when "unix"
              UNIXSocket.new "#{uri.host}#{uri.path}"
            else
              raise "Invalid scheme: #{uri.scheme}"
            end

  if @options[:command] == "status"
    message "Puma is started"
  else
    url = "/#{@options[:command]}"

    if @options.has_key?(:control_auth_token)
      url = url + "?token=#{@options[:control_auth_token]}"
    end

    @server << "GET #{url} HTTP/1.0\r\n\r\n"

    unless data = @server.read
      raise "Server closed connection before responding"
    end

    response = data.split("\r\n")

    if response.empty?
      raise "Server sent empty response"
    end

    (@http,@code,@message) = response.first.split(" ",3)

    if @code == "403"
      raise "Unauthorized access to server (wrong auth token)"
    elsif @code == "404"
      raise "Command error: #{response.last}"
    elsif @code != "200"
      raise "Bad response from server: #{@code}"
    end

    message "Command #{@options[:command]} sent success"
    message response.last if @options[:command] == "stats"
  end

  @server.close
end
send_signal() click to toggle source
# File vendor/gems/puma-2.8.2-java/lib/puma/control_cli.rb, line 174
def send_signal
  unless pid = @options[:pid]
    raise "Neither pid nor control url available"
  end

  begin
    Process.getpgid pid
  rescue SystemCallError
    if @options[:command] == "restart"
      @options.delete(:command)
      start
    else
      raise "No pid '#{pid}' found"
    end
  end

  case @options[:command]
  when "restart"
    Process.kill "SIGUSR2", pid

  when "halt"
    Process.kill "QUIT", pid

  when "stop"
    Process.kill "SIGTERM", pid

  when "stats"
    puts "Stats not available via pid only"
    return

  when "phased-restart"
    Process.kill "SIGUSR1", pid

  else
    message "Puma is started"
    return
  end

  message "Command #{@options[:command]} sent success"
end

Private Instance Methods

start() click to toggle source
# File vendor/gems/puma-2.8.2-java/lib/puma/control_cli.rb, line 232
def start
  require 'puma/cli'

  run_args = @argv

  if path = @options[:state]
    run_args = ["-S", path] + run_args
  end

  if path = @options[:config_file]
    run_args = ["-C", path] + run_args
  end

  events = Puma::Events.new @stdout, @stderr

  cli = Puma::CLI.new run_args, events
  cli.run
end