mongrel_service 0.1 → 0.4.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt ADDED
@@ -0,0 +1,52 @@
1
+ === 0.4.beta1 / 2010-01-01
2
+
3
+ * Enhancements:
4
+ * Removed win32-service dependency, making mongrel_service more portable
5
+ between Ruby implementations on Windows (One-Click and RubyInstaller)
6
+
7
+ * Now mongrel log files are written to the path specified by --log option.
8
+ Contribution by Daniel Gies (BigFix). Closes #44.
9
+
10
+ * Bugfixes:
11
+ * Wait longer for child process terminate properly (max 20 seconds).
12
+ Imported tests from RubyServices project. Closes #18.
13
+
14
+ * Workaround Windows 2008 process detection issues forcing 'service'
15
+ initialization parameter. Closes #54. [papillon]
16
+
17
+ * Updated ServiceFB to work with FB > 0.18.
18
+
19
+ === 0.3.4 / 2008-01-02
20
+
21
+ * Strict Gem dependencies for mongrel_service. This version is compatible
22
+ only with mongrel 1.0.x, 1.1.x and with win32-service 0.5.x.
23
+
24
+ * Fixed issues realted to Win32::Service and gem_plugin being registered with
25
+ different names due win32-service changes.
26
+
27
+ === 0.3.3 / 2007-10-26
28
+
29
+ * Properly display package/gem version for mongrel_service. Closes #13823.
30
+
31
+ * Updated ServiceFB to r80 to solve issue when compiling with FB > 0.17.
32
+
33
+ === 0.3.2 / 2007-06-01
34
+
35
+ * Solved detection of parent process at ServiceFB level
36
+ (solves the x64 Windows issues).
37
+
38
+ * Upgraded to ServiceFB 'trunk' (but pistoned it, just in case).
39
+
40
+ * Fixed problems with ruby installations outside PATH or inside folders with spaces.
41
+
42
+ * Activate FB pedantic warnings by default (is really useful).
43
+
44
+ === 0.3.1 / 2007-01-19
45
+
46
+ * Single Service (SingleMongrel) object type implemented.
47
+
48
+ * Updated Rakefile to reflect the new building steps.
49
+
50
+ * Removed SendSignal, too hackish for my taste, replaced with complete FB solution.
51
+
52
+ * Added basic Process monitoring and re-spawning.
data/LICENSE.txt ADDED
@@ -0,0 +1,55 @@
1
+ Mongrel Web Server (Mongrel) is copyrighted free software by Zed A. Shaw
2
+ <zedshaw at zedshaw dot com> and contributors. You can redistribute it
3
+ and/or modify it under either the terms of the GPL2 or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise make them
13
+ Freely Available, such as by posting said modifications to Usenet or an
14
+ equivalent medium, or by allowing the author to include your
15
+ modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) rename any non-standard executables so the names do not conflict with
21
+ standard executables, which must also be provided.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or executable
26
+ form, provided that you do at least ONE of the following:
27
+
28
+ a) distribute the executables and library files of the software,
29
+ together with instructions (in the manual page or equivalent) on where
30
+ to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of the
33
+ software.
34
+
35
+ c) give non-standard executables non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under this terms.
43
+
44
+ 5. The scripts and library files supplied as input to or produced as
45
+ output from the software do not automatically fall under the
46
+ copyright of the software, but belong to whomever generated them,
47
+ and may be sold commercially, and may be aggregated with this
48
+ software.
49
+
50
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
51
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
52
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53
+ PURPOSE.
54
+
55
+
data/Manifest.txt ADDED
@@ -0,0 +1,32 @@
1
+ History.txt
2
+ lib/mongrel_service/init.rb
3
+ lib/mongrel_service/service_manager.rb
4
+ LICENSE.txt
5
+ Manifest.txt
6
+ Rakefile
7
+ README.txt
8
+ resources/defaults.yaml
9
+ resources/mongrel_service.exe
10
+ src/mongrel_service/_debug.bi
11
+ src/mongrel_service/boolean.bi
12
+ src/mongrel_service/console_process.bas
13
+ src/mongrel_service/console_process.bi
14
+ src/mongrel_service/mongrel_service.bas
15
+ src/mongrel_service/mongrel_service.bi
16
+ src/ServiceFB/_internals.bi
17
+ src/ServiceFB/_utils_internals.bi
18
+ src/ServiceFB/ServiceFB.bas
19
+ src/ServiceFB/ServiceFB.bi
20
+ src/ServiceFB/ServiceFB_Utils.bas
21
+ src/ServiceFB/ServiceFB_Utils.bi
22
+ tasks/gem.rake
23
+ tasks/native_lib.rake
24
+ tasks/native_service.rake
25
+ tasks/tests.rake
26
+ tests/all_tests.bas
27
+ tests/fixtures/mock_process.bas
28
+ tests/test_console_process.bas
29
+ tests/test_helpers.bas
30
+ tests/test_helpers.bi
31
+ TODO.txt
32
+ tools/freebasic.rb
data/README.txt ADDED
@@ -0,0 +1,20 @@
1
+ = Mongrel Native Win32 Service Plugin
2
+
3
+ * http://github.com/fauna/mongrel_service
4
+
5
+ == DESCRIPTION
6
+
7
+ This plugin offer native win32 services for rails.
8
+ This replace mongrel_rails_service.
9
+
10
+ == USAGE
11
+
12
+ Use the following commands to get more help:
13
+
14
+ service::install --help
15
+ service::remove --help
16
+ service::update --help
17
+
18
+ == AUTHOR
19
+
20
+ Luis Lavena
data/Rakefile CHANGED
@@ -1,42 +1,8 @@
1
- require 'rake'
2
- require 'rake/testtask'
3
- require 'rake/clean'
4
- require 'rake/gempackagetask'
5
- require 'rake/rdoctask'
6
- require 'tools/rakehelp'
7
- require 'fileutils'
8
- include FileUtils
9
-
10
- setup_tests
11
- setup_clean ["pkg", "lib/*.bundle", "*.gem", ".config"]
12
-
13
- setup_rdoc ['README', 'LICENSE', 'COPYING', 'lib/**/*.rb', 'doc/**/*.rdoc']
14
-
15
- desc "Does a full compile, test run"
16
- task :default => [:test, :package]
17
-
18
- version="0.1"
19
- name="mongrel_service"
20
-
21
- setup_gem(name, version) do |spec|
22
- spec.summary = "Mongrel Native Win32 Service Plugin for Rails"
23
- spec.description = "This plugin offer native win32 services for rails, powered by Mongrel."
24
- spec.author="Luis Lavena"
25
-
26
- # added mongrel_service executable
27
- spec.executables = ["mongrel_service"]
28
-
29
- spec.add_dependency('gem_plugin', '>= 0.2.1')
30
- spec.add_dependency('mongrel', '>= 0.3.12.4')
31
- spec.files += Dir.glob("resources/**/*")
32
- end
33
-
34
-
35
- task :install => [:test, :package] do
36
- sh %{gem install pkg/#{name}-#{version}.gem}
37
- end
38
-
39
- task :uninstall => [:clean] do
40
- sh %{gem uninstall #{name}}
41
- end
42
-
1
+ #
2
+ # NOTE: Keep this file clean.
3
+ # Add your customizations inside tasks directory.
4
+ # Thank You.
5
+ #
6
+
7
+ # load rakefile extensions (tasks)
8
+ Dir['tasks/*.rake'].sort.each { |f| load f }
data/TODO.txt ADDED
@@ -0,0 +1,19 @@
1
+ Legend:
2
+ [ ] not done
3
+ [X] done
4
+ [+] in progess
5
+
6
+ ### General
7
+ [ ] Add more documentation about services and requirements
8
+ [ ] Add process monitoring.
9
+
10
+ ### Dependencies
11
+ [+] Remove win32/service extension dependency (instead of relying in the non-official 0.5.0 one).
12
+ [ ] Add service management (from ServiceFB) to install and remove services.
13
+
14
+ ### SingleMongrel
15
+ [+] Sanitize SingleMongrel and document the functions.
16
+
17
+ ### ClusterMongrel
18
+ [ ] Parse mongrel_cluster configuration file (yaml) looking for port information
19
+ [ ] Reimplent SingleMongrel for ClusterMongrel, splitting source files for better organization.
@@ -2,8 +2,8 @@ require 'gem_plugin'
2
2
  require 'mongrel'
3
3
  require 'mongrel/rails'
4
4
  require 'rbconfig'
5
- require 'win32/service'
6
-
5
+ require 'fileutils'
6
+ require 'mongrel_service/service_manager'
7
7
 
8
8
  module Service
9
9
  class Install < GemPlugin::Plugin "/commands"
@@ -26,7 +26,7 @@ module Service
26
26
  ['-B', '--debug', "Enable debugging mode", :@debug, false],
27
27
  ['-C', '--config PATH', "Use a config file", :@config_file, nil],
28
28
  ['-S', '--script PATH', "Load the given file as an extra config script.", :@config_script, nil],
29
- ['-u', '--cpu CPU', "Bind the process to specific cpu, starting from 1.", :@cpu, nil]
29
+ ['', '--prefix PATH', "URL prefix for Rails app", :@prefix, nil]
30
30
  ]
31
31
  end
32
32
 
@@ -42,13 +42,15 @@ module Service
42
42
 
43
43
  # start with the premise of app really exist.
44
44
  app_exist = true
45
- %w{app config db log public}.each do |path|
45
+ %w{app config log}.each do |path|
46
46
  if !File.directory?(File.join(@cwd, path))
47
47
  app_exist = false
48
48
  break
49
49
  end
50
50
  end
51
51
 
52
+ valid?(@prefix[0].chr == "/" && @prefix[-1].chr != "/", "Prefix must begin with / and not end in /") if @prefix
53
+
52
54
  valid? app_exist == true, "The path you specified isn't a valid Rails application."
53
55
 
54
56
  valid_dir? File.dirname(@log_file), "Path to log file not valid: #@log_file"
@@ -57,12 +59,9 @@ module Service
57
59
  valid_exists? @mime_map, "MIME mapping file does not exist: #@mime_map" if @mime_map
58
60
  valid_exists? @config_file, "Config file not there: #@config_file" if @config_file
59
61
 
60
- # Validate the number of cpu to bind to.
61
- valid? @cpu.to_i > 0, "You must specify a numeric value for cpu. (1..8)" if @cpu
62
-
63
62
  # We should validate service existance here, right Zed?
64
63
  begin
65
- valid? !Win32::Service.exists?(@svc_name), "The service already exist, please remove it first."
64
+ valid? !ServiceManager.exist?(@svc_name), "The service already exist, please remove it first."
66
65
  rescue
67
66
  end
68
67
 
@@ -75,57 +74,82 @@ module Service
75
74
  end
76
75
 
77
76
  def run
77
+ # check if mongrel_service.exe is in ruby bindir.
78
+ gem_root = File.join(File.dirname(__FILE__), "..", "..")
79
+ gem_executable = File.join(gem_root, "resources/mongrel_service.exe")
80
+ bindir_executable = File.join(Config::CONFIG['bindir'], '/mongrel_service.exe')
81
+
82
+ unless File.exist?(bindir_executable)
83
+ STDERR.puts "** Copying native mongrel_service executable..."
84
+ FileUtils.cp gem_executable, bindir_executable rescue nil
85
+ end
86
+
87
+ unless FileUtils.compare_file(bindir_executable, gem_executable)
88
+ STDERR.puts "** Updating native mongrel_service executable..."
89
+ FileUtils.rm_f bindir_executable rescue nil
90
+ FileUtils.cp gem_executable, bindir_executable rescue nil
91
+ end
92
+
93
+ # build the command line
94
+ argv = []
95
+
96
+ # start using the native executable
97
+ argv << '"' + bindir_executable + '"'
98
+
99
+ # force indication of service mode (workaround Windows 2008 psapi issue)
100
+ argv << "service"
101
+
102
+ # use the 'single' service for now
103
+ argv << "single"
104
+
78
105
  # command line setting override config file settings
79
106
  @options = { :host => @address, :port => @port, :cwd => @cwd,
80
107
  :log_file => @log_file, :pid_file => @pid_file, :environment => @environment,
81
108
  :docroot => @docroot, :mime_map => @mime_map,
82
109
  :debug => @debug, :includes => ["mongrel"], :config_script => @config_script,
83
- :num_procs => @num_procs, :timeout => @timeout, :cpu => @cpu
110
+ :num_procs => @num_procs, :timeout => @timeout, :cpu => @cpu, :prefix => @prefix
84
111
  }
85
-
112
+
113
+ # if we are using a config file, pass -c and -C to the service instead of each start parameter.
86
114
  if @config_file
87
- STDERR.puts "** Loading settings from #{@config_file} (command line options override)."
115
+ STDERR.puts "** Using #{@config_file} instead of command line parameters."
88
116
  conf = YAML.load_file(@config_file)
89
- @options = conf.merge(@options)
117
+
118
+ # add the root folder (-c)
119
+ argv << "-c \"#{conf[:cwd]}\""
120
+
121
+ # use the config file
122
+ argv << "-C \"#{@config_file}\""
123
+
124
+ else
125
+ # use the command line instead
126
+ # now the options
127
+ argv << "-e #{@options[:environment]}" if @options[:environment]
128
+ argv << "-p #{@options[:port]}"
129
+ argv << "-a #{@options[:host]}" if @options[:host]
130
+ argv << "-l \"#{@options[:log_file]}\"" if @options[:log_file]
131
+ argv << "-P \"#{@options[:pid_file]}\""
132
+ argv << "-c \"#{@options[:cwd]}\"" if @options[:cwd]
133
+ argv << "-t #{@options[:timeout]}" if @options[:timeout]
134
+ argv << "-m \"#{@options[:mime_map]}\"" if @options[:mime_map]
135
+ argv << "-r \"#{@options[:docroot]}\"" if @options[:docroot]
136
+ argv << "-n #{@options[:num_procs]}" if @options[:num_procs]
137
+ argv << "-B" if @options[:debug]
138
+ argv << "-S \"#{@options[:config_script]}\"" if @options[:config_script]
139
+ argv << "-u #{@options[:cpu.to_i]}" if @options[:cpu]
140
+ argv << "--prefix \"#{@options[:prefix]}\"" if @options[:prefix]
90
141
  end
91
142
 
92
- argv = []
93
-
94
- # ruby.exe instead of rubyw.exe due a exception raised when stoping the service!
95
- argv << '"' + Config::CONFIG['bindir'] + '/ruby.exe' + '"'
96
-
97
- # add service_script, we now use the rubygem powered one
98
- argv << '"' + Config::CONFIG['bindir'] + '/mongrel_service' + '"'
99
-
100
- # now the options
101
- argv << "-e #{@options[:environment]}" if @options[:environment]
102
- argv << "-p #{@options[:port]}"
103
- argv << "-a #{@options[:address]}" if @options[:address]
104
- argv << "-l \"#{@options[:log_file]}\"" if @options[:log_file]
105
- argv << "-P \"#{@options[:pid_file]}\""
106
- argv << "-c \"#{@options[:cwd]}\"" if @options[:cwd]
107
- argv << "-t #{@options[:timeout]}" if @options[:timeout]
108
- argv << "-m \"#{@options[:mime_map]}\"" if @options[:mime_map]
109
- argv << "-r \"#{@options[:docroot]}\"" if @options[:docroot]
110
- argv << "-n #{@options[:num_procs]}" if @options[:num_procs]
111
- argv << "-B" if @options[:debug]
112
- argv << "-S \"#{@options[:config_script]}\"" if @options[:config_script]
113
- argv << "-u #{@options[:cpu.to_i]}" if @options[:cpu]
114
-
115
- svc = Win32::Service.new
116
143
  begin
117
- svc.create_service{ |s|
118
- s.service_name = @svc_name
119
- s.display_name = @svc_display
120
- s.binary_path_name = argv.join ' '
121
- s.dependencies = []
122
- }
123
- puts "Mongrel service '#{@svc_display}' installed as '#{@svc_name}'."
124
- rescue Win32::ServiceError => err
144
+ ServiceManager.create(
145
+ @svc_name,
146
+ @svc_display,
147
+ argv.join(' ')
148
+ )
149
+ rescue ServiceManager::CreateError => e
125
150
  puts "There was a problem installing the service:"
126
- puts err
151
+ puts e
127
152
  end
128
- svc.close
129
153
  end
130
154
  end
131
155
 
@@ -138,13 +162,15 @@ module Service
138
162
 
139
163
  def validate
140
164
  valid? @svc_name != nil, "A service name is mandatory."
141
-
165
+
142
166
  # Validate that the service exists
143
- begin
144
- valid? Win32::Service.exists?(@svc_name), "There is no service with that name, cannot proceed."
145
- rescue
167
+ valid? ServiceManager.exist?(@svc_name), "There is no service with that name, cannot proceed."
168
+ if @valid then
169
+ ServiceManager.open(@svc_name) do |svc|
170
+ valid? svc.binary_path_name.include?("mongrel_service"), "The service specified isn't a Mongrel service."
171
+ end
146
172
  end
147
-
173
+
148
174
  return @valid
149
175
  end
150
176
  end
@@ -152,69 +178,24 @@ module Service
152
178
  class Remove < GemPlugin::Plugin "/commands"
153
179
  include Mongrel::Command::Base
154
180
  include ServiceValidation
155
-
181
+
156
182
  def run
157
- display_name = Win32::Service.getdisplayname(@svc_name)
158
-
183
+ display_name = ServiceManager.getdisplayname(@svc_name)
184
+
159
185
  begin
160
- Win32::Service.stop(@svc_name)
161
- rescue
186
+ ServiceManager.stop(@svc_name)
187
+ rescue ServiceManager::ServiceError => e
162
188
  end
163
- begin
164
- Win32::Service.delete(@svc_name)
165
- rescue
166
- end
167
- puts "#{display_name} service removed."
168
- end
169
- end
170
189
 
171
- class Start < GemPlugin::Plugin "/commands"
172
- include Mongrel::Command::Base
173
- include ServiceValidation
174
-
175
- def run
176
- display_name = Win32::Service.getdisplayname(@svc_name)
177
-
178
190
  begin
179
- Win32::Service.start(@svc_name)
180
- started = false
181
- while started == false
182
- s = Win32::Service.status(@svc_name)
183
- started = true if s.current_state == "running"
184
- break if started == true
185
- puts "One moment, " + s.current_state
186
- sleep 1
187
- end
188
- puts "#{display_name} service started"
189
- rescue Win32::ServiceError => err
190
- puts "There was a problem starting the service:"
191
- puts err
191
+ ServiceManager.delete(@svc_name)
192
+ rescue ServiceManager::ServiceError => e
193
+ puts e
192
194
  end
193
- end
194
- end
195
195
 
196
- class Stop < GemPlugin::Plugin "/commands"
197
- include Mongrel::Command::Base
198
- include ServiceValidation
199
-
200
- def run
201
- display_name = Win32::Service.getdisplayname(@svc_name)
202
-
203
- begin
204
- Win32::Service.stop(@svc_name)
205
- stopped = false
206
- while stopped == false
207
- s = Win32::Service.status(@svc_name)
208
- stopped = true if s.current_state == "stopped"
209
- break if stopped == true
210
- puts "One moment, " + s.current_state
211
- sleep 1
212
- end
213
- puts "#{display_name} service stopped"
214
- rescue Win32::ServiceError => err
215
- puts "There was a problem stopping the service:"
216
- puts err
196
+ unless ServiceManager.exist?(@svc_name) then
197
+ puts "#{display_name} service removed."
217
198
  end
218
199
  end
219
200
  end
220
- end
201
+ end