Skip to content

Instantly share code, notes, and snippets.

@oggy
Created April 19, 2011 20:16
Show Gist options
  • Save oggy/929513 to your computer and use it in GitHub Desktop.
Save oggy/929513 to your computer and use it in GitHub Desktop.
Script to start redis using command line options, rather than a config file
#!/usr/bin/env ruby
#
# Run redis-server with settings taken from the command line.
#
# Source: https://gist.github.com/929513
#
require 'optparse'
require 'fileutils'
require 'tempfile'
require 'erb'
class App
RC_DIR = File.expand_path('~/.redis')
def initialize(args)
@port = 6379
@log_level = 'debug'
@db_path ||= "#{RC_DIR}/PORT.rdb"
@log_path ||= "#{RC_DIR}/PORT.log"
@pid_path ||= "#{RC_DIR}/PORT.pid"
parser = OptionParser.new do |parser|
parser.banner = "Usage: #$0 [options] start|stop|run"
parser.on '-p', '--port=PORT', "Port to listen on (default: #{port})" do |port|
@port = port
end
parser.on '-l', '--log-path=PATH', "Path of log file (default: #{@log_path})" do |log_path|
@log_path = log_path
end
parser.on '-P', '--pid-path=PATH', "Path of pid file (default: #{@pid_path})" do |pid_path|
@pid_path = pid_path
end
parser.on '-d', '--db-path=PATH', "Path of the database file (default: #{@db_path})" do |db_path|
@db_path = db_path == '-' ? '-' : File.expand_path(db_path)
end
parser.on '-L', '--log-level=LEVEL', "Log level [debug|verbose|notice|warning] (default: #{log_level})" do |log_level|
@log_level = log_level
end
end
@configs, args = args.partition { |arg| arg =~ /=/ }
parser.parse!(args)
@db_path.sub!(/PORT/, @port.to_s)
@log_path.sub!(/PORT/, @port.to_s)
@pid_path.sub!(/PORT/, @port.to_s)
args.size == 1 or
abort parser.banner
@command = args.first
end
attr_reader :command, :port, :log_path, :pid_path, :db_path, :log_level, :configs
def run
FileUtils.mkdir_p RC_DIR
clean_stale_pid_file
case command
when 'start', 'run'
!running? or
abort "Already running."
with_redis_config do |path|
run_redis(path)
end
when 'stop'
running? or
abort "Not running."
Process.kill 'INT', File.read(pid_path).to_i
File.delete(pid_path)
end
end
def clean_stale_pid_file
if !File.exist?(pid_path)
@running = false
else
pid = File.read(pid_path).strip
`ps -p #{pid}`
@running = $?.success?
if !@running
STDERR.puts "Deleting stale PID file: #{pid_path}"
File.delete(pid_path)
end
end
end
def running?
@running
end
def with_redis_config
file = nil
begin
Tempfile.open("redis-conf:#{port}") do |f|
file = f
f.print interpret_config
end
yield file.path if file
ensure
FileUtils.rm_f file.path
end
end
def interpret_config
ERB.new(DATA.read).result(binding)
end
def run_redis(config_path)
# Spawn a child process, as the tempfile will be deleted when we exit.
system 'redis-server', config_path or
abort "Redis failed with status #{$?.exitstatus}"
end
end
App.new(ARGV).run
__END__
port <%= port %>
pidfile <%= pid_path %>
<% if log_path %>logfile <%= log_path %><% end %>
loglevel <%= log_level %>
<% unless db_path == '-' %>
dir <%= File.dirname(db_path) %>
dbfilename <%= File.basename(db_path) %>
save 60 1
<% end %>
<%= configs.map { |c| c.sub(/\s*=\s*/, ' ') }.join("\n") %>
daemonize <%= command == 'run' ? 'no' : 'yes' %>
timeout 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment