#!/usr/bin/env ruby require 'optparse' require 'ostruct' require 'eventmachine' require 'socket' require 'dante' module Flapper def receive_data data send_data ">>>you sent: #{data}" close_connection if data =~ /quit/i end end def local_ip # turn off reverse DNS resolution temporarily orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true UDPSocket.open do |s| s.connect '64.233.187.99', 1 s.addr.last end ensure Socket.do_not_reverse_lookup = orig end def main(bind_ip) start_every = 120 stop_after = 60 bind_port = 12345 EM.run { puts "#{Time.now}: starting server" server_init = EM.start_server bind_ip, bind_port, Flapper EM.add_timer(stop_after) do puts "#{Time.now}: stopping server" EM.stop_server(server_init) end EM.add_periodic_timer(start_every) do puts "#{Time.now}: starting server" server = EM.start_server bind_ip, bind_port, Flapper EM.add_timer(stop_after) do puts "#{Time.now}: stopping server" EM.stop_server(server) end end } end options = OpenStruct.new options.daemonize = nil exe = File.basename(__FILE__) OptionParser.new do |opts| opts.banner = "Usage: #{exe} COMMAND [OPTIONS]" opts.separator "" opts.separator "Commands" opts.separator " start #{" " * 25} start #{exe}" opts.separator " stop #{" " * 26} stop #{exe}" opts.separator " restart #{" " * 23} (re)start #{exe}" opts.separator " status #{" " * 24} see if #{exe} is running" opts.separator "" opts.separator "Options" opts.on("-d", "--[no-]daemonize", "Daemonize?") do |d| options.daemonize = d end opts.on("-p", "--pidfile [PATH]", String, "PATH to the pidfile to write to") do |pid| options.pidfile = pid end opts.on("-l", "--logfile [PATH]", String, "PATH to the logfile to write to") do |l| options.log_path = l end opts.on("-b", "--bind-ip [ADDRESS]", String, "ADDRESS (IPv4 or IPv6) for flapper to bind to") do |b| options.bind_ip = b end end.parse!(ARGV) pidfile = options.pidfile || "/var/run/flapjack/#{exe}.pid" logfile = options.log_path || "/var/log/flapjack/#{exe}.log" daemonize = options.daemonize.nil? ? true : options.daemonize bind_ip = options.bind_ip || local_ip runner = Dante::Runner.new(exe, :pid_path => pidfile, :log_path => logfile) case ARGV[0] when "start" if runner.daemon_running? puts "#{exe} is already running." exit 1 else print "#{exe} starting..." runner.execute(:daemonize => daemonize) { main(bind_ip) } puts " done." end when "stop" if runner.daemon_running? print "#{exe} stopping..." runner.execute(:kill => true) puts " done." else puts "#{exe} is not running." exit 1 end when "restart" print "#{exe} restarting..." runner.execute(:daemonize => true, :restart => true) { main(bind_ip) } puts " done." when "status" uptime = (runner.daemon_running?) ? (Time.now - File.stat(pidfile).ctime) : 0 if runner.daemon_running? puts "#{exe} is running: #{uptime}" else puts "#{exe} is not running" exit 3 end else if ARGV.nil? || ARGV.empty? puts "No command provided" else puts "Unknown command provided: '#{ARGV[0]}'" end exit 1 end