Skip to content

Instantly share code, notes, and snippets.

@spiegela
Created May 18, 2012 14:43
Show Gist options
  • Save spiegela/2725608 to your computer and use it in GitHub Desktop.
Save spiegela/2725608 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# ^^ Replace with an RVM wrapper if RVM is to be used.
require "bundler/setup"
require 'methadone'
require "etc"
# Lambda for init script to fork into new daemon
STARTUP = labmda{ Verify::Pool.new(:environment => env).start }
# Default application root. Can be overridden with command line option
DEF_APP_ROOT = '/srv/app/verify/current'
# This should be the name of our library to require also
APP_NAME = 'verify'
# Plain text description used in help messages
DESCRIPTION = 'Verify Worker Pool'
# Init script designed to be run as root. Change to this user prior to fork.
DEFAULT_USER = 'vd'
require APP_NAME
module Verify
class Init
include Methadone::Main
include Methadone::CLILogging
main do |action|
logger = options[:logger]
change_user!
case action
when 'start' then start!
when 'stop' then stop!
when 'restart' then stop!; start! # start whether it's running or not
when 'try-restart' then stop! and start! # start only if it's running
when 'status' then status!
else
raise ArgumentError, 'Invalid action specified. We support: "start", "start", "restart" and "status"'
end
end
description "Initialization script for #{DESCRIPTION}"
raise RuntimeError, 'Must run as root' if Process.euid != 0
# Setup defaults
options[:environment] = ENV['APP_ENV'] || 'production'
options[:base] = ENV['APP_ROOT'] || DEFAULT_APP_ROOT
options[:pid] = base || "#{base}/tmp/pids/#{APP_NAME}.pid"
options[:logger] = 'standard'
options[:user] = DEFAULT_USER
on '-e ENV', '--environment', 'envrionment to run under'
# Validate logger option and set it up
on '-l VAL', '--logger', 'logger should be "standard" or "gelf"' do |logger|
options[:logger] = case logger
when "standard"
Logger.new(STDOOUT)
when "gelf"
# TODO: Add GELF logger
else
raise ArgumentError, 'Invalid option provided for logger. Should be "standard" or "gelf"'
end
end
# Validate base option and change working dir
on '-b PATH', '--base', 'base directory of verify application' do |base|
if File.directory?(base)
Dir.chdir base
options[:base] = base
else
raise ArgumentError, "No directory found matching option provided for base"
end
end
# Validate pid file location
on '-p FILE', '--pid', 'location of the application PID file' do |pid|
raise ArgumentError, "Directory for PID does not exists" \
unless File.directory? File.basename(pid)
options[:pid] = pid
end
on '-u USER', '--user', 'user to run as' do |user|
raise ArgumentError, "Runtime user, #{options[:user]}, not found" \
unless Etc.getpwnam(options[:user])
end
arg :action, "Action to perform"
use_log_level_option
def change_user!
uid = Etc.getpwnam(options[:user]).uid
Process::UID.change_privilege uid
end
def write_new_pid p
f = File.open(options[:pid], 'w')
f.puts p
f.close
end
def process_is_running?
return false unless File.exists?(options[:pid])
pid = File.read(options[:pid]).chomp.to_i
begin
Process.getpgid( pid )
rescue Errno::ESRCH
info "Cleaning up stald PID file"
File.rm options[:pid]
false
end
end
def start!
raise "#{APP_NAME} daemon is already running with pid: #{p}" if p = process_is_running?
p = Process.fork STARTUP
write_new_pid p
Dir.chdir '/'
File.umask 0000
exit 0
end
def stop!
if p = process_is_running?
Process.kill p
else
raise RuntimeError, "No daemon is running with pid: #{p}"
end
end
def status!
if p = process_is_running?
puts "#{APP_NAME} daemon is running [pid = #{p}]."
else
puts "#{APP_NAME} daemon is not running."
end
end
go!
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment