#200 and #201
[acts_as_ferret.git] / script / ferret_service
blob6c56443f3c89771099b133430263366cf563ecc7
1 # Ferret Win32 Service Daemon install script \r
2 # created by Herryanto Siatono <herryanto@pluitsolutions.com>\r
3 #\r
4 # see doc/README.win32 for usage instructions\r
5 #\r
6 require 'optparse'\r
7 require 'win32/service'\r
8 include Win32\r
9 \r
10 module Ferret\r
11   # Parse and validate service command and options\r
12   class FerretServiceCommand\r
13     COMMANDS = ['install', 'remove', 'start', 'stop', 'help']\r
14     BANNER = "Usage: ruby script/ferret_service <command> [options]"\r
15     \r
16     attr_reader :options, :command\r
17     \r
18     def initialize\r
19       @options = {}\r
20     end\r
21     \r
22     def valid_command?      \r
23       COMMANDS.include?@command\r
24     end\r
25     \r
26     def valid_options?\r
27       @options[:name] and !@options[:name].empty?\r
28     end\r
29     \r
30     def print_command_list\r
31       puts BANNER \r
32       puts "\nAvailable commands:\n"\r
33       puts COMMANDS.map {|cmd| " - #{cmd}\n"}\r
34       puts "\nUse option -h for each command to help."\r
35       exit\r
36     end\r
37     \r
38     def validate_options\r
39       errors = []\r
40       errors << "Service name is required." unless @options[:name]\r
41       \r
42       if (errors.size > 0)\r
43         errors << "Error found. Use: 'ruby script/ferret_service #{@command} -h' for to get help."\r
44         puts errors.join("\n")\r
45         exit\r
46       end\r
47     end\r
48     \r
49     def run(args)\r
50       @command = args.shift      \r
51       @command = @command.dup.downcase if @command\r
52       \r
53       # validate command and options      \r
54       print_command_list unless valid_command? or @command == 'help'\r
55       \r
56       opts_parser = create_options_parser\r
57       begin\r
58         opts_parser.parse!(args)\r
59       rescue OptionParser::ParseError => e\r
60         puts e\r
61         puts opts_parser\r
62       end\r
63       \r
64       # validate required options\r
65       validate_options\r
66     end\r
67     \r
68     def create_options_parser\r
69       opts_parser = OptionParser.new\r
70       opts_parser.banner = BANNER\r
71       opts_parser.on("-n", "--name=NAME", "Service name") {|name| @options[:name] = name }\r
72       opts_parser.on_tail("-t", "--trace",  "Display stack trace when exception thrown") { @options[:trace] = true }\r
73       opts_parser.on_tail("-h", "--help",   "Show this help message") { puts opts_parser; exit }\r
74       \r
75       if ['install'].include?@command\r
76         opts_parser.on("-d", "--display=NAME", "Service display name") {|name| @options[:display] = name }\r
77         \r
78         opts_parser.on("-l", "--log FILE", "Service log file") {|file| @options[:log] = file }  \r
79         opts_parser.on("-e",     "--environment ENV ",    "Rails environment") { |env|\r
80           @options[:environment] = env\r
81           ENV['RAILS_ENV'] = env\r
82         }    \r
83       end\r
84       opts_parser\r
85     end\r
86   end\r
87   \r
88   # Install, Remove, Start and Stop Ferret DRb server Win32 service\r
89   class FerretService\r
90     FERRET_DAEMON = 'ferret_daemon'\r
91     \r
92     def initialize\r
93     end\r
94     \r
95     def install\r
96       svc = Service.new\r
97       \r
98       begin\r
99         if Service.exists?(@options[:name])\r
100           puts "Service name '#{@options[:name]}' already exists."\r
101           return\r
102         end \r
103         \r
104         svc.create_service do |s|\r
105           s.service_name = @options[:name]\r
106           s.display_name = @options[:display]\r
107           s.binary_path_name = binary_path_name\r
108           s.dependencies = []\r
109         end\r
110         \r
111         svc.close\r
112         puts "'#{@options[:name]}' service installed."\r
113       rescue => e\r
114         handle_error(e)\r
115       end\r
116     end\r
117     \r
118     def remove\r
119       begin\r
120         Service.stop(@options[:name])\r
121       rescue\r
122       end\r
123       \r
124       begin\r
125         Service.delete(@options[:name])    \r
126         puts "'#{@options[:name]}' service removed."\r
127       rescue => e      \r
128         handle_error(e)\r
129       end\r
130     end\r
131     \r
132     def start\r
133       begin\r
134         Service.start(@options[:name])\r
135         puts "'#{@options[:name]}' successfully started."\r
136       rescue => e\r
137         handle_error(e)\r
138       end \r
139     end\r
140     \r
141     def stop\r
142       begin\r
143         Service.stop(@options[:name])\r
144         puts "'#{@options[:name]}' successfully stopped.\n"\r
145       rescue => e\r
146         handle_error(e)\r
147       end \r
148     end\r
149     \r
150     def run(args)\r
151       svc_cmd = FerretServiceCommand.new\r
152       svc_cmd.run(args)\r
153       @options = svc_cmd.options\r
154       self.send(svc_cmd.command.to_sym)\r
155     end\r
156     \r
157     protected  \r
158     def handle_error(e)\r
159       if @options[:trace]\r
160         raise e\r
161       else\r
162         puts e\r
163       end\r
164     end\r
165     \r
166     def binary_path_name\r
167       path = ""\r
168       path << "#{ENV['RUBY_HOME']}/bin/" if ENV['RUBY_HOME']\r
169       path << "ruby.exe "\r
170       path << File.expand_path("script/" + FERRET_DAEMON)\r
171       path << " -e #{@options[:environment]} " if @options[:environment]\r
172       path << " -l #{@options[:log]} " if @options[:log]\r
173       path\r
174     end\r
175   end\r
176 end\r
178 Ferret::FerretService.new.run(ARGV)\r