daemon-kit 0.1.7.10 → 0.1.7.11
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/.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
|