zuk-picnic 0.7.999.20090212
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +1 -0
- data/History.txt +68 -0
- data/LICENSE.txt +165 -0
- data/Manifest.txt +29 -0
- data/README.txt +31 -0
- data/Rakefile +62 -0
- data/lib/picnic/authentication.rb +218 -0
- data/lib/picnic/cli.rb +165 -0
- data/lib/picnic/conf.rb +135 -0
- data/lib/picnic/controllers.rb +4 -0
- data/lib/picnic/logger.rb +41 -0
- data/lib/picnic/server.rb +98 -0
- data/lib/picnic/service_control.rb +274 -0
- data/lib/picnic/version.rb +9 -0
- data/lib/picnic.rb +48 -0
- data/setup.rb +1585 -0
- data/test/picnic_test.rb +11 -0
- data/test/test_helper.rb +2 -0
- data/vendor/camping-2.0.20090212/CHANGELOG +118 -0
- data/vendor/camping-2.0.20090212/COPYING +18 -0
- data/vendor/camping-2.0.20090212/README +119 -0
- data/vendor/camping-2.0.20090212/Rakefile +174 -0
- data/vendor/camping-2.0.20090212/bin/camping +99 -0
- data/vendor/camping-2.0.20090212/doc/camping.1.gz +0 -0
- data/vendor/camping-2.0.20090212/examples/README +5 -0
- data/vendor/camping-2.0.20090212/examples/blog.rb +375 -0
- data/vendor/camping-2.0.20090212/examples/campsh.rb +629 -0
- data/vendor/camping-2.0.20090212/examples/tepee.rb +242 -0
- data/vendor/camping-2.0.20090212/extras/Camping.gif +0 -0
- data/vendor/camping-2.0.20090212/extras/flipbook_rdoc.rb +491 -0
- data/vendor/camping-2.0.20090212/extras/permalink.gif +0 -0
- data/vendor/camping-2.0.20090212/lib/camping/ar/session.rb +132 -0
- data/vendor/camping-2.0.20090212/lib/camping/ar.rb +78 -0
- data/vendor/camping-2.0.20090212/lib/camping/mab.rb +26 -0
- data/vendor/camping-2.0.20090212/lib/camping/reloader.rb +163 -0
- data/vendor/camping-2.0.20090212/lib/camping/server.rb +158 -0
- data/vendor/camping-2.0.20090212/lib/camping/session.rb +74 -0
- data/vendor/camping-2.0.20090212/lib/camping-unabridged.rb +638 -0
- data/vendor/camping-2.0.20090212/lib/camping.rb +54 -0
- data/vendor/camping-2.0.20090212/setup.rb +1551 -0
- data/vendor/camping-2.0.20090212/test/apps/env_debug.rb +65 -0
- data/vendor/camping-2.0.20090212/test/apps/forms.rb +95 -0
- data/vendor/camping-2.0.20090212/test/apps/misc.rb +86 -0
- data/vendor/camping-2.0.20090212/test/apps/sessions.rb +38 -0
- data/vendor/camping-2.0.20090212/test/test_camping.rb +54 -0
- metadata +128 -0
@@ -0,0 +1,274 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module Picnic
|
4
|
+
|
5
|
+
# Provides functionality for controlling a Picnic-based server as
|
6
|
+
# an init.d service.
|
7
|
+
#
|
8
|
+
# Based on code from rubycas-server by jzylks and matt.zukowski.
|
9
|
+
#
|
10
|
+
# Usage Example:
|
11
|
+
#
|
12
|
+
# #!/usr/bin/env ruby
|
13
|
+
#
|
14
|
+
# require 'rubygems'
|
15
|
+
# require 'picnic/service_control'
|
16
|
+
#
|
17
|
+
# ctl = Picnic::ServiceControl.new('foo')
|
18
|
+
# ctl.handle_cli_input
|
19
|
+
#
|
20
|
+
# The file containing this code can now be used to control the Picnic
|
21
|
+
# app 'foo'.
|
22
|
+
#
|
23
|
+
# For, example, lets say you put this in a file called <tt>foo-ctl</tt>.
|
24
|
+
# You can now use <tt>foo-ctl</tt> on the command line as follows:
|
25
|
+
#
|
26
|
+
# chmod +x foo-ctl
|
27
|
+
# ./foo-ctl -h
|
28
|
+
# ./foo-ctl start --verbose --config /etc/foo/config.yml
|
29
|
+
# ./foo-ctl stop --config /etc/foo/config.yml
|
30
|
+
#
|
31
|
+
# Your <tt>foo-ctl</tt> script can also be used as part of Linux's init.d
|
32
|
+
# mechanism for launching system services. To do this, create the file
|
33
|
+
# <tt>/etc/init.d/foo</tt> and make sure that it is executable. It will
|
34
|
+
# look something like the following (this may vary depending on your Linux
|
35
|
+
# distribution; this example is for SuSE):
|
36
|
+
#
|
37
|
+
# #!/bin/sh
|
38
|
+
# CTL=foo-ctl
|
39
|
+
# . /etc/rc.status
|
40
|
+
#
|
41
|
+
# rc_reset
|
42
|
+
# case "$1" in
|
43
|
+
# start)
|
44
|
+
# $CTL start
|
45
|
+
# rc_status -v
|
46
|
+
# ;;
|
47
|
+
# stop)
|
48
|
+
# $CTL stop
|
49
|
+
# rc_status -v
|
50
|
+
# ;;
|
51
|
+
# restart)
|
52
|
+
# $0 stop
|
53
|
+
# $0 start
|
54
|
+
# rc_status
|
55
|
+
# ;;
|
56
|
+
# status)
|
57
|
+
# $CTL status
|
58
|
+
# rc_status -v
|
59
|
+
# ;;
|
60
|
+
# *)
|
61
|
+
# echo "Usage: $0 {start|stop|status|restart}
|
62
|
+
# exit 1
|
63
|
+
# ;;
|
64
|
+
# esac
|
65
|
+
# rc_exit
|
66
|
+
#
|
67
|
+
# You should now be able to launch your application like any other init.d script
|
68
|
+
# (just make sure that <tt>foo-ctl</tt> is installed in your executable <tt>PATH</tt>
|
69
|
+
# -- if your application is properly installed as a RubyGem, this will be done automatically).
|
70
|
+
#
|
71
|
+
# On most Linux systems, you can make your app start up automatically during boot by calling:
|
72
|
+
#
|
73
|
+
# chkconfig -a foo
|
74
|
+
#
|
75
|
+
# On Debian and Ubuntu, it's:
|
76
|
+
#
|
77
|
+
# update-rc.d foo defaults
|
78
|
+
#
|
79
|
+
class ServiceControl
|
80
|
+
|
81
|
+
attr_accessor :app, :options
|
82
|
+
|
83
|
+
# Creates a new service controller.
|
84
|
+
#
|
85
|
+
# +app+:: The name of the application. This should match the name of the
|
86
|
+
# binary, which by default is expected to be in the same directory
|
87
|
+
# as the service control script.
|
88
|
+
# +options+:: A hash overriding default options. The options are:
|
89
|
+
# +bin_file+:: The name of the binary file that this control
|
90
|
+
# script will use to start and stop your app.
|
91
|
+
# +pid_file+:: Where the app's PID file (containing the app's
|
92
|
+
# process ID) should be placed.
|
93
|
+
# +verbose+:: True if the service control script should report
|
94
|
+
# everything that it's doing to STDOUT.
|
95
|
+
def initialize(app, options = {})
|
96
|
+
@app = app
|
97
|
+
|
98
|
+
@options = options
|
99
|
+
@options[:bin_file] ||= "bin/#{app}"
|
100
|
+
@options[:pid_file] ||= "/etc/#{app}/#{app}.pid"
|
101
|
+
@options[:conf_file] ||= nil
|
102
|
+
@options[:verbose] ||= false
|
103
|
+
|
104
|
+
@options = options
|
105
|
+
end
|
106
|
+
|
107
|
+
# Parses command line options given to the service control script.
|
108
|
+
def handle_cli_input
|
109
|
+
OptionParser.new do |opts|
|
110
|
+
opts.banner = "Usage: #{$0} (start|stop|restart) [options]"
|
111
|
+
opts.banner += "\n#{app} is only usable when using webrick or mongrel"
|
112
|
+
|
113
|
+
opts.on("-c", "--config FILE", "Path to #{app} configuration file") { |value| @options[:conf_file] = value }
|
114
|
+
opts.on("-P", "--pid_file FILE", "Path to #{app} pid file") { |value| @options[:pid_file] = value }
|
115
|
+
opts.on('-v', '--verbose', "Print debugging information to the console") { |value| @options[:verbose] = value }
|
116
|
+
|
117
|
+
if ARGV.empty?
|
118
|
+
puts opts
|
119
|
+
exit
|
120
|
+
else
|
121
|
+
@cmd = opts.parse!(ARGV)
|
122
|
+
if @cmd.nil?
|
123
|
+
puts opts
|
124
|
+
exit
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
if !@options[:conf_file].nil? && !File.exists?(@options[:conf_file])
|
130
|
+
puts "Invalid path to #{app} configuration file: #{@options[:conf_file]}"
|
131
|
+
exit
|
132
|
+
end
|
133
|
+
|
134
|
+
case @cmd[0]
|
135
|
+
when "start":
|
136
|
+
puts "Starting #{app}..."
|
137
|
+
start
|
138
|
+
when "stop":
|
139
|
+
puts "Stopping #{app}..."
|
140
|
+
stop
|
141
|
+
when "restart":
|
142
|
+
puts "Restarting #{app}..."
|
143
|
+
stop
|
144
|
+
start
|
145
|
+
when "status":
|
146
|
+
puts "Checking status of #{app}..."
|
147
|
+
status
|
148
|
+
else
|
149
|
+
puts "Invalid command. Usage: #{app}-ctl [-cPv] start|stop|restart|status"
|
150
|
+
end
|
151
|
+
|
152
|
+
exit
|
153
|
+
end
|
154
|
+
|
155
|
+
def start
|
156
|
+
# use local app bin if it exists and is executable -- makes debugging easier
|
157
|
+
bin = options[:bin_file]
|
158
|
+
|
159
|
+
if File.exists?(bin)
|
160
|
+
exec = "ruby #{bin}"
|
161
|
+
else
|
162
|
+
exec = app
|
163
|
+
end
|
164
|
+
|
165
|
+
case get_state
|
166
|
+
when :ok
|
167
|
+
$stderr.puts "#{app} is already running"
|
168
|
+
exit 1
|
169
|
+
when :not_running, :empty_pid
|
170
|
+
$stderr.puts "The pid file '#{@options[:pid_file]}' exists but #{app} is not running." +
|
171
|
+
" The pid file will be automatically deleted for you, but this shouldn't have happened!"
|
172
|
+
File.delete(@options[:pid_file])
|
173
|
+
when :dead
|
174
|
+
$stderr.puts "The pid file '#{@options[:pid_file]}' exists but #{app} is not running." +
|
175
|
+
" Please delete the pid file first."
|
176
|
+
exit 1
|
177
|
+
when :missing_pid
|
178
|
+
# we should be good to go (unless the server is already running without a pid file)
|
179
|
+
else
|
180
|
+
$stderr.puts "#{app} could not be started. Try looking in the log file for more info."
|
181
|
+
exit 1
|
182
|
+
end
|
183
|
+
|
184
|
+
cmd = "#{exec} -d -P #{@options[:pid_file]}"
|
185
|
+
cmd += " -c #{@options[:conf_file]}" if !@options[:conf_file].nil?
|
186
|
+
|
187
|
+
puts "<<< #{cmd}" if @options[:verbose]
|
188
|
+
|
189
|
+
output = `#{cmd}`
|
190
|
+
|
191
|
+
puts ">>> #{output}" if @options[:verbose]
|
192
|
+
|
193
|
+
s = get_state
|
194
|
+
|
195
|
+
puts ">>> STATE: #{s.to_s}" if options[:verbose]
|
196
|
+
|
197
|
+
if s == :ok
|
198
|
+
exit 0
|
199
|
+
else
|
200
|
+
$stderr.puts "\n#{app} could not start properly!\nTry running with the --verbose option for details."
|
201
|
+
case s
|
202
|
+
when :missing_pid
|
203
|
+
exit 4
|
204
|
+
when :not_running
|
205
|
+
exit 3
|
206
|
+
when :dead
|
207
|
+
exit 1
|
208
|
+
else
|
209
|
+
exit 4
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def stop
|
215
|
+
if File.exists? @options[:pid_file]
|
216
|
+
pid = open(@options[:pid_file]).read.to_i
|
217
|
+
begin
|
218
|
+
Process.kill("TERM", pid)
|
219
|
+
exit 0
|
220
|
+
rescue Errno::ESRCH
|
221
|
+
$stderr.puts "#{app} process '#{pid}' does not exist."
|
222
|
+
exit 1
|
223
|
+
end
|
224
|
+
else
|
225
|
+
$stderr.puts "#{@options[:pid_file]} not found. Is #{app} running?"
|
226
|
+
exit 4
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def status
|
231
|
+
case get_state
|
232
|
+
when :ok
|
233
|
+
puts "#{app} appears to be up and running."
|
234
|
+
exit 0
|
235
|
+
when :missing_pid
|
236
|
+
$stderr.puts "#{app} does not appear to be running (pid file not found)."
|
237
|
+
exit 3
|
238
|
+
when :empty_pid
|
239
|
+
$stderr.puts "#{app} does not appear to be running (pid file exists but is empty)."
|
240
|
+
when :not_running
|
241
|
+
$stderr.puts "#{app} is not running."
|
242
|
+
exit 1
|
243
|
+
when :dead
|
244
|
+
$stderr.puts "#{app} is dead or unresponsive."
|
245
|
+
exit 102
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
def get_state
|
250
|
+
# FIXME: This is a poor attempt at trying to fix a problem where occassionally
|
251
|
+
# an empty pid_file is read, probably because it has not yet been
|
252
|
+
# fully written.
|
253
|
+
sleep 0.5
|
254
|
+
|
255
|
+
if File.exists? @options[:pid_file]
|
256
|
+
pid = File.read(@options[:pid_file]).strip
|
257
|
+
|
258
|
+
return :empty_pid unless pid and !pid.empty? # pid file exists but is empty
|
259
|
+
|
260
|
+
state = `ps -p #{pid} -o state=`.strip
|
261
|
+
if state == ''
|
262
|
+
return :not_running
|
263
|
+
elsif state == 'R' || state == 'S'
|
264
|
+
return :ok
|
265
|
+
else
|
266
|
+
return :dead
|
267
|
+
end
|
268
|
+
else
|
269
|
+
# TODO: scan through the process table to see if server is running without pid file
|
270
|
+
return :missing_pid
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
data/lib/picnic.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'activesupport'
|
3
|
+
|
4
|
+
$: << File.dirname(__FILE__)
|
5
|
+
$: << File.dirname(__FILE__) + "/../vendor/camping-2.0.20090212/lib"
|
6
|
+
|
7
|
+
require "camping"
|
8
|
+
|
9
|
+
|
10
|
+
module Picnic
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.mod_eval do
|
14
|
+
# Enable authentication for your app.
|
15
|
+
#
|
16
|
+
# For example:
|
17
|
+
#
|
18
|
+
# Camping.goes :Blog
|
19
|
+
# Blog.picnic!
|
20
|
+
#
|
21
|
+
# $CONF[:authentication] ||= {:username => 'admin', :password => 'picnic'}
|
22
|
+
# Blog.authenticate_using :basic
|
23
|
+
#
|
24
|
+
# module Blog
|
25
|
+
# def self.authenticate(credentials)
|
26
|
+
# credentials[:username] == Taskr::Conf[:authentication][:username] &&
|
27
|
+
# credentials[:password] == Taskr::Conf[:authentication][:password]
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# Note that in the above example we use the authentication configuration from
|
32
|
+
# your app's conf file.
|
33
|
+
#
|
34
|
+
def authenticate_using(mod)
|
35
|
+
load "picnic/authentication.rb"
|
36
|
+
mod = self::Authentication.const_get(mod.to_s.camelize) unless mod.kind_of? Module
|
37
|
+
|
38
|
+
$LOG.info("Enabling authentication for all requests using #{mod.inspect}.")
|
39
|
+
|
40
|
+
module_eval do
|
41
|
+
include mod
|
42
|
+
end
|
43
|
+
end
|
44
|
+
module_function :authenticate_using
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|