mongrel_service 0.3.4-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,70 @@
1
+ '#--
2
+ '# Copyright (c) 2006-2007 Luis Lavena, Multimedia systems
3
+ '#
4
+ '# This source code is released under the MIT License.
5
+ '# See MIT-LICENSE file for details
6
+ '#++
7
+
8
+ #if __FB_VERSION__ < "0.17"
9
+ #error ServiceFB is designed to compile with FreeBASIC version "0.17"
10
+ #else
11
+
12
+ #ifndef __FB_WIN32__
13
+ #error Platform unsupported. Compiling ServiceFB requires Windows platform.
14
+ #else
15
+
16
+ #ifndef __ServiceFB_Utils_bi__
17
+ #define __ServiceFB_Utils_bi__
18
+
19
+ #include once "win/psapi.bi"
20
+ #include once "win/tlhelp32.bi"
21
+
22
+ namespace fb
23
+ namespace svc
24
+ namespace utils '# fb.svc.utils
25
+ '# use this to determine (using select case maybe?) the
26
+ '# mode which the service was invoked.
27
+ enum ServiceRunMode
28
+ RunAsUnknown = 0
29
+ RunAsService
30
+ RunAsManager
31
+ RunAsConsole
32
+ end enum
33
+
34
+
35
+ '# ServiceController type (object)
36
+ '# this is a helper object in case you want to implement
37
+ '# console mode (command line testing/debugging) and management (install/remove/control)
38
+ '# to your services, all from the same executable
39
+ type ServiceController
40
+ '# ctor/dtor()
41
+ declare constructor()
42
+ declare constructor(byref as string)
43
+ declare constructor(byref as string, byref as string)
44
+ declare constructor(byref as string, byref as string, byref as string)
45
+ declare destructor()
46
+
47
+ '# methods (public)
48
+ declare sub Banner()
49
+ declare function RunMode() as ServiceRunMode
50
+ declare sub Manage()
51
+ declare sub Manage(byref as ServiceProcess)
52
+ declare sub Console()
53
+ declare sub Console(byref as ServiceProcess)
54
+
55
+ '# properties (public)
56
+ '# use these properties for shwoing information on console/manager mode
57
+ '# as banner.
58
+ '# Product, version
59
+ '# copyright
60
+ product as string
61
+ version as string
62
+ copyright as string
63
+ end type
64
+ end namespace '# fb.svc.utils
65
+ end namespace '# fb.svc
66
+ end namespace '# fb
67
+
68
+ #endif '# __ServiceFB_bi__
69
+ #endif '# __FB_WIN32__
70
+ #endif '# __FB_VERSION__
@@ -0,0 +1,50 @@
1
+ '#--
2
+ '# Copyright (c) 2006-2007 Luis Lavena, Multimedia systems
3
+ '#
4
+ '# This source code is released under the MIT License.
5
+ '# See MIT-LICENSE file for details
6
+ '#++
7
+
8
+ '##################################################################
9
+ '#
10
+ '# DO NOT INCLUDE THIS FILE DIRECTLY!
11
+ '# it is used internaly by ServiceFB
12
+ '# use ServiceFB.bi instead
13
+ '#
14
+ '##################################################################
15
+
16
+ namespace fb
17
+ namespace svc
18
+ '# now due references locking, I needed a constructor and destructor for
19
+ '# the namespace to garantee everything is cleaned up on termination of the process
20
+ declare sub _initialize() constructor
21
+ declare sub _terminate() destructor
22
+
23
+ '# global service procedures (private)
24
+ declare sub _main(byval as DWORD, byval as LPSTR ptr)
25
+ declare function _control_ex(byval as DWORD, byval as DWORD, byval as LPVOID, byval as LPVOID) as DWORD
26
+ declare sub _run()
27
+
28
+ '# global references helper
29
+ declare function _add_to_references(byref as ServiceProcess) as integer
30
+ declare function _find_in_references(byref as string) as ServiceProcess ptr
31
+
32
+ '# command line builder (helper)
33
+ '# this is used to gather information about:
34
+ '# mode (if present)
35
+ '# valid service name (after lookup in the table)
36
+ '# command line to be passed to service
37
+ declare sub _build_commandline(byref as string, byref as string, byref as string)
38
+
39
+ '# I started this as simple, unique service served from one process
40
+ '# but the idea of share the same process space (and reduce resources use) was good.
41
+ '# to do that, I needed a references table (similar to service_table, but we will
42
+ '# hold the ServiceProcess registered by ServiceHost (the multi services host).
43
+ '# also, I needed a locking mechanism to avoid problems of two calls changing the table
44
+ '# at the same time.
45
+ extern _svc_references as ServiceProcess ptr ptr
46
+ extern _svc_references_count as integer
47
+ extern _svc_references_lock as any ptr
48
+ end namespace '# fb.svc
49
+ end namespace '# fb
50
+
@@ -0,0 +1,49 @@
1
+ '#--
2
+ '# Copyright (c) 2006-2007 Luis Lavena, Multimedia systems
3
+ '#
4
+ '# This source code is released under the MIT License.
5
+ '# See MIT-LICENSE file for details
6
+ '#++
7
+
8
+ '##################################################################
9
+ '#
10
+ '# DO NOT INCLUDE THIS FILE DIRECTLY!
11
+ '# it is used internaly by ServiceFB
12
+ '# use ServiceFB_Utils.bi instead
13
+ '#
14
+ '##################################################################
15
+
16
+ namespace fb
17
+ namespace svc
18
+ namespace utils '# fb.svc.utils
19
+ '# console_handler is used to get feedback form keyboard and allow
20
+ '# shutdown of service using Ctrl+C / Ctrl+Break from keyboard
21
+ declare function _console_handler(byval as DWORD) as BOOL
22
+
23
+ '# helper private subs used to list the services and their descriptions
24
+ '# in _svc_references
25
+ declare sub _list_references()
26
+
27
+ '# internals functions used to get Parent PID and Process Name
28
+ '# using this we automatically determine if the service was started by SCM
29
+ '# or by the user, from commandline or from explorer
30
+ declare function _parent_pid(byval as uinteger) as uinteger
31
+ declare function _process_name(byval as uinteger) as string
32
+ declare function _process_name_dyn_psapi(byval as uinteger) as string
33
+ declare function _show_error() as string
34
+
35
+ '# InStrRev (authored by ikkejw @ freebasic forums)
36
+ '# http://www.freebasic.net/forum/viewtopic.php?p=49315#49315
37
+ declare function InStrRev(byval as uinteger = 0, byref as string, byref as string) as uinteger
38
+
39
+ '# use a signal (condition) in the console mode to know
40
+ '# when the service should be stopped.
41
+ '# the Console() main loop will wait for it, and the console_handler
42
+ '# will raise in case Ctrl+C / Ctrl+Break or other events are
43
+ '# received.
44
+ extern _svc_stop_signal as any ptr
45
+ extern _svc_in_console as ServiceProcess ptr
46
+ extern _svc_in_console_stop_flag as BOOL
47
+ end namespace '# fb.svc.utils
48
+ end namespace '# fb.svc
49
+ end namespace '# fb
@@ -0,0 +1,211 @@
1
+ require 'gem_plugin'
2
+ require 'mongrel'
3
+ require 'mongrel/rails'
4
+ require 'rbconfig'
5
+ require 'fileutils'
6
+
7
+ module Service
8
+ class Install < GemPlugin::Plugin "/commands"
9
+ include Mongrel::Command::Base
10
+
11
+ def configure
12
+ options [
13
+ ['-N', '--name SVC_NAME', "Required name for the service to be registered/installed.", :@svc_name, nil],
14
+ ['-D', '--display SVC_DISPLAY', "Adjust the display name of the service.", :@svc_display, nil],
15
+ ["-e", "--environment ENV", "Rails environment to run as", :@environment, ENV['RAILS_ENV'] || "development"],
16
+ ['-p', '--port PORT', "Which port to bind to", :@port, 3000],
17
+ ['-a', '--address ADDR', "Address to bind to", :@address, "0.0.0.0"],
18
+ ['-l', '--log FILE', "Where to write log messages", :@log_file, "log/mongrel.log"],
19
+ ['-P', '--pid FILE', "Where to write the PID", :@pid_file, "log/mongrel.pid"],
20
+ ['-n', '--num-procs INT', "Number of processors active before clients denied", :@num_procs, 1024],
21
+ ['-t', '--timeout TIME', "Timeout all requests after 100th seconds time", :@timeout, 0],
22
+ ['-m', '--mime PATH', "A YAML file that lists additional MIME types", :@mime_map, nil],
23
+ ['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, Dir.pwd],
24
+ ['-r', '--root PATH', "Set the document root (default 'public')", :@docroot, "public"],
25
+ ['-B', '--debug', "Enable debugging mode", :@debug, false],
26
+ ['-C', '--config PATH', "Use a config file", :@config_file, nil],
27
+ ['-S', '--script PATH', "Load the given file as an extra config script.", :@config_script, nil],
28
+ ['', '--prefix PATH', "URL prefix for Rails app", :@prefix, nil]
29
+ ]
30
+ end
31
+
32
+ # When we validate the options, we need to make sure the --root is actually RAILS_ROOT
33
+ # of the rails application we wanted to serve, because later "as service" no error
34
+ # show to trace this.
35
+ def validate
36
+ # TODO: investigate why Win32::Service interfere with gem_plugin
37
+ gem 'win32-service', '>= 0.5.2', '< 0.6.0'
38
+ require 'win32/service'
39
+
40
+ @cwd = File.expand_path(@cwd)
41
+ valid_dir? @cwd, "Invalid path to change to: #@cwd"
42
+
43
+ # change there to start, then we'll have to come back after daemonize
44
+ Dir.chdir(@cwd)
45
+
46
+ # start with the premise of app really exist.
47
+ app_exist = true
48
+ %w{app config log}.each do |path|
49
+ if !File.directory?(File.join(@cwd, path))
50
+ app_exist = false
51
+ break
52
+ end
53
+ end
54
+
55
+ valid?(@prefix[0].chr == "/" && @prefix[-1].chr != "/", "Prefix must begin with / and not end in /") if @prefix
56
+
57
+ valid? app_exist == true, "The path you specified isn't a valid Rails application."
58
+
59
+ valid_dir? File.dirname(@log_file), "Path to log file not valid: #@log_file"
60
+ valid_dir? File.dirname(@pid_file), "Path to pid file not valid: #@pid_file"
61
+ valid_dir? @docroot, "Path to docroot not valid: #@docroot"
62
+ valid_exists? @mime_map, "MIME mapping file does not exist: #@mime_map" if @mime_map
63
+ valid_exists? @config_file, "Config file not there: #@config_file" if @config_file
64
+
65
+ # We should validate service existance here, right Zed?
66
+ begin
67
+ valid? !Win32::Service.exists?(@svc_name), "The service already exist, please remove it first."
68
+ rescue
69
+ end
70
+
71
+ valid? @svc_name != nil, "A service name is mandatory."
72
+
73
+ # default service display to service name
74
+ @svc_display = @svc_name if !@svc_display
75
+
76
+ return @valid
77
+ end
78
+
79
+ def run
80
+ gem 'win32-service', '>= 0.5.2', '< 0.6.0'
81
+ require 'win32/service'
82
+
83
+ # check if mongrel_service.exe is in ruby bindir.
84
+ gem_root = File.join(File.dirname(__FILE__), "..", "..")
85
+ gem_executable = File.join(gem_root, "bin/mongrel_service.exe")
86
+ bindir_executable = File.join(Config::CONFIG['bindir'], '/mongrel_service.exe')
87
+
88
+ unless File.exist?(bindir_executable)
89
+ STDERR.puts "** Copying native mongrel_service executable..."
90
+ FileUtils.cp gem_executable, bindir_executable rescue nil
91
+ end
92
+
93
+ unless FileUtils.compare_file(bindir_executable, gem_executable)
94
+ STDERR.puts "** Updating native mongrel_service executable..."
95
+ FileUtils.rm_f bindir_executable rescue nil
96
+ FileUtils.cp gem_executable, bindir_executable rescue nil
97
+ end
98
+
99
+ # build the command line
100
+ argv = []
101
+
102
+ # start using the native executable
103
+ argv << '"' + bindir_executable + '"'
104
+
105
+ # use the 'single' service for now
106
+ argv << "single"
107
+
108
+ # command line setting override config file settings
109
+ @options = { :host => @address, :port => @port, :cwd => @cwd,
110
+ :log_file => @log_file, :pid_file => @pid_file, :environment => @environment,
111
+ :docroot => @docroot, :mime_map => @mime_map,
112
+ :debug => @debug, :includes => ["mongrel"], :config_script => @config_script,
113
+ :num_procs => @num_procs, :timeout => @timeout, :cpu => @cpu, :prefix => @prefix
114
+ }
115
+
116
+ # if we are using a config file, pass -c and -C to the service instead of each start parameter.
117
+ if @config_file
118
+ STDERR.puts "** Using #{@config_file} instead of command line parameters."
119
+ conf = YAML.load_file(@config_file)
120
+
121
+ # add the root folder (-c)
122
+ argv << "-c \"#{conf[:cwd]}\""
123
+
124
+ # use the config file
125
+ argv << "-C \"#{@config_file}\""
126
+
127
+ else
128
+ # use the command line instead
129
+ # now the options
130
+ argv << "-e #{@options[:environment]}" if @options[:environment]
131
+ argv << "-p #{@options[:port]}"
132
+ argv << "-a #{@options[:host]}" if @options[:host]
133
+ argv << "-l \"#{@options[:log_file]}\"" if @options[:log_file]
134
+ argv << "-P \"#{@options[:pid_file]}\""
135
+ argv << "-c \"#{@options[:cwd]}\"" if @options[:cwd]
136
+ argv << "-t #{@options[:timeout]}" if @options[:timeout]
137
+ argv << "-m \"#{@options[:mime_map]}\"" if @options[:mime_map]
138
+ argv << "-r \"#{@options[:docroot]}\"" if @options[:docroot]
139
+ argv << "-n #{@options[:num_procs]}" if @options[:num_procs]
140
+ argv << "-B" if @options[:debug]
141
+ argv << "-S \"#{@options[:config_script]}\"" if @options[:config_script]
142
+ argv << "-u #{@options[:cpu.to_i]}" if @options[:cpu]
143
+ argv << "--prefix \"#{@options[:prefix]}\"" if @options[:prefix]
144
+ end
145
+
146
+ svc = Win32::Service.new
147
+ begin
148
+ svc.create_service{ |s|
149
+ s.service_name = @svc_name
150
+ s.display_name = @svc_display
151
+ s.binary_path_name = argv.join ' '
152
+ s.dependencies = []
153
+ s.service_type = Win32::Service::WIN32_OWN_PROCESS
154
+ }
155
+ puts "Mongrel service '#{@svc_display}' installed as '#{@svc_name}'."
156
+ rescue Win32::ServiceError => err
157
+ puts "There was a problem installing the service:"
158
+ puts err
159
+ end
160
+ svc.close
161
+ end
162
+ end
163
+
164
+ module ServiceValidation
165
+ def configure
166
+ options [
167
+ ['-N', '--name SVC_NAME', "Required name for the service to be registered/installed.", :@svc_name, nil],
168
+ ]
169
+ end
170
+
171
+ def validate
172
+ valid? @svc_name != nil, "A service name is mandatory."
173
+
174
+ gem 'win32-service', '>= 0.5.2', '< 0.6.0'
175
+ require 'win32/service'
176
+
177
+ # Validate that the service exists
178
+ begin
179
+ valid? Win32::Service.exists?(@svc_name), "There is no service with that name, cannot proceed."
180
+ Win32::Service.open(@svc_name) do |svc|
181
+ valid? svc.binary_path_name.include?("mongrel_service"), "The service specified isn't a Mongrel service."
182
+ end
183
+ rescue
184
+ end
185
+
186
+ return @valid
187
+ end
188
+ end
189
+
190
+ class Remove < GemPlugin::Plugin "/commands"
191
+ include Mongrel::Command::Base
192
+ include ServiceValidation
193
+
194
+ def run
195
+ gem 'win32-service', '>= 0.5.2', '< 0.6.0'
196
+ require 'win32/service'
197
+
198
+ display_name = Win32::Service.getdisplayname(@svc_name)
199
+
200
+ begin
201
+ Win32::Service.stop(@svc_name)
202
+ rescue
203
+ end
204
+ begin
205
+ Win32::Service.delete(@svc_name)
206
+ rescue
207
+ end
208
+ puts "#{display_name} service removed."
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,117 @@
1
+
2
+ # Gem::Specification for Mongrel_service-0.3.4
3
+ # Originally generated by Echoe
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = %q{mongrel_service}
7
+ s.version = "0.3.4"
8
+ s.date = %q{2008-01-02}
9
+ s.summary = %q{Mongrel Native Win32 Service Plugin for Rails}
10
+ s.email = %q{}
11
+ s.homepage = %q{http://rubyforge.org/projects/mongrel}
12
+ s.rubyforge_project = %q{mongrel}
13
+ s.description = %q{This plugin offer native win32 services for rails, powered by Mongrel.}
14
+ s.has_rdoc = true
15
+ s.platform = %q{x86-mingw32}
16
+ s.authors = ["Luis Lavena"]
17
+ s.files = ["bin/mongrel_service.exe", "tools/freebasic.rb", "TODO", "resources/defaults.yaml", "README", "native/mongrel_service.bi", "native/mongrel_service.bas", "native/console_process.bi", "native/console_process.bas", "native/_debug.bi", "LICENSE", "lib/ServiceFB/ServiceFB_Utils.bi", "lib/ServiceFB/ServiceFB_Utils.bas", "lib/ServiceFB/ServiceFB.bi", "lib/ServiceFB/ServiceFB.bas", "lib/ServiceFB/_utils_internals.bi", "lib/ServiceFB/_internals.bi", "lib/mongrel_service/init.rb", "COPYING", "CHANGELOG", "Manifest", "mongrel_service.gemspec"]
18
+ s.add_dependency(%q<gem_plugin>, [">= 0.2.3", "< 0.3.0"])
19
+ s.add_dependency(%q<mongrel>, [">= 1.0.2", "< 1.2.0"])
20
+ s.add_dependency(%q<win32-service>, [">= 0.5.2", "< 0.6.0"])
21
+ end
22
+
23
+
24
+ # # Original Rakefile source (requires the Echoe gem):
25
+ #
26
+ # require 'echoe'
27
+ # require 'tools/freebasic'
28
+ #
29
+ # # Task :package needs compile before doing the gem stuff.
30
+ # # (weird behavior of Rake?)
31
+ # task :package => [:compile]
32
+ #
33
+ # echoe_spec = Echoe.new("mongrel_service") do |p|
34
+ # p.summary = "Mongrel Native Win32 Service Plugin for Rails"
35
+ # p.summary += " (debug build)" unless ENV['RELEASE']
36
+ # p.description = "This plugin offer native win32 services for rails, powered by Mongrel."
37
+ # p.author = "Luis Lavena"
38
+ # p.platform = Gem::Platform::CURRENT
39
+ # p.dependencies = [['gem_plugin', '>=0.2.3', '<0.3.0'],
40
+ # ['mongrel', '>=1.0.2', '<1.2.0'],
41
+ # ['win32-service', '>=0.5.2', '<0.6.0']]
42
+ #
43
+ # p.executable_pattern = ""
44
+ #
45
+ # p.need_tar_gz = false
46
+ # p.need_zip = true
47
+ # ]
48
+ # p.require_signed = true
49
+ # end
50
+ #
51
+ # desc "Compile native code"
52
+ # task :compile => [:native_lib, :native_service]
53
+ #
54
+ # # global options shared by all the project in this Rakefile
55
+ # OPTIONS = {
56
+ # :debug => false,
57
+ # :profile => false,
58
+ # :errorchecking => :ex,
59
+ # :mt => true,
60
+ # :pedantic => true }
61
+ #
62
+ # OPTIONS[:debug] = true if ENV['DEBUG']
63
+ # OPTIONS[:profile] = true if ENV['PROFILE']
64
+ # OPTIONS[:errorchecking] = :exx if ENV['EXX']
65
+ # OPTIONS[:pedantic] = false if ENV['NOPEDANTIC']
66
+ #
67
+ # # ServiceFB namespace (lib)
68
+ # namespace :lib do
69
+ # project_task 'servicefb' do
70
+ # lib 'ServiceFB'
71
+ # build_to 'lib'
72
+ #
73
+ # define 'SERVICEFB_DEBUG_LOG' unless ENV['RELEASE']
74
+ # source 'lib/ServiceFB/ServiceFB.bas'
75
+ #
76
+ # option OPTIONS
77
+ # end
78
+ #
79
+ # project_task 'servicefb_utils' do
80
+ # lib 'ServiceFB_Utils'
81
+ # build_to 'lib'
82
+ #
83
+ # define 'SERVICEFB_DEBUG_LOG' unless ENV['RELEASE']
84
+ # source 'lib/ServiceFB/ServiceFB_Utils.bas'
85
+ #
86
+ # option OPTIONS
87
+ # end
88
+ # end
89
+ #
90
+ # # add lib namespace to global tasks
91
+ # #include_projects_of :lib
92
+ # task :native_lib => "lib:build"
93
+ # task :clean => "lib:clobber"
94
+ #
95
+ # # mongrel_service (native)
96
+ # namespace :native do
97
+ # project_task 'mongrel_service' do
98
+ # executable 'mongrel_service'
99
+ # build_to 'bin'
100
+ #
101
+ # define 'DEBUG_LOG' unless ENV['RELEASE']
102
+ # define "GEM_VERSION=#{echoe_spec.version}"
103
+ #
104
+ # main 'native/mongrel_service.bas'
105
+ # source 'native/console_process.bas'
106
+ #
107
+ # lib_path 'lib'
108
+ # library 'ServiceFB', 'ServiceFB_Utils'
109
+ # library 'user32', 'advapi32', 'psapi'
110
+ #
111
+ # option OPTIONS
112
+ # end
113
+ # end
114
+ #
115
+ # #include_projects_of :native
116
+ # task :native_service => "native:build"
117
+ # task :clean => "native:clobber"