daemon-kit 0.1.7.10 → 0.1.7.11
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Configuration.txt +8 -0
- data/History.txt +13 -1
- data/Logging.txt +4 -0
- data/Manifest.txt +7 -1
- data/PostInstall.txt +1 -1
- data/README.rdoc +9 -13
- data/Rakefile +22 -30
- data/TODO.txt +1 -10
- data/app_generators/daemon_kit/daemon_kit_generator.rb +18 -1
- data/app_generators/daemon_kit/templates/config/boot.rb +6 -15
- data/app_generators/daemon_kit/templates/config/environments/production.rb +3 -0
- data/bin/{daemon_kit → daemon-kit} +0 -0
- data/config/website.yml +2 -0
- data/daemon-kit.gemspec +264 -0
- data/daemon_generators/nanite_agent/templates/config/nanite.yml +2 -2
- data/daemon_generators/rspec/templates/spec/spec_helper.rb +3 -1
- data/daemon_generators/rspec/templates/tasks/rspec.rake +8 -10
- data/daemon_generators/test_unit/USAGE +5 -0
- data/daemon_generators/test_unit/templates/tasks/test_unit.rake +7 -0
- data/daemon_generators/test_unit/templates/test/test.rb +9 -0
- data/daemon_generators/test_unit/templates/test/test_helper.rb +6 -0
- data/daemon_generators/test_unit/test_unit_generator.rb +51 -0
- data/lib/daemon_kit.rb +9 -1
- data/lib/daemon_kit/abstract_logger.rb +6 -0
- data/lib/daemon_kit/application.rb +1 -0
- data/lib/daemon_kit/arguments.rb +5 -0
- data/lib/daemon_kit/error_handlers/hoptoad.rb +4 -4
- data/lib/daemon_kit/exceptions.rb +7 -0
- data/lib/daemon_kit/initializer.rb +25 -11
- data/lib/daemon_kit/nanite/agent.rb +26 -5
- data/lib/daemon_kit/ruote_workitem.rb +9 -1
- data/lib/daemon_kit/tasks/god.rake +1 -1
- data/lib/daemon_kit/xmpp.rb +31 -0
- data/tasks/cucumber.rake +13 -0
- data/tasks/tests.rake +6 -0
- data/templates/god/god.erb +2 -2
- data/test/test_ruote_generator.rb +8 -2
- data/test/test_test_unit_generator.rb +46 -0
- metadata +45 -36
@@ -1,3 +1,5 @@
|
|
1
|
+
DAEMON_ENV = 'test' unless defined?( DAEMON_ENV )
|
2
|
+
|
1
3
|
begin
|
2
4
|
require 'spec'
|
3
5
|
rescue LoadError
|
@@ -15,7 +17,7 @@ Spec::Runner.configure do |config|
|
|
15
17
|
# RSpec uses it's own mocking framework by default. If you prefer to
|
16
18
|
# use mocha, flexmock or RR, uncomment the appropriate line:
|
17
19
|
#
|
18
|
-
config.mock_with :mocha
|
20
|
+
# config.mock_with :mocha
|
19
21
|
# config.mock_with :flexmock
|
20
22
|
# config.mock_with :rr
|
21
23
|
end
|
@@ -1,21 +1,19 @@
|
|
1
1
|
begin
|
2
2
|
require 'spec'
|
3
|
-
rescue LoadError
|
4
|
-
require 'rubygems'
|
5
|
-
require 'spec'
|
6
|
-
end
|
7
|
-
begin
|
8
3
|
require 'spec/rake/spectask'
|
9
4
|
rescue LoadError
|
10
5
|
puts <<-EOS
|
11
6
|
To use rspec for testing you must install rspec gem:
|
12
7
|
gem install rspec
|
13
8
|
EOS
|
14
|
-
exit(0)
|
15
9
|
end
|
16
10
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
11
|
+
begin
|
12
|
+
desc "Run the specs under spec/"
|
13
|
+
Spec::Rake::SpecTask.new do |t|
|
14
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
15
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
16
|
+
end
|
17
|
+
rescue NameError
|
18
|
+
# No loss, warning printed already
|
21
19
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class TestUnitGenerator < RubiGen::Base
|
2
|
+
|
3
|
+
attr_reader :gem_name, :module_name
|
4
|
+
|
5
|
+
def initialize(runtime_args, runtime_options = {})
|
6
|
+
super
|
7
|
+
@destination_root = File.expand_path(destination_root)
|
8
|
+
@gem_name = base_name
|
9
|
+
@module_name = @gem_name.camelcase
|
10
|
+
extract_options
|
11
|
+
end
|
12
|
+
|
13
|
+
def manifest
|
14
|
+
record do |m|
|
15
|
+
# Ensure appropriate folder(s) exists
|
16
|
+
m.directory 'test'
|
17
|
+
m.directory 'tasks'
|
18
|
+
|
19
|
+
m.template 'test/test.rb', "test/#{gem_name}_test.rb"
|
20
|
+
m.template_copy_each %w( test_helper.rb ), 'test'
|
21
|
+
m.file_copy_each %w( test_unit.rake ), 'tasks'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
def banner
|
27
|
+
<<-EOS
|
28
|
+
Creates a ...
|
29
|
+
|
30
|
+
USAGE: #{$0} #{spec.name} name
|
31
|
+
EOS
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_options!(opts)
|
35
|
+
# opts.separator ''
|
36
|
+
# opts.separator 'Options:'
|
37
|
+
# For each option below, place the default
|
38
|
+
# at the top of the file next to "default_options"
|
39
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
40
|
+
# "Some comment about this option",
|
41
|
+
# "Default: none") { |o| options[:author] = o }
|
42
|
+
# opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
43
|
+
end
|
44
|
+
|
45
|
+
def extract_options
|
46
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
47
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
48
|
+
# raw instance variable value.
|
49
|
+
# @author = options[:author]
|
50
|
+
end
|
51
|
+
end
|
data/lib/daemon_kit.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
# TODO: Strip this out eventually so we can run without rubygems
|
2
2
|
require 'rubygems'
|
3
3
|
|
4
|
+
# Seems in 1.9 we need to load openssl before em or there is failures all around.
|
5
|
+
# But we need to consider that people might not have ssl in the first place.
|
6
|
+
if RUBY_VERSION >= "1.9"
|
7
|
+
begin
|
8
|
+
require 'openssl'
|
9
|
+
rescue LoadError
|
10
|
+
end
|
11
|
+
end
|
4
12
|
require 'eventmachine'
|
5
13
|
|
6
14
|
require File.dirname(__FILE__) + '/daemon_kit/core_ext'
|
@@ -10,7 +18,7 @@ $:.unshift( File.dirname(__FILE__).to_absolute_path ) unless
|
|
10
18
|
$:.include?( File.dirname(__FILE__).to_absolute_path )
|
11
19
|
|
12
20
|
module DaemonKit
|
13
|
-
VERSION = '0.1.7.
|
21
|
+
VERSION = '0.1.7.11'
|
14
22
|
|
15
23
|
autoload :Initializer, 'daemon_kit/initializer'
|
16
24
|
autoload :Application, 'daemon_kit/application'
|
@@ -63,6 +63,12 @@ module DaemonKit
|
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
+
# Write unformatted message to logging device, mostly useful for Logger interface
|
67
|
+
# compatibility and debugging soap4r (possibly others)
|
68
|
+
def <<( msg ) #:nodoc:
|
69
|
+
self.logger.write( msg ) if self.logger && self.logger.respond_to?( :write )
|
70
|
+
end
|
71
|
+
|
66
72
|
def debug( msg )
|
67
73
|
add( :debug, msg )
|
68
74
|
end
|
data/lib/daemon_kit/arguments.rb
CHANGED
@@ -19,10 +19,15 @@ module DaemonKit
|
|
19
19
|
'run'
|
20
20
|
]
|
21
21
|
|
22
|
+
# We don't parse arguments by default
|
23
|
+
@parser_available = false
|
24
|
+
|
22
25
|
class << self
|
23
26
|
|
24
27
|
attr_reader :default_command, :commands
|
25
28
|
|
29
|
+
attr_accessor :parser_available
|
30
|
+
|
26
31
|
# Parse the argument values and return an array with the command
|
27
32
|
# name, config values and argument values
|
28
33
|
def parse( argv )
|
@@ -19,8 +19,8 @@ module DaemonKit
|
|
19
19
|
data = clean_exception( exception )
|
20
20
|
|
21
21
|
response = begin
|
22
|
-
http.post( url.path, data.to_yaml, headers )
|
23
|
-
rescue
|
22
|
+
http.post( url.path, {"notice" => data}.to_yaml, headers )
|
23
|
+
rescue TimeoutError => e
|
24
24
|
DaemonKit.logger.error("Timeout while contacting the Hoptoad server.")
|
25
25
|
nil
|
26
26
|
end
|
@@ -43,8 +43,8 @@ module DaemonKit
|
|
43
43
|
:error_message => "#{exception.class.name}: #{exception.message}",
|
44
44
|
:backtrace => exception.backtrace,
|
45
45
|
:environment => ENV.to_hash,
|
46
|
-
:request =>
|
47
|
-
:session =>
|
46
|
+
:request => {},
|
47
|
+
:session => {}
|
48
48
|
}
|
49
49
|
|
50
50
|
stringify_keys( data )
|
@@ -5,4 +5,11 @@ module DaemonKit
|
|
5
5
|
|
6
6
|
# Raised when no class is registered to process a ruote workitem
|
7
7
|
class MissingParticipant < Exception; end
|
8
|
+
|
9
|
+
# Raised when the daemon itself cannot be found.
|
10
|
+
class DaemonNotFound < Exception
|
11
|
+
def initialize( file )
|
12
|
+
super "No daemon found at the path '#{file}'"
|
13
|
+
end
|
14
|
+
end
|
8
15
|
end
|
@@ -64,7 +64,7 @@ module DaemonKit
|
|
64
64
|
initializer.after_daemonize
|
65
65
|
end
|
66
66
|
|
67
|
-
def self.shutdown( clean = false )
|
67
|
+
def self.shutdown( clean = false, do_exit = false )
|
68
68
|
return unless $daemon_kit_shutdown_hooks_ran.nil?
|
69
69
|
$daemon_kit_shutdown_hooks_ran = true
|
70
70
|
|
@@ -81,7 +81,8 @@ module DaemonKit
|
|
81
81
|
log_exceptions if DaemonKit.configuration.backtraces && !clean
|
82
82
|
|
83
83
|
DaemonKit.logger.warn "Shutting down #{DaemonKit.configuration.daemon_name}"
|
84
|
-
|
84
|
+
|
85
|
+
exit if do_exit
|
85
86
|
end
|
86
87
|
|
87
88
|
def initialize( configuration )
|
@@ -114,10 +115,10 @@ module DaemonKit
|
|
114
115
|
|
115
116
|
if DaemonKit.configuration.user || DaemonKit.configuration.group
|
116
117
|
euid = Process.euid
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
118
|
+
egid = Process.egid
|
119
|
+
uid = Process.uid
|
120
|
+
gid = Process.gid
|
121
|
+
DaemonKit.logger.info( "DaemonKit dropped privileges to: #{euid} (EUID), #{egid} (EGID), #{uid} (UID), #{gid} (GID)" )
|
121
122
|
end
|
122
123
|
end
|
123
124
|
|
@@ -191,7 +192,8 @@ module DaemonKit
|
|
191
192
|
end
|
192
193
|
|
193
194
|
def initialize_signal_traps
|
194
|
-
|
195
|
+
# Only exit the process if we're not in the 'test' environment
|
196
|
+
term_proc = Proc.new { DaemonKit::Initializer.shutdown( true, DAEMON_ENV != 'test' ) }
|
195
197
|
configuration.trap( 'INT', term_proc )
|
196
198
|
configuration.trap( 'TERM', term_proc )
|
197
199
|
at_exit { DaemonKit::Initializer.shutdown }
|
@@ -212,7 +214,7 @@ module DaemonKit
|
|
212
214
|
end
|
213
215
|
|
214
216
|
def self.log_exceptions
|
215
|
-
trace_file = File.join( DaemonKit.root, "backtrace-#{Time.now.strftime('%Y%m%d%H%M%S')}-#{Process.pid}.log" )
|
217
|
+
trace_file = File.join( DaemonKit.root, 'log', "backtrace-#{Time.now.strftime('%Y%m%d%H%M%S')}-#{Process.pid}.log" )
|
216
218
|
trace_log = Logger.new( trace_file )
|
217
219
|
|
218
220
|
# Find the last exception
|
@@ -252,7 +254,7 @@ module DaemonKit
|
|
252
254
|
attr_accessor :logger
|
253
255
|
|
254
256
|
# The log level to use, defaults to DEBUG
|
255
|
-
|
257
|
+
attr_reader :log_level
|
256
258
|
|
257
259
|
# Path to the log file, defaults to 'log/<environment>.log'
|
258
260
|
configurable :log_path
|
@@ -286,7 +288,7 @@ module DaemonKit
|
|
286
288
|
|
287
289
|
# Our safety net (#Safety) instance
|
288
290
|
attr_accessor :safety_net
|
289
|
-
|
291
|
+
|
290
292
|
# :nodoc: Shutdown hooks
|
291
293
|
attr_reader :shutdown_hooks
|
292
294
|
|
@@ -326,6 +328,12 @@ module DaemonKit
|
|
326
328
|
def trap( signal, proc = nil, &block )
|
327
329
|
return if proc.nil? && !block_given?
|
328
330
|
|
331
|
+
# One step towards running on windows, not enough though
|
332
|
+
unless Signal.list.include?( signal )
|
333
|
+
DaemonKit.logger.warn( "Trapping #{signal} signals not supported on this platform" )
|
334
|
+
return
|
335
|
+
end
|
336
|
+
|
329
337
|
unless @signal_traps.has_key?( signal )
|
330
338
|
set_trap( signal )
|
331
339
|
end
|
@@ -344,6 +352,12 @@ module DaemonKit
|
|
344
352
|
@pid_file ||= "#{File.dirname(self.log_path)}/#{self.daemon_name}.pid"
|
345
353
|
end
|
346
354
|
|
355
|
+
# Set the log level
|
356
|
+
def log_level=( level )
|
357
|
+
@log_level = level
|
358
|
+
DaemonKit.logger.level = @log_level if DaemonKit.logger
|
359
|
+
end
|
360
|
+
|
347
361
|
protected
|
348
362
|
|
349
363
|
def run_traps( signal )
|
@@ -430,7 +444,7 @@ module DaemonKit
|
|
430
444
|
# arguments to be parsed cause they will interfere with the
|
431
445
|
# script encapsulating DaemonKit, like capistrano
|
432
446
|
def own_args?
|
433
|
-
|
447
|
+
Arguments.parser_available
|
434
448
|
end
|
435
449
|
end
|
436
450
|
|
@@ -1,3 +1,24 @@
|
|
1
|
+
module Nanite
|
2
|
+
class Agent
|
3
|
+
|
4
|
+
attr_accessor :init_block
|
5
|
+
|
6
|
+
def load_actors_with_daemon_kit_changes( &block )
|
7
|
+
actors = @options[:actors]
|
8
|
+
Dir["#{DaemonKit.root}/lib/actors/*.rb"].each do |actor|
|
9
|
+
next if actors && !actors.include?( File.basename(actor, '.rb') )
|
10
|
+
Nanite::Log.info( "[setup] loading #{actor}" )
|
11
|
+
require actor
|
12
|
+
end
|
13
|
+
|
14
|
+
self.init_block.call( self )
|
15
|
+
end
|
16
|
+
|
17
|
+
alias_method :load_actors_without_daemon_kit_changes, :load_actors
|
18
|
+
alias_method :load_actors, :load_actors_with_daemon_kit_changes
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
1
22
|
module DaemonKit
|
2
23
|
module Nanite
|
3
24
|
# Pull support into a daemon for being a nanite agent.
|
@@ -29,22 +50,22 @@ module DaemonKit
|
|
29
50
|
# Ensure graceful shutdown of the connection to the broker
|
30
51
|
DaemonKit.trap('INT') { ::EM.stop }
|
31
52
|
DaemonKit.trap('TERM') { ::EM.stop }
|
53
|
+
::Nanite::Log.logger = DaemonKit.logger
|
32
54
|
|
33
55
|
# Start our mapper
|
34
56
|
mapper_thread = Thread.new do
|
35
57
|
EM.run do
|
36
|
-
agent = ::Nanite.
|
37
|
-
|
58
|
+
agent = ::Nanite::Agent.new( @config )
|
59
|
+
agent.init_block = block
|
60
|
+
agent.run
|
38
61
|
end
|
39
62
|
end
|
40
63
|
|
41
|
-
#block.call if block
|
42
|
-
|
43
64
|
mapper_thread.join
|
44
65
|
end
|
45
66
|
|
46
67
|
private
|
47
|
-
|
68
|
+
|
48
69
|
# Make sure to fine tune the agent config to be DK friendly
|
49
70
|
def config_agent
|
50
71
|
@config[:root] = DAEMON_ROOT
|
@@ -42,6 +42,9 @@ module DaemonKit
|
|
42
42
|
|
43
43
|
work = parse( workitem )
|
44
44
|
|
45
|
+
# Invalid JSON... mmm
|
46
|
+
return if work.nil?
|
47
|
+
|
45
48
|
DaemonKit.logger.warn "Processing workitem that has timed out!" if work.timed_out?
|
46
49
|
|
47
50
|
target, method = parse_command( work )
|
@@ -94,7 +97,12 @@ module DaemonKit
|
|
94
97
|
end
|
95
98
|
|
96
99
|
def parse( workitem )
|
97
|
-
|
100
|
+
begin
|
101
|
+
return new( JSON.parse( workitem ) )
|
102
|
+
rescue JSON::ParserError => e
|
103
|
+
DaemonKit.logger.error "No valid JSON payload found in #{workitem}"
|
104
|
+
return nil
|
105
|
+
end
|
98
106
|
end
|
99
107
|
end
|
100
108
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module DaemonKit
|
2
|
+
# Thin wrapper around the blather DSL
|
3
|
+
class XMPP
|
4
|
+
include ::Blather::DSL
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def run( &block )
|
9
|
+
DaemonKit::EM.run
|
10
|
+
|
11
|
+
xmpp = new
|
12
|
+
|
13
|
+
xmpp.instance_eval( &block )
|
14
|
+
|
15
|
+
xmpp.run
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@config = DaemonKit::Config.load('jabber')
|
21
|
+
|
22
|
+
jid = if @config.resource
|
23
|
+
"#{@config.jabber_id}/#{@config.resource}"
|
24
|
+
else
|
25
|
+
@config.jabber_id
|
26
|
+
end
|
27
|
+
|
28
|
+
setup jid, @config.password
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|