daemon-kit 0.1.7 → 0.1.7.4

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.
Files changed (80) hide show
  1. data/Configuration.txt +58 -0
  2. data/History.txt +24 -0
  3. data/Manifest.txt +50 -2
  4. data/PostInstall.txt +1 -1
  5. data/README.rdoc +7 -9
  6. data/Rakefile +2 -4
  7. data/TODO.txt +6 -5
  8. data/app_generators/daemon_kit/daemon_kit_generator.rb +5 -0
  9. data/app_generators/daemon_kit/templates/Rakefile +3 -1
  10. data/app_generators/daemon_kit/templates/bin/daemon.erb +1 -1
  11. data/app_generators/daemon_kit/templates/config/arguments.rb +12 -0
  12. data/app_generators/daemon_kit/templates/config/boot.rb +2 -2
  13. data/app_generators/daemon_kit/templates/script/console +3 -0
  14. data/app_generators/daemon_kit/templates/script/destroy +14 -0
  15. data/app_generators/daemon_kit/templates/script/generate +14 -0
  16. data/daemon_generators/amqp/templates/config/amqp.yml +5 -5
  17. data/daemon_generators/deploy_capistrano/deploy_capistrano_generator.rb +4 -23
  18. data/daemon_generators/deploy_capistrano/templates/USAGE +10 -0
  19. data/daemon_generators/deploy_capistrano/templates/config/deploy.rb +3 -1
  20. data/lib/daemon_kit.rb +33 -5
  21. data/lib/daemon_kit/amqp.rb +2 -1
  22. data/lib/daemon_kit/application.rb +136 -11
  23. data/lib/daemon_kit/arguments.rb +151 -0
  24. data/lib/daemon_kit/commands/console.rb +38 -0
  25. data/lib/daemon_kit/config.rb +1 -0
  26. data/lib/daemon_kit/console_daemon.rb +2 -0
  27. data/lib/daemon_kit/core_ext.rb +1 -0
  28. data/lib/daemon_kit/core_ext/string.rb +22 -0
  29. data/lib/daemon_kit/deployment/capistrano.rb +6 -9
  30. data/lib/daemon_kit/error_handlers/mail.rb +52 -15
  31. data/lib/daemon_kit/initializer.rb +95 -41
  32. data/lib/daemon_kit/pid_file.rb +61 -0
  33. data/lib/daemon_kit/tasks/environment.rake +5 -4
  34. data/lib/daemon_kit/tasks/framework.rake +15 -1
  35. data/lib/daemon_kit/tasks/god.rake +62 -0
  36. data/lib/daemon_kit/tasks/log.rake +8 -0
  37. data/lib/daemon_kit/tasks/monit.rake +29 -0
  38. data/spec/argument_spec.rb +51 -0
  39. data/spec/config_spec.rb +77 -0
  40. data/spec/daemon_kit_spec.rb +2 -2
  41. data/spec/error_handlers_spec.rb +23 -0
  42. data/spec/fixtures/env.yml +15 -0
  43. data/spec/fixtures/noenv.yml +4 -0
  44. data/spec/initializer_spec.rb +4 -3
  45. data/spec/spec_helper.rb +8 -11
  46. data/templates/god/god.erb +69 -0
  47. data/templates/monit/monit.erb +14 -0
  48. data/test/test_daemon-kit_generator.rb +6 -1
  49. data/test/test_deploy_capistrano_generator.rb +1 -2
  50. data/vendor/tmail-1.2.3/tmail.rb +5 -0
  51. data/vendor/tmail-1.2.3/tmail/address.rb +426 -0
  52. data/vendor/tmail-1.2.3/tmail/attachments.rb +46 -0
  53. data/vendor/tmail-1.2.3/tmail/base64.rb +46 -0
  54. data/vendor/tmail-1.2.3/tmail/compat.rb +41 -0
  55. data/vendor/tmail-1.2.3/tmail/config.rb +67 -0
  56. data/vendor/tmail-1.2.3/tmail/core_extensions.rb +63 -0
  57. data/vendor/tmail-1.2.3/tmail/encode.rb +581 -0
  58. data/vendor/tmail-1.2.3/tmail/header.rb +960 -0
  59. data/vendor/tmail-1.2.3/tmail/index.rb +9 -0
  60. data/vendor/tmail-1.2.3/tmail/interface.rb +1130 -0
  61. data/vendor/tmail-1.2.3/tmail/loader.rb +3 -0
  62. data/vendor/tmail-1.2.3/tmail/mail.rb +578 -0
  63. data/vendor/tmail-1.2.3/tmail/mailbox.rb +495 -0
  64. data/vendor/tmail-1.2.3/tmail/main.rb +6 -0
  65. data/vendor/tmail-1.2.3/tmail/mbox.rb +3 -0
  66. data/vendor/tmail-1.2.3/tmail/net.rb +248 -0
  67. data/vendor/tmail-1.2.3/tmail/obsolete.rb +132 -0
  68. data/vendor/tmail-1.2.3/tmail/parser.rb +1476 -0
  69. data/vendor/tmail-1.2.3/tmail/port.rb +379 -0
  70. data/vendor/tmail-1.2.3/tmail/quoting.rb +118 -0
  71. data/vendor/tmail-1.2.3/tmail/require_arch.rb +58 -0
  72. data/vendor/tmail-1.2.3/tmail/scanner.rb +49 -0
  73. data/vendor/tmail-1.2.3/tmail/scanner_r.rb +261 -0
  74. data/vendor/tmail-1.2.3/tmail/stringio.rb +280 -0
  75. data/vendor/tmail-1.2.3/tmail/utils.rb +337 -0
  76. data/vendor/tmail-1.2.3/tmail/version.rb +39 -0
  77. data/vendor/tmail.rb +13 -0
  78. metadata +57 -18
  79. data/daemon_generators/deploy_capistrano/USAGE +0 -5
  80. data/lib/daemon_kit/patches/force_kill_wait.rb +0 -120
@@ -1,9 +1,10 @@
1
1
  task :environment do
2
- # This relies on the fact that rake changes the currect working
3
- # directory to the directory where the Rakefile is located, thus
4
- # implying DAEMON_ROOT.
5
- DAEMON_ROOT = '.'
6
2
  $daemon_kit_rake_task = true
7
3
 
8
4
  require 'config/environment'
9
5
  end
6
+
7
+ task "Execute system commands in other tasks with sudo"
8
+ task :sudo do
9
+ $RAKE_USE_SUDO = true
10
+ end
@@ -76,7 +76,7 @@ namespace :daemon_kit do
76
76
  desc "Upgrade your local files for a daemon after upgrading daemon-kit"
77
77
  task :upgrade => 'environment' do
78
78
  # Run these
79
- %w{ initializers }.each do |t|
79
+ %w{ initializers rakefile scripts }.each do |t|
80
80
  Rake::Task["daemon_kit:upgrade:#{t}"].invoke
81
81
  end
82
82
 
@@ -87,6 +87,8 @@ namespace :daemon_kit do
87
87
  namespace :upgrade do
88
88
  # Upgrade the initializers
89
89
  task :initializers do
90
+ copy_framework_template( 'config/boot.rb', 'config/boot.rb' )
91
+
90
92
  if File.directory?( File.join(DaemonKit.root, 'config', 'initializers') )
91
93
  mv File.join(DaemonKit.root, 'config', 'initializers'), File.join(DAEMON_ROOT, 'config', 'pre-daemonize')
92
94
  copy_framework_template( 'config', 'pre-daemonize', 'readme' )
@@ -97,6 +99,18 @@ namespace :daemon_kit do
97
99
  copy_framework_template( 'config', 'post-daemonize', 'readme' )
98
100
  end
99
101
  end
102
+
103
+ # Upgrade the Rakefile
104
+ task :rakefile do
105
+ copy_framework_template( 'Rakefile' )
106
+ end
107
+
108
+ # Upgrade the scripts
109
+ task :scripts do
110
+ %w{ console destroy generate }.each do |s|
111
+ copy_framework_template( "script", s )
112
+ end
113
+ end
100
114
  end
101
115
  end
102
116
 
@@ -0,0 +1,62 @@
1
+ require 'erb'
2
+
3
+ namespace :god do
4
+ desc "Generate a stub god config file template for the daemon"
5
+ task :template => 'environment' do
6
+ # Preserve local changes
7
+ if File.exists?( "#{DaemonKit.root}/config/god.erb" ) && ENV['FORCE'].nil?
8
+ puts "Template already exists, use FORCE=1 to overwrite."
9
+ exit 1
10
+ end
11
+
12
+ cp "#{DaemonKit.framework_root}/templates/god/god.erb", "#{DaemonKit.root}/config/god.erb"
13
+ end
14
+
15
+ desc "Parse the god config template into a god config file"
16
+ task :generate => 'environment' do
17
+
18
+ unless File.exists?( "#{DaemonKit.root}/config/god.erb" )
19
+ Rake::Task["god:template"].invoke
20
+ end
21
+
22
+ name = DaemonKit.configuration.daemon_name
23
+
24
+ File.open( "#{DaemonKit.root}/config/#{name}.god", "w+" ) do |f|
25
+ t = File.read( "#{DaemonKit.root}/config/god.erb" )
26
+ f.write( ERB.new( t ).result( binding ) )
27
+ end
28
+
29
+ puts "Monit config generated in config/#{name}.god"
30
+ end
31
+
32
+ desc "Load the god file into god"
33
+ task :load => 'environment' do
34
+ name = DaemonKit.configuration.daemon_name
35
+
36
+ sh "#{$RAKE_USE_SUDO ? 'sudo' : ''} god load #{DaemonKit.root}/config/#{name}.god"
37
+ end
38
+
39
+ desc "Refresh the god config file in the running god"
40
+ task :refresh => 'environment' do
41
+ name = DaemonKit.configuration.daemon_name
42
+
43
+ sh "#{$RAKE_USE_SUDO ? 'sudo' : ''} god unmonitor #{name}"
44
+ sh "#{$RAKE_USE_SUDO ? 'sudo' : ''} god remove #{name}"
45
+ sh "#{$RAKE_USE_SUDO ? 'sudo' : ''} god load #{DaemonKit.root}/config/#{name}.god"
46
+ sh "#{$RAKE_USE_SUDO ? 'sudo' : ''} god monitor #{name}"
47
+ end
48
+
49
+ desc "Start god monitoring of the config file"
50
+ task :monitor => 'environment' do
51
+ name = DaemonKit.configuration.daemon_name
52
+
53
+ sh "#{$RAKE_USE_SUDO ? 'sudo' : ''} god monitor #{name}"
54
+ end
55
+
56
+ desc "Stop god monitoring of the config file"
57
+ task :unmonitor => 'environment' do
58
+ name = DaemonKit.configuration.daemon_name
59
+
60
+ sh "#{$RAKE_USE_SUDO ? 'sudo' : ''} god unmonitor #{name}"
61
+ end
62
+ end
@@ -0,0 +1,8 @@
1
+ namespace :log do
2
+ desc "Truncate all log files found in DAEMON_ROOT/log/"
3
+ task :truncate => 'environment' do
4
+ Dir[ "#{DaemonKit.root}/log/*.log" ].each do |l|
5
+ File.open( l, 'w+' ) { |f| f.write('') }
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,29 @@
1
+ require 'erb'
2
+
3
+ namespace :monit do
4
+ desc "Generate a stub monit config file template for the daemon"
5
+ task :template => 'environment' do
6
+ # Preserve local changes
7
+ if File.exists?( "#{DaemonKit.root}/config/monit.erb" ) && ENV['FORCE'].nil?
8
+ puts "Template already exists, use FORCE=1 to overwrite."
9
+ exit 1
10
+ end
11
+
12
+ cp "#{DaemonKit.framework_root}/templates/monit/monit.erb", "#{DaemonKit.root}/config/monit.erb"
13
+ end
14
+
15
+ desc "Parse the monit config template into a monit config file"
16
+ task :generate => 'environment' do
17
+
18
+ unless File.exists?( "#{DaemonKit.root}/config/monit.erb" )
19
+ Rake::Task["monit:template"].invoke
20
+ end
21
+
22
+ File.open( "#{DaemonKit.root}/config/monit.conf", "w+" ) do |f|
23
+ t = File.read( "#{DaemonKit.root}/config/monit.erb" )
24
+ f.write( ERB.new( t ).result( binding ) )
25
+ end
26
+
27
+ puts "Monit config generated in config/monit.conf"
28
+ end
29
+ end
@@ -0,0 +1,51 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe DaemonKit::Arguments do
4
+
5
+ describe "parsing ARGV" do
6
+
7
+ it "should extract the given command" do
8
+ argv = [ 'start', '-f', 'foo' ]
9
+ res = DaemonKit::Arguments.parse( argv )
10
+
11
+ res.first.should == :start
12
+ end
13
+
14
+ it "should have a default command if missing" do
15
+ argv = [ '-h' ]
16
+ res = DaemonKit::Arguments.parse( argv )
17
+
18
+ res.first.should == :run
19
+ end
20
+
21
+ it "should extract explicit configuration options" do
22
+ argv = [ 'start', '--config', 'environment=development' ]
23
+ res = DaemonKit::Arguments.parse( argv )
24
+
25
+ res.shift
26
+ res.first.should == [ 'environment=development' ]
27
+
28
+ res.last.should == []
29
+ end
30
+
31
+ it "should extract implicit configuration options" do
32
+ argv = [ '-e', 'production' ]
33
+ res = DaemonKit::Arguments.parse( argv )
34
+
35
+ res.shift
36
+ res.first.should == ['environment=production']
37
+
38
+ res.last.should == []
39
+ end
40
+
41
+ it "should extract daemon options" do
42
+ argv = [ 'start', '-h' ]
43
+ res = DaemonKit::Arguments.parse( argv )
44
+
45
+ res.shift
46
+ res.first.should == []
47
+
48
+ res.last.should == [ '-h' ]
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,77 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe DaemonKit::Config do
4
+
5
+ describe "working with config data" do
6
+ before(:each) do
7
+ @config = DaemonKit::Config.new('foo' => 'bar')
8
+ end
9
+
10
+ it "should have string key access to values" do
11
+ @config['foo'].should == 'bar'
12
+ end
13
+
14
+ it "should have symbol key access to values" do
15
+ @config[:foo].should == 'bar'
16
+ end
17
+
18
+ it "should have instance accessors to values" do
19
+ @config.foo.should == 'bar'
20
+ end
21
+
22
+ it "should return the config as a has" do
23
+ @config.to_h.should == { 'foo' => 'bar' }
24
+ end
25
+
26
+ it "should be able to symbolize keys in returned hash" do
27
+ @config.to_h(true).should == { :foo => 'bar' }
28
+ end
29
+
30
+ it "should symbolize keys in a nested fashion"
31
+ end
32
+
33
+ describe "parsing files" do
34
+ before(:all) do
35
+ FileUtils.mkdir_p( DAEMON_ROOT + "/config" )
36
+ FileUtils.cp( File.dirname(__FILE__) + '/fixtures/env.yml', DAEMON_ROOT + '/config/' )
37
+ FileUtils.cp( File.dirname(__FILE__) + '/fixtures/noenv.yml', DAEMON_ROOT + '/config/' )
38
+ end
39
+
40
+ it "should parse env keys correctly" do
41
+ config = DaemonKit::Config.load('env')
42
+
43
+ config.test.should == 'yes!'
44
+ config.array.should_not be_empty
45
+ end
46
+
47
+ it "should not be worried about missing env keys" do
48
+ config = DaemonKit::Config.load('noenv')
49
+
50
+ config.string.should == 'value'
51
+ end
52
+
53
+ it "should accept symbol file names" do
54
+ config = DaemonKit::Config.load(:env)
55
+ config.test.should == 'yes!'
56
+ end
57
+
58
+ it "should bail on missing files" do
59
+ lambda {
60
+ DaemonKit::Config.load('missing')
61
+ }.should raise_error(ArgumentError)
62
+ end
63
+
64
+ it "should give direct hash access to a config" do
65
+ config = DaemonKit::Config.hash(:env)
66
+
67
+ config.should be_a_kind_of(Hash)
68
+ config.keys.should include('test')
69
+ end
70
+
71
+ it "should give direct symbolized hash access to a config" do
72
+ config = DaemonKit::Config.hash(:env, true)
73
+
74
+ config.keys.should include(:test)
75
+ end
76
+ end
77
+ end
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper.rb'
2
2
 
3
3
  describe DaemonKit do
4
-
4
+
5
5
  it "should work"
6
-
6
+
7
7
  end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe DaemonKit::Safety do
4
+ end
5
+
6
+ describe DaemonKit::ErrorHandlers::Mail do
7
+ it "should send an email report" do
8
+ conf = Object.new
9
+ conf.stubs(:daemon_name).returns('test')
10
+ DaemonKit.stubs(:configuration).returns(conf)
11
+
12
+ fake_smtp = Object.new
13
+ fake_smtp.expects(:start).with('localhost.localdomain', nil, nil, nil)
14
+ Net::SMTP.expects(:new).with('localhost', 25).returns(fake_smtp)
15
+
16
+ begin
17
+ raise RuntimeError, "specs don't fail :)"
18
+ rescue => e
19
+ handler = DaemonKit::ErrorHandlers::Mail.instance
20
+ handler.handle_exception( e )
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ # Test ENV keys
2
+
3
+ defaults: &defaults
4
+ string: value
5
+ array:
6
+ - entry
7
+ - entry
8
+
9
+ development:
10
+ test: no!
11
+ <<: *defaults
12
+
13
+ test:
14
+ test: yes!
15
+ <<: *defaults
@@ -0,0 +1,4 @@
1
+ string: value
2
+ array:
3
+ - entry
4
+ - entry
@@ -1,10 +1,11 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'daemon_kit/initializer'
2
3
 
3
4
  describe DaemonKit::Configuration do
4
5
  before(:each) do
5
6
  @configuration = DaemonKit::Configuration.new
6
7
  end
7
-
8
+
8
9
  it "should know our environment" do
9
10
  @configuration.environment.should_not be_nil
10
11
  end
@@ -16,7 +17,7 @@ describe DaemonKit::Configuration do
16
17
  it "should have a default log level" do
17
18
  @configuration.log_level.should_not be_nil
18
19
  end
19
-
20
+
20
21
  end
21
22
 
22
23
 
@@ -27,5 +28,5 @@ describe DaemonKit::Initializer do
27
28
  DaemonKit::Initializer.run(:initialize_logger)
28
29
  DaemonKit.logger.should_not be_nil
29
30
  end
30
-
31
+
31
32
  end
data/spec/spec_helper.rb CHANGED
@@ -1,19 +1,16 @@
1
- begin
2
- require 'spec'
3
- rescue LoadError
4
- require 'rubygems'
5
- gem 'rspec'
6
- require 'spec'
7
- end
8
-
9
- $:.unshift(File.dirname(__FILE__) + '/../lib')
10
- require 'daemon_kit'
1
+ require 'rubygems'
2
+ gem 'rspec'
3
+ require 'spec'
11
4
 
12
- gem 'mocha'
5
+ require 'mocha'
13
6
  require 'fileutils'
14
7
 
8
+ DAEMON_ENV = "test"
15
9
  DAEMON_ROOT = "#{File.dirname(__FILE__)}/../tmp"
16
10
 
11
+ $:.unshift( File.dirname(__FILE__) + '/../lib' )
12
+ require 'daemon_kit'
13
+
17
14
  Spec::Runner.configure do |config|
18
15
  # == Mock Framework
19
16
  #
@@ -0,0 +1,69 @@
1
+ #
2
+ # This is a configuration template for 'god' process monitoring.
3
+ #
4
+ # More information can be found at http://god.rubyforge.org/
5
+ #
6
+
7
+ DAEMON_ROOT = "<%= DaemonKit.root %>"
8
+
9
+ God.watch do |w|
10
+ w.name = '<%= DaemonKit.configuration.daemon_name %>'
11
+ w.interval = 30.seconds
12
+ w.start = "/usr/bin/env DAEMON_ENV=<%= DaemonKit.env %> <%= DaemonKit.root %>/bin/<%= DaemonKit.configuration.daemon_name %> start"
13
+ w.stop = "/usr/bin/env DAEMON_ENV=<%= DaemonKit.env %> <%= DaemonKit.root %>/bin/<%= DaemonKit.configuration.daemon_name %> stop"
14
+ w.start_grace = 10.seconds
15
+ w.stop_grace = 10.seconds
16
+ w.pid_file = "<%= DaemonKit.configuration.pid_file %>"
17
+ w.behavior(:clean_pid_file)
18
+ #w.uid = 'nobody'
19
+ #w.gid = 'nobody'
20
+
21
+ w.start_if do |start|
22
+ start.condition(:process_running) do |c|
23
+ c.interval = 30.seconds
24
+ c.running = false
25
+ c.notify = 'sysadmin'
26
+ end
27
+ end
28
+
29
+ w.restart_if do |restart|
30
+ restart.condition(:memory_usage) do |c|
31
+ c.above = 250.megabytes
32
+ c.times = [3, 5] # 3 out of 5 intervals
33
+ c.notify = 'sysadmin'
34
+ end
35
+
36
+ restart.condition(:cpu_usage) do |c|
37
+ c.above = 50.percent
38
+ c.times = 5
39
+ c.notify = 'sysadmin'
40
+ end
41
+ end
42
+
43
+ w.lifecycle do |on|
44
+ on.condition(:flapping) do |c|
45
+ c.to_state = [:start, :restart]
46
+ c.times = 5
47
+ c.within = 5.minute
48
+ c.transition = :unmonitored
49
+ c.retry_in = 10.minutes
50
+ c.retry_times = 5
51
+ c.retry_within = 2.hours
52
+ c.notify = 'sysadmin'
53
+ end
54
+ end
55
+ end
56
+
57
+ God::Contacts::Email.server_settings = {
58
+ :address => "smtp.gmail.com",
59
+ :port => 587,
60
+ :domain => "localhost",
61
+ :authentication => :plain,
62
+ :user_name => "you@gmail.com",
63
+ :password => "secret"
64
+ }
65
+
66
+ God.contact(:email) do |c|
67
+ c.name = 'sysadmin'
68
+ c.email = 'you@gmail.com'
69
+ end