lib/gemirro/cli/server.rb in gemirro-0.2.0 vs lib/gemirro/cli/server.rb in gemirro-0.3.0

- old
+ new

@@ -1,20 +1,114 @@ # -*- coding: utf-8 -*- + Gemirro::CLI.options.command 'server' do banner 'Usage: gemirro server [OPTIONS]' - description 'Run web server' + description 'Manage web server' separator "\nOptions:\n" + on :start, 'Run web server' + on :stop, 'Stop web server' + on :restart, 'Restart web server' + on :status, 'Status of web server' on :c=, :config=, 'Path to the configuration file' + @pid_file = nil run do |opts, _args| + load_configuration(opts) + start if opts[:start] + stop if opts[:stop] + restart if opts[:restart] + status if opts[:status] + end + + def load_configuration(opts) Gemirro::CLI.load_configuration(opts[:c]) config = Gemirro.configuration unless File.directory?(config.destination) config.logger.error("The directory #{config.destination} does not exist") abort end + @pid_file = File.join(config.destination, '..', 'gemirro.pid') require 'gemirro/server' + end + + # Copy stdout because we'll need to reopen it later on + @orig_stdout = STDOUT.clone + $PROGRAM_NAME = 'gemirro' + + def create_pid + File.open(@pid_file, 'w') do |f| + f.write("#{Process.pid}") + end + rescue Errno::EACCES + STDOUT.reopen @orig_stdout + puts "Error: Can't write to #{@pid_file} - Permission denied" + exit! + end + + def destroy_pid + File.delete(@pid_file) if File.exist?(@pid_file) && pid == Process.pid + end + + def pid + File.open(@pid_file, 'r') do |f| + return f.gets.to_i + end + rescue Errno::ENOENT + puts "Error: PID File not found #{@pid_file}" + exit! + end + + def start + puts 'Starting...' + if File.exist?(@pid_file) + if running?(pid) + puts "Error: #{$PROGRAM_NAME} already running" + abort + end + end + + Process.daemon + create_pid + STDOUT.reopen @orig_stdout + puts "done! (PID is #{pid})\n" Gemirro::Server.run! + destroy_pid + STDOUT.reopen '/dev/null', 'a' + end + + def stop + process_pid = pid + begin + Process.kill('TERM', process_pid) + Timeout.timeout(30) { sleep 0.1 while running?(process_pid) } + rescue Errno::ESRCH + puts "Error: Couldn't find process with PID #{process_pid}" + exit! + rescue Timeout::Error + puts 'timeout while sending TERM signal, sending KILL signal now... ' + Process.kill('KILL', process_pid) + destroy_pid + end + puts 'done!' + end + + def restart + stop + start + end + + def status + if running?(pid) + puts "#{$PROGRAM_NAME} is running" + else + puts "#{$PROGRAM_NAME} is not running" + end + end + + def running?(process_id) + Process.getpgid(process_id) != -1 + rescue Errno::ESRCH + false end end