daemon-kit 0.1.7 → 0.1.7.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Configuration.txt +58 -0
- data/History.txt +24 -0
- data/Manifest.txt +50 -2
- data/PostInstall.txt +1 -1
- data/README.rdoc +7 -9
- data/Rakefile +2 -4
- data/TODO.txt +6 -5
- data/app_generators/daemon_kit/daemon_kit_generator.rb +5 -0
- data/app_generators/daemon_kit/templates/Rakefile +3 -1
- data/app_generators/daemon_kit/templates/bin/daemon.erb +1 -1
- data/app_generators/daemon_kit/templates/config/arguments.rb +12 -0
- data/app_generators/daemon_kit/templates/config/boot.rb +2 -2
- data/app_generators/daemon_kit/templates/script/console +3 -0
- data/app_generators/daemon_kit/templates/script/destroy +14 -0
- data/app_generators/daemon_kit/templates/script/generate +14 -0
- data/daemon_generators/amqp/templates/config/amqp.yml +5 -5
- data/daemon_generators/deploy_capistrano/deploy_capistrano_generator.rb +4 -23
- data/daemon_generators/deploy_capistrano/templates/USAGE +10 -0
- data/daemon_generators/deploy_capistrano/templates/config/deploy.rb +3 -1
- data/lib/daemon_kit.rb +33 -5
- data/lib/daemon_kit/amqp.rb +2 -1
- data/lib/daemon_kit/application.rb +136 -11
- data/lib/daemon_kit/arguments.rb +151 -0
- data/lib/daemon_kit/commands/console.rb +38 -0
- data/lib/daemon_kit/config.rb +1 -0
- data/lib/daemon_kit/console_daemon.rb +2 -0
- data/lib/daemon_kit/core_ext.rb +1 -0
- data/lib/daemon_kit/core_ext/string.rb +22 -0
- data/lib/daemon_kit/deployment/capistrano.rb +6 -9
- data/lib/daemon_kit/error_handlers/mail.rb +52 -15
- data/lib/daemon_kit/initializer.rb +95 -41
- data/lib/daemon_kit/pid_file.rb +61 -0
- data/lib/daemon_kit/tasks/environment.rake +5 -4
- data/lib/daemon_kit/tasks/framework.rake +15 -1
- data/lib/daemon_kit/tasks/god.rake +62 -0
- data/lib/daemon_kit/tasks/log.rake +8 -0
- data/lib/daemon_kit/tasks/monit.rake +29 -0
- data/spec/argument_spec.rb +51 -0
- data/spec/config_spec.rb +77 -0
- data/spec/daemon_kit_spec.rb +2 -2
- data/spec/error_handlers_spec.rb +23 -0
- data/spec/fixtures/env.yml +15 -0
- data/spec/fixtures/noenv.yml +4 -0
- data/spec/initializer_spec.rb +4 -3
- data/spec/spec_helper.rb +8 -11
- data/templates/god/god.erb +69 -0
- data/templates/monit/monit.erb +14 -0
- data/test/test_daemon-kit_generator.rb +6 -1
- data/test/test_deploy_capistrano_generator.rb +1 -2
- data/vendor/tmail-1.2.3/tmail.rb +5 -0
- data/vendor/tmail-1.2.3/tmail/address.rb +426 -0
- data/vendor/tmail-1.2.3/tmail/attachments.rb +46 -0
- data/vendor/tmail-1.2.3/tmail/base64.rb +46 -0
- data/vendor/tmail-1.2.3/tmail/compat.rb +41 -0
- data/vendor/tmail-1.2.3/tmail/config.rb +67 -0
- data/vendor/tmail-1.2.3/tmail/core_extensions.rb +63 -0
- data/vendor/tmail-1.2.3/tmail/encode.rb +581 -0
- data/vendor/tmail-1.2.3/tmail/header.rb +960 -0
- data/vendor/tmail-1.2.3/tmail/index.rb +9 -0
- data/vendor/tmail-1.2.3/tmail/interface.rb +1130 -0
- data/vendor/tmail-1.2.3/tmail/loader.rb +3 -0
- data/vendor/tmail-1.2.3/tmail/mail.rb +578 -0
- data/vendor/tmail-1.2.3/tmail/mailbox.rb +495 -0
- data/vendor/tmail-1.2.3/tmail/main.rb +6 -0
- data/vendor/tmail-1.2.3/tmail/mbox.rb +3 -0
- data/vendor/tmail-1.2.3/tmail/net.rb +248 -0
- data/vendor/tmail-1.2.3/tmail/obsolete.rb +132 -0
- data/vendor/tmail-1.2.3/tmail/parser.rb +1476 -0
- data/vendor/tmail-1.2.3/tmail/port.rb +379 -0
- data/vendor/tmail-1.2.3/tmail/quoting.rb +118 -0
- data/vendor/tmail-1.2.3/tmail/require_arch.rb +58 -0
- data/vendor/tmail-1.2.3/tmail/scanner.rb +49 -0
- data/vendor/tmail-1.2.3/tmail/scanner_r.rb +261 -0
- data/vendor/tmail-1.2.3/tmail/stringio.rb +280 -0
- data/vendor/tmail-1.2.3/tmail/utils.rb +337 -0
- data/vendor/tmail-1.2.3/tmail/version.rb +39 -0
- data/vendor/tmail.rb +13 -0
- metadata +57 -18
- data/daemon_generators/deploy_capistrano/USAGE +0 -5
- 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,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
|
data/spec/config_spec.rb
ADDED
@@ -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
|
data/spec/daemon_kit_spec.rb
CHANGED
@@ -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
|
data/spec/initializer_spec.rb
CHANGED
@@ -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
|
-
|
2
|
-
|
3
|
-
|
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
|
-
|
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
|