sunshine 1.0.0.pre → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,6 +2,12 @@
2
2
 
3
3
  * Improvements:
4
4
 
5
+ * Added auto_dependencies config to turn on/off auto installing things.
6
+
7
+ * Added healthcheck middleware support.
8
+
9
+ * Added support for Apache2 and its passenger implementation.
10
+
5
11
  * Removed all Atti-specific code for public release.
6
12
 
7
13
  * Bugfixes:
@@ -19,6 +19,7 @@ lib/sunshine/app.rb
19
19
  lib/sunshine/binder.rb
20
20
  lib/sunshine/crontab.rb
21
21
  lib/sunshine/daemon.rb
22
+ lib/sunshine/daemons/apache.rb
22
23
  lib/sunshine/daemons/ar_sendmail.rb
23
24
  lib/sunshine/daemons/delayed_job.rb
24
25
  lib/sunshine/daemons/nginx.rb
@@ -41,12 +42,14 @@ lib/sunshine/repos/rsync_repo.rb
41
42
  lib/sunshine/repos/svn_repo.rb
42
43
  lib/sunshine/server_app.rb
43
44
  lib/sunshine/shell.rb
45
+ templates/apache/apache.conf.erb
44
46
  templates/logrotate/logrotate.conf.erb
45
47
  templates/nginx/nginx.conf.erb
46
48
  templates/nginx/nginx_optimize.conf
47
49
  templates/nginx/nginx_proxy.conf
48
50
  templates/rainbows/rainbows.conf.erb
49
- templates/tasks/sunshine.rake
51
+ templates/sunshine/middleware/health.rb
52
+ templates/sunshine/sunshine.rake
50
53
  templates/unicorn/unicorn.conf.erb
51
54
  test/fixtures/app_configs/test_app.yml
52
55
  test/fixtures/sunshine_test/test_upload
@@ -56,6 +59,7 @@ test/test_helper.rb
56
59
  test/unit/test_app.rb
57
60
  test/unit/test_binder.rb
58
61
  test/unit/test_crontab.rb
62
+ test/unit/test_daemon.rb
59
63
  test/unit/test_git_repo.rb
60
64
  test/unit/test_healthcheck.rb
61
65
  test/unit/test_nginx.rb
@@ -15,13 +15,35 @@ module Sunshine
15
15
  # and optionally an accompanying message.
16
16
 
17
17
  def self.exec argv, config
18
- template_rakefile = "#{Sunshine::ROOT}/templates/tasks/sunshine.rake"
19
18
 
20
- target_rakefile = config['rakefile']
19
+ copy_rakefile(config['rakefile']) if config.has_key? 'rakefile'
20
+ copy_middleware(config['middleware']) if config.has_key? 'middleware'
21
21
 
22
- FileUtils.cp template_rakefile, target_rakefile
22
+ return true
23
+ end
24
+
25
+
26
+ ##
27
+ # Copy template rakefile to specified location.
23
28
 
24
- return true, "Copied Sunshine template rakefile to #{target_rakefile}"
29
+ def self.copy_rakefile path
30
+ template_rakefile = "#{Sunshine::ROOT}/templates/sunshine/sunshine.rake"
31
+
32
+ FileUtils.cp template_rakefile, path
33
+
34
+ puts "Copied Sunshine template rakefile to #{path}"
35
+ end
36
+
37
+
38
+ ##
39
+ # Copy middleware to specified location.
40
+
41
+ def self.copy_middleware path
42
+ middleware_dir = "#{Sunshine::ROOT}/templates/sunshine/middleware/."
43
+
44
+ FileUtils.cp_r middleware_dir, path
45
+
46
+ puts "Copied Sunshine middleware to #{path}"
25
47
  end
26
48
 
27
49
 
@@ -83,6 +105,12 @@ Sunshine is an object oriented deploy tool for rack applications.
83
105
  options['rakefile'] = path || File.join(Dir.pwd, "sunshine.rake")
84
106
  end
85
107
 
108
+ opt.on('--middleware [PATH]',
109
+ 'Copy Sunshine rack middleware files.') do |path|
110
+ options['middleware'] =
111
+ path || File.join(Dir.pwd, ".")
112
+ end
113
+
86
114
  opt.separator nil
87
115
  opt.separator "For more help on sunshine commands, "+
88
116
  "use '#{opt.program_name} COMMAND --help'"
@@ -72,7 +72,7 @@ module Sunshine
72
72
 
73
73
  ##
74
74
  # Sunshine version.
75
- VERSION = '1.0.0.pre'
75
+ VERSION = '1.0.0'
76
76
 
77
77
 
78
78
  ##
@@ -91,6 +91,14 @@ module Sunshine
91
91
  end
92
92
 
93
93
 
94
+ ##
95
+ # Automatically install dependencies as needed. Defaults to true.
96
+ # Overridden in the ~/.sunshine config file or at setup time.
97
+
98
+ def self.auto_dependencies?
99
+ @config['auto_dependencies']
100
+ end
101
+
94
102
  ##
95
103
  # Returns the main Sunshine dependencies library.
96
104
 
@@ -101,8 +109,8 @@ module Sunshine
101
109
 
102
110
  ##
103
111
  # The default directory where apps should be deployed to:
104
- # '/var/www' by default. Overridden in the ~/.sunshine config file.
105
- # See also App#deploy_path.
112
+ # '/var/www' by default. Overridden in the ~/.sunshine config file
113
+ # or at setup time. See also App#deploy_path.
106
114
 
107
115
  def self.web_directory
108
116
  @config['web_directory']
@@ -226,7 +234,8 @@ module Sunshine
226
234
  'deploy_env' => :development,
227
235
  'auto' => false,
228
236
  'max_deploy_versions' => 5,
229
- 'web_directory' => '/var/www'
237
+ 'web_directory' => '/var/www',
238
+ 'auto_dependencies' => true
230
239
  }
231
240
 
232
241
  ##
@@ -361,6 +370,7 @@ module Sunshine
361
370
 
362
371
  require 'sunshine/daemon'
363
372
  require 'sunshine/daemons/server'
373
+ require 'sunshine/daemons/apache'
364
374
  require 'sunshine/daemons/nginx'
365
375
  require 'sunshine/daemons/unicorn'
366
376
  require 'sunshine/daemons/rainbows'
@@ -342,6 +342,10 @@ module Sunshine
342
342
  shell.expand_path path
343
343
  end
344
344
 
345
+ binder.set :target_server do
346
+ target.server_name || server_name
347
+ end
348
+
345
349
  binder
346
350
  end
347
351
 
@@ -0,0 +1,37 @@
1
+ module Sunshine
2
+
3
+ ##
4
+ # A wrapper for configuring the apache2 server.
5
+
6
+ class Apache < Server
7
+
8
+ def initialize app, options={}
9
+ super
10
+
11
+ @bin = options[:bin] || 'apachectl'
12
+
13
+ @sudo = options[:sudo] || @port < 1024
14
+
15
+ @sigkill = 'WINCH'
16
+
17
+ # TODO: have a separate max_clients and processes
18
+ @max_clients = options[:max_clients] || options[:processes] || 128
19
+
20
+ @dep_name = options[:dep_name] ||
21
+ use_passenger? ? 'passenger-apache' : 'apache2'
22
+ end
23
+
24
+
25
+ def start_cmd
26
+ "#{@bin} -f #{self.config_file_path} -E #{log_file :stderr}"
27
+ end
28
+
29
+
30
+ def setup
31
+ super do |server_app, binder|
32
+ binder.set :max_clients, @max_clients
33
+ yield(server_app, binder) if block_given?
34
+ end
35
+ end
36
+ end
37
+ end
@@ -8,97 +8,15 @@ module Sunshine
8
8
  def initialize app, options={}
9
9
  super
10
10
 
11
- @sudo ||= @port < 1024
11
+ @sudo = options[:sudo] || @port < 1024
12
12
 
13
- @dep_name = use_passenger? ? 'passenger-nginx' : 'nginx'
13
+ @dep_name = options[:dep_name] ||
14
+ use_passenger? ? 'passenger-nginx' : 'nginx'
14
15
  end
15
16
 
16
17
 
17
18
  def start_cmd
18
19
  "#{@bin} -c #{self.config_file_path}"
19
20
  end
20
-
21
-
22
- def stop_cmd
23
- cmd = "test -f #{@pid} && kill -QUIT $(cat #{@pid})"+
24
- " || echo 'No #{@name} process to stop for #{@app.name}';"
25
- cmd << "sleep 2 ; rm -f #{@pid};"
26
- end
27
-
28
-
29
- def setup
30
- super do |server_app, binder|
31
-
32
- binder.forward :use_passenger?
33
-
34
- binder.set :passenger_root do
35
- passenger_root server_app.shell
36
- end
37
-
38
- binder.set :nginx_conf_path do
39
- nginx_bin = server_app.shell.call "which nginx"
40
- File.join File.dirname(nginx_bin), '..', 'conf'
41
- end
42
-
43
- yield(server_app, binder) if block_given?
44
- end
45
- end
46
-
47
-
48
- ##
49
- # Check if passenger is required to run the application.
50
- # Returns true if the server's target is a Sunshine::App
51
-
52
- def use_passenger?
53
- Sunshine::App === @target
54
- end
55
-
56
-
57
- ##
58
- # Gets the root of the installer passenger gem.
59
-
60
- def passenger_root shell
61
- str = shell.call "gem list passenger -d"
62
- version = $1 if str =~ /passenger\s\((.*)\)$/
63
- gempath = $1 if str =~ /Installed\sat:\s(.*)$/
64
-
65
- return unless version && gempath
66
-
67
- File.join(gempath, "gems/passenger-#{version}")
68
- end
69
-
70
-
71
- ##
72
- # Run passenger installation for nginx
73
-
74
- def setup_passenger server_app
75
- server_app.install_deps 'passenger'
76
-
77
- server_app.shell.call \
78
- 'passenger-install-nginx-module --auto --auto-download',
79
- :sudo => true do |stream, data, inn|
80
-
81
- if data =~ /Please specify a prefix directory \[(.*)\]:/
82
-
83
- dir = $1
84
- inn.puts dir
85
-
86
- required_dirs = [
87
- File.join(dir, 'fastcgi_temp'),
88
- File.join(dir, 'proxy_temp')
89
- ]
90
-
91
- server_app.shell.call \
92
- "mkdir -p #{required_dirs.join(" ")}", :sudo => true
93
-
94
- error_log = File.join(dir, "logs/error.log")
95
-
96
- server_app.shell.call \
97
- "touch #{error_log} && chmod a+rw #{error_log}", :sudo => true
98
-
99
- server_app.add_shell_paths File.join(dir, 'sbin')
100
- end
101
- end
102
- end
103
21
  end
104
22
  end
@@ -17,6 +17,7 @@ module Sunshine
17
17
 
18
18
 
19
19
  attr_reader :server_name, :port
20
+ attr_accessor :sigkill
20
21
 
21
22
 
22
23
  # Server objects need only an App object to be instantiated.
@@ -35,8 +36,67 @@ module Sunshine
35
36
 
36
37
  super app, options
37
38
 
38
- @port = options[:port] || 80
39
- @server_name = options[:server_name]
39
+ @port = options[:port] || 80
40
+ @server_name = options[:server_name]
41
+ @sigkill = 'QUIT'
42
+ @supports_rack = false
43
+ end
44
+
45
+
46
+ ##
47
+ # Check if passenger is required to run the application.
48
+ # Returns true if the server's target is a Sunshine::App
49
+
50
+ def use_passenger?
51
+ Sunshine::App === @target && !supports_rack?
52
+ end
53
+
54
+
55
+ ##
56
+ # Gets the root of the installer passenger gem.
57
+
58
+ def self.passenger_root shell
59
+ str = shell.call "gem list passenger -d"
60
+ version = $1 if str =~ /passenger\s\((.*)\)$/
61
+ gempath = $1 if str =~ /Installed\sat:\s(.*)$/
62
+
63
+ return unless version && gempath
64
+
65
+ File.join(gempath, "gems/passenger-#{version}")
66
+ end
67
+
68
+
69
+ ##
70
+ # Add passenger information to the binder at setup time.
71
+
72
+ def setup
73
+ super do |server_app, binder|
74
+
75
+ binder.forward :use_passenger?
76
+
77
+ binder.set :passenger_root do
78
+ Server.passenger_root server_app.shell
79
+ end
80
+
81
+ yield(server_app, binder) if block_given?
82
+ end
83
+ end
84
+
85
+
86
+ ##
87
+ # Default server stop command.
88
+
89
+ def stop_cmd
90
+ "test -f #{@pid} && kill -#{@sigkill} $(cat #{@pid}) && sleep 1 && "+
91
+ "rm -f #{@pid} || echo 'No #{@name} process to stop for #{@app.name}';"
92
+ end
93
+
94
+
95
+ ##
96
+ # Defines if this server supports interfacing with rack.
97
+
98
+ def supports_rack?
99
+ @supports_rack
40
100
  end
41
101
 
42
102
 
@@ -7,7 +7,10 @@ module Sunshine
7
7
 
8
8
  def initialize app, options={}
9
9
  super
10
+
10
11
  @timeout = options[:timeout] || 3.0
12
+
13
+ @supports_rack = true
11
14
  end
12
15
 
13
16
 
@@ -15,12 +18,5 @@ module Sunshine
15
18
  "cd #{@app.current_path} && #{@bin} -D -E"+
16
19
  " #{@app.deploy_env} -p #{@port} -c #{self.config_file_path};"
17
20
  end
18
-
19
-
20
- def stop_cmd
21
- "test -f #{@pid} && kill -QUIT $(cat #{@pid})"+
22
- " || echo 'No #{@name} process to stop for #{@app.name}';"+
23
- "sleep 2; rm -f #{@pid};"
24
- end
25
21
  end
26
22
  end
@@ -4,14 +4,17 @@
4
4
  #class Sunshine::Dependencies < Settler
5
5
  Sunshine.dependencies.instance_eval do
6
6
 
7
- yum 'tpkg'
8
-
9
7
  apt 'svn', :pkg => 'subversion'
10
8
  yum 'svn', :pkg => 'subversion'
11
9
 
12
10
  apt 'git', :pkg => 'git-core'
13
11
  yum 'git', :pkg => 'git-core'
14
12
 
13
+ yum 'httpd-devel'
14
+
15
+ apt 'apache2', :pkg => 'apache2-mpm-prefork'
16
+ yum 'apache2', :pkg => 'httpd', :requires => 'httpd-devel'
17
+
15
18
  apt 'nginx'
16
19
  yum 'nginx'
17
20
 
@@ -53,19 +56,16 @@ Sunshine.dependencies.instance_eval do
53
56
  yum 'sqlite-devel'
54
57
 
55
58
 
56
- # Define gems used by Sunshine
59
+ ##
60
+ # Define phusion passenger dependencies
57
61
 
58
- gem 'bundler', :version => ">=0.9"
59
-
60
- gem 'isolate', :version => ">=1.3.0"
62
+ gem 'passenger', :version => ">=2.2.11"
61
63
 
62
- gem 'rake', :version => ">=0.8"
64
+ dependency 'passenger-nginx' do
65
+ requires 'passenger'
63
66
 
64
- gem 'passenger-nginx', :pkg => 'passenger' do
65
67
  install do |shell, sudo|
66
68
 
67
- shell.call "gem install passenger --no-ri --no-rdoc", :sudo => sudo
68
-
69
69
  shell.call 'passenger-install-nginx-module --auto --auto-download',
70
70
  :sudo => true do |stream, data, inn|
71
71
 
@@ -86,8 +86,38 @@ Sunshine.dependencies.instance_eval do
86
86
  end
87
87
  end
88
88
  end
89
+
90
+
91
+ check do |shell, sudo|
92
+ shell.call("nginx -V 2>&1") =~ /gems\/passenger-\d+(\.\d+)+\/ext\/nginx/
93
+ end
94
+ end
95
+
96
+
97
+ dependency 'passenger-apache' do
98
+ requires 'passenger', 'apache2'
99
+
100
+ install 'passenger-install-apache2-module --auto'
101
+
102
+ check do |shell, sudo|
103
+ passenger_dir = Server.passenger_root shell
104
+ passenger_mod = File.join passenger_dir, 'ext/apache2/mod_passenger.so'
105
+
106
+ shell.call("test -f #{passenger_mod}", :sudo => true) &&
107
+ shell.call("apachectl -v")
108
+ end
89
109
  end
90
110
 
111
+
112
+ ##
113
+ # Define gems used by Sunshine
114
+
115
+ gem 'bundler', :version => ">=0.9"
116
+
117
+ gem 'isolate', :version => ">=1.3.0"
118
+
119
+ gem 'rake', :version => ">=0.8"
120
+
91
121
  gem 'geminstaller', :version => ">=0.5"
92
122
 
93
123
  gem 'unicorn', :version => ">=0.9"
@@ -4,6 +4,21 @@ module Sunshine
4
4
  # Healthcheck objects handle enabling and disabling health checking for
5
5
  # load balancers by touching health.enabled and health.disabled files on
6
6
  # an app's shell.
7
+ #
8
+ # If you would like to use Sunshine's healthcheck rack middleware, use
9
+ # the following command:
10
+ # sunshine --middleware your_middleware_dir
11
+ #
12
+ # Then simply specify the following in your config.ru:
13
+ # require 'your_middleware_dir/health'
14
+ # use Sunshine::Health
15
+ #
16
+ # Sunshine::Health supports the following options:
17
+ # :uri_path:: The path that healthcheck will be used on.
18
+ # :health_file:: The file to check for health.
19
+ #
20
+ # use SunshineHealth, :uri_path => "/health.txt",
21
+ # :health_file => "health.txt"
7
22
 
8
23
  class Healthcheck
9
24
 
@@ -57,7 +57,7 @@ module Sunshine
57
57
  end
58
58
 
59
59
 
60
- attr_reader :url
60
+ attr_reader :url, :scm
61
61
 
62
62
  def initialize url, options={}
63
63
  @scm = self.class.name.split("::").last.sub('Repo', '').downcase
@@ -78,9 +78,6 @@ module Sunshine
78
78
  Sunshine.logger.info @scm,
79
79
  "Checking out to #{shell.host} #{path}" do
80
80
 
81
- Sunshine.dependencies.install @scm, :call => shell if
82
- Sunshine.dependencies.exist? @scm
83
-
84
81
  shell.call "test -d #{path} && rm -rf #{path} || echo false"
85
82
  shell.call "mkdir -p #{path}"
86
83
 
@@ -142,11 +142,11 @@ module Sunshine
142
142
  end
143
143
 
144
144
 
145
-
146
145
  ##
147
146
  # Checks out the app's codebase to the checkout path.
148
147
 
149
148
  def checkout_repo repo
149
+ install_deps repo.scm
150
150
  @info[:scm] = repo.checkout_to self.checkout_path, @shell
151
151
  end
152
152
 
@@ -257,8 +257,11 @@ module Sunshine
257
257
 
258
258
  ##
259
259
  # Install dependencies previously defined in Sunshine.dependencies.
260
+ # Will not execute if Sunshine.auto_dependencies? is false.
260
261
 
261
262
  def install_deps(*deps)
263
+ return unless Sunshine.auto_dependencies?
264
+
262
265
  options = {:call => @shell, :prefer => pkg_manager}
263
266
  options.merge! deps.delete_at(-1) if Hash === deps.last
264
267
 
@@ -0,0 +1,54 @@
1
+ LoadModule log_config_module modules/mod_log_config.so
2
+ LoadModule authz_host_module modules/mod_authz_host.so
3
+
4
+ ErrorLog <%= expand_path log_file(:stderr) %>
5
+ TransferLog <%= expand_path log_file(:stdout) %>
6
+
7
+ <% if use_passenger? %>
8
+ LoadModule passenger_module <%= passenger_root %>/ext/apache2/mod_passenger.so
9
+
10
+ PassengerRuby <%= shell.call "which ruby" %>
11
+ PassengerRoot <%= passenger_root %>
12
+ PassengerMaxPoolSize <%= processes %>
13
+ <% end %>
14
+
15
+ <% unless Sunshine::App === target %>
16
+ LoadModule proxy_module modules/mod_proxy.so
17
+ LoadModule proxy_connect_module modules/mod_proxy_connect.so
18
+ LoadModule proxy_http_module modules/mod_proxy_http.so
19
+ <% end %>
20
+
21
+
22
+ PidFile <%= expand_path pid %>
23
+ MaxClients <%= max_clients %>
24
+
25
+ <% if sudo == true || sudo == 'root' %>
26
+ User nobody
27
+ Group nobody
28
+ <% end %>
29
+
30
+ Listen <%= port %>
31
+
32
+
33
+ NameVirtualHost *:<%= port %>
34
+
35
+ <VirtualHost *:<%= port %>>
36
+ ServerName <%= server_name %>
37
+ ServerAlias www.<%= server_name %>
38
+
39
+ <% if Sunshine::App === target %>
40
+
41
+ DocumentRoot <%= expand_path app.current_path %>/public
42
+
43
+ <Directory <%= app.current_path %>/public>
44
+ Allow from all
45
+ Options -MultiViews
46
+ </Directory>
47
+
48
+ <% else %>
49
+
50
+ ProxyPass / http://0.0.0.0:<%= target.port %>/
51
+ ProxyPassReverse / http://0.0.0.0:<%= target.port %>/
52
+
53
+ <% end %>
54
+ </VirtualHost>
@@ -18,12 +18,12 @@ http {
18
18
 
19
19
  <% if use_passenger? %>
20
20
  passenger_root <%= passenger_root %>;
21
+ passenger_ruby <%= shell.call "which ruby" %>;
21
22
  <% end %>
22
23
 
23
24
  client_body_temp_path <%= darwin ? '/var/tmp/nginx' : '/dev/shm' %>;
24
25
  proxy_temp_path <%= darwin ? '/var/tmp/nginx' : '/dev/shm' %>;
25
26
 
26
- include <%= File.join nginx_conf_path, 'mime.types' %>;
27
27
  default_type application/octet-stream;
28
28
 
29
29
  log_format sunshine '$remote_addr - $remote_user [$time_local] '
@@ -48,7 +48,7 @@ http {
48
48
  gzip_proxied any;
49
49
  gzip_types text/plain text/html text/css application/x-javascript application/xml application/xml+rss text/javascript;
50
50
 
51
- <% if target.is_a?(Sunshine::Server) %>
51
+ <% if Sunshine::Server === target %>
52
52
  upstream app_server {
53
53
  server 0:<%= target.port %> fail_timeout=<%= timeout %>;
54
54
  }
@@ -91,7 +91,7 @@ http {
91
91
  include <%= expand_path config_path %>/nginx_proxy.conf;
92
92
  expires -1;
93
93
 
94
- <% if target.is_a?(Sunshine::Server) %>
94
+ <% if Sunshine::Server === target %>
95
95
  if (!-f $request_filename) {
96
96
  proxy_pass http://app_server;
97
97
  break;
@@ -0,0 +1,58 @@
1
+ module Sunshine
2
+
3
+ class Health
4
+
5
+ ##
6
+ # Default healthcheck request path.
7
+
8
+ DEFAULT_REQUEST_PATH = '/_health'
9
+
10
+
11
+ ##
12
+ # The healthcheck-enabled file.
13
+
14
+ HEALTHCHECK_FILE = 'health.enabled'
15
+
16
+
17
+ ##
18
+ # Creates a new SunshineHealth middleware. Supported options are:
19
+ # :uri_path:: The path that healthcheck will be used on.
20
+ # :health_file:: The file to check for health.
21
+
22
+ def initialize app, options={}
23
+ @app = app
24
+ @uri_path = options[:uri_path] || DEFAULT_REQUEST_PATH
25
+ @healthcheck_file = options[:health_file] || HEALTHCHECK_FILE
26
+ end
27
+
28
+
29
+ def call env
30
+ check_health?(env) ? health_response : @app.call(env)
31
+ end
32
+
33
+
34
+ ##
35
+ # Given the rack env, do we need to perform a health check?
36
+
37
+ def check_health? env
38
+ env['REQUEST_PATH'] == @uri_path
39
+ end
40
+
41
+
42
+ ##
43
+ # Check if healthcheck is enabled.
44
+
45
+ def health_enabled?
46
+ File.file? @healthcheck_file
47
+ end
48
+
49
+
50
+ ##
51
+ # Get a rack response for the current health status.
52
+
53
+ def health_response
54
+ status, body = health_enabled? ? [200, "OK"] : [404, "404"]
55
+ [status, {'Content-Type' => 'text/html'}, body]
56
+ end
57
+ end
58
+ end
@@ -183,6 +183,8 @@ unless MockObject === Sunshine.shell
183
183
  Sunshine.shell.mock :write, :return => nil
184
184
  end
185
185
 
186
+ YAML.extend MockObject unless MockObject === YAML
187
+
186
188
  unless Sunshine::Dependency.include? MockObject
187
189
  Sunshine::Dependency.send(:include, MockObject)
188
190
  end
@@ -0,0 +1,33 @@
1
+ require 'test/test_helper'
2
+
3
+ class TestDaemon < Test::Unit::TestCase
4
+
5
+ def setup
6
+ mock_remote_shell_popen4
7
+ @app = Sunshine::App.new(TEST_APP_CONFIG_FILE).extend MockObject
8
+ @server_app = @app.server_apps.first.extend MockObject
9
+ @app.server_apps.first.shell.extend MockObject
10
+
11
+ use_remote_shell @server_app.shell
12
+ end
13
+
14
+
15
+ def test_missing_start_stop_cmd
16
+ daemon = Sunshine::Daemon.new @app
17
+
18
+ begin
19
+ daemon.start_cmd
20
+ raise "Should have thrown CriticalDeployError but didn't :("
21
+ rescue Sunshine::CriticalDeployError => e
22
+ assert_equal "@start_cmd undefined. Can't start daemon", e.message
23
+ end
24
+
25
+ begin
26
+ daemon.stop_cmd
27
+ raise "Should have thrown CriticalDeployError but didn't :("
28
+ rescue Sunshine::CriticalDeployError => e
29
+ assert_equal "@stop_cmd undefined. Can't stop daemon", e.message
30
+ end
31
+ end
32
+
33
+ end
@@ -22,6 +22,9 @@ passenger (2.2.4)
22
22
 
23
23
  Apache module for Ruby on Rails support.
24
24
  STR
25
+
26
+ @nginx_passenger_check =
27
+ "/opt/ruby-ypc/lib/ruby/gems/1.8/gems/passenger-2.2.11/ext/nginx"
25
28
  end
26
29
 
27
30
 
@@ -66,7 +69,10 @@ passenger (2.2.4)
66
69
 
67
70
  def test_setup_passenger
68
71
  ds = @passenger.app.server_apps.first.shell
69
- ds.set_mock_response 0, "gem list passenger -d" => [:out, @gemout]
72
+
73
+ ds.set_mock_response 0,
74
+ "gem list passenger -d" => [:out, @gemout],
75
+ "nginx -V 2>&1" => [:out, @nginx_passenger_check]
70
76
 
71
77
  @passenger.setup do |ds, binder|
72
78
  assert binder.sudo
@@ -92,16 +98,14 @@ passenger (2.2.4)
92
98
 
93
99
  ## Helper methods
94
100
 
95
- def start_cmd svr, sudo=false
96
- sudo = sudo ? "sudo " : ""
97
- "#{sudo}#{svr.bin} -c #{svr.config_file_path}"
101
+ def start_cmd svr
102
+ "#{svr.bin} -c #{svr.config_file_path}"
98
103
  end
99
104
 
100
105
 
101
- def stop_cmd svr, sudo=false
102
- sudo = sudo ? "sudo " : ""
103
- cmd = "#{sudo }test -f #{svr.pid} && kill -QUIT $(cat #{svr.pid})"+
104
- " || echo 'No #{svr.name} process to stop for #{svr.app.name}';"
105
- cmd << "sleep 2 ; rm -f #{svr.pid};"
106
+ def stop_cmd svr
107
+ "test -f #{svr.pid} && kill -#{svr.sigkill} $(cat #{svr.pid}) && "+
108
+ "sleep 1 && rm -f #{svr.pid} || "+
109
+ "echo 'No #{svr.name} process to stop for #{svr.app.name}';"
106
110
  end
107
111
  end
@@ -173,25 +173,6 @@ class TestServer < Test::Unit::TestCase
173
173
  end
174
174
 
175
175
 
176
- def test_missing_start_stop_cmd
177
- server = Sunshine::Server.new @app
178
-
179
- begin
180
- server.start_cmd
181
- raise "Should have thrown CriticalDeployError but didn't :("
182
- rescue Sunshine::CriticalDeployError => e
183
- assert_equal "@start_cmd undefined. Can't start server", e.message
184
- end
185
-
186
- begin
187
- server.stop_cmd
188
- raise "Should have thrown CriticalDeployError but didn't :("
189
- rescue Sunshine::CriticalDeployError => e
190
- assert_equal "@stop_cmd undefined. Can't stop server", e.message
191
- end
192
- end
193
-
194
-
195
176
  def test_log_files
196
177
  @server.log_files :test_log => "/path/test_log.log",
197
178
  :another_test => "/path/another_test.log"
@@ -3,6 +3,7 @@ require 'test/test_helper'
3
3
  class TestSunshine < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
+ mock_yaml_load_file
6
7
  end
7
8
 
8
9
 
@@ -64,10 +65,10 @@ class TestSunshine < Test::Unit::TestCase
64
65
 
65
66
  assert_equal servers, Sunshine.setup['servers']
66
67
 
67
-
68
68
  Sunshine.run %w{thing1 thing2 -v}.unshift(name)
69
69
  servers = [Sunshine.shell]
70
70
 
71
+ args = [%w{thing1 thing2}, Sunshine.setup]
71
72
  assert_command cmd, args
72
73
 
73
74
  assert_equal servers, Sunshine.setup['servers']
@@ -154,4 +155,9 @@ class TestSunshine < Test::Unit::TestCase
154
155
  end
155
156
  end
156
157
 
158
+ def mock_yaml_load_file
159
+ YAML.mock :load_file, :args => [Sunshine::USER_CONFIG_FILE],
160
+ :return => Sunshine::DEFAULT_CONFIG
161
+ end
162
+
157
163
  end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sunshine
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: true
4
+ prerelease: false
5
5
  segments:
6
6
  - 1
7
7
  - 0
8
8
  - 0
9
- - pre
10
- version: 1.0.0.pre
9
+ version: 1.0.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Jeremie Castagna
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-03-23 00:00:00 -07:00
17
+ date: 2010-03-25 00:00:00 -07:00
19
18
  default_executable:
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
@@ -61,7 +60,7 @@ dependencies:
61
60
  type: :runtime
62
61
  version_requirements: *id003
63
62
  - !ruby/object:Gem::Dependency
64
- name: hoe
63
+ name: rubyforge
65
64
  prerelease: false
66
65
  requirement: &id004 !ruby/object:Gem::Requirement
67
66
  requirements:
@@ -69,11 +68,39 @@ dependencies:
69
68
  - !ruby/object:Gem::Version
70
69
  segments:
71
70
  - 2
71
+ - 0
72
72
  - 3
73
- - 3
74
- version: 2.3.3
73
+ version: 2.0.3
75
74
  type: :development
76
75
  version_requirements: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ name: gemcutter
78
+ prerelease: false
79
+ requirement: &id005 !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ segments:
84
+ - 0
85
+ - 5
86
+ - 0
87
+ version: 0.5.0
88
+ type: :development
89
+ version_requirements: *id005
90
+ - !ruby/object:Gem::Dependency
91
+ name: hoe
92
+ prerelease: false
93
+ requirement: &id006 !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ segments:
98
+ - 2
99
+ - 5
100
+ - 0
101
+ version: 2.5.0
102
+ type: :development
103
+ version_requirements: *id006
77
104
  description: |-
78
105
  Sunshine is an object-oriented api for rack application deployment.
79
106
 
@@ -116,6 +143,7 @@ files:
116
143
  - lib/sunshine/binder.rb
117
144
  - lib/sunshine/crontab.rb
118
145
  - lib/sunshine/daemon.rb
146
+ - lib/sunshine/daemons/apache.rb
119
147
  - lib/sunshine/daemons/ar_sendmail.rb
120
148
  - lib/sunshine/daemons/delayed_job.rb
121
149
  - lib/sunshine/daemons/nginx.rb
@@ -138,12 +166,14 @@ files:
138
166
  - lib/sunshine/repos/svn_repo.rb
139
167
  - lib/sunshine/server_app.rb
140
168
  - lib/sunshine/shell.rb
169
+ - templates/apache/apache.conf.erb
141
170
  - templates/logrotate/logrotate.conf.erb
142
171
  - templates/nginx/nginx.conf.erb
143
172
  - templates/nginx/nginx_optimize.conf
144
173
  - templates/nginx/nginx_proxy.conf
145
174
  - templates/rainbows/rainbows.conf.erb
146
- - templates/tasks/sunshine.rake
175
+ - templates/sunshine/middleware/health.rb
176
+ - templates/sunshine/sunshine.rake
147
177
  - templates/unicorn/unicorn.conf.erb
148
178
  - test/fixtures/app_configs/test_app.yml
149
179
  - test/fixtures/sunshine_test/test_upload
@@ -153,6 +183,7 @@ files:
153
183
  - test/unit/test_app.rb
154
184
  - test/unit/test_binder.rb
155
185
  - test/unit/test_crontab.rb
186
+ - test/unit/test_daemon.rb
156
187
  - test/unit/test_git_repo.rb
157
188
  - test/unit/test_healthcheck.rb
158
189
  - test/unit/test_nginx.rb
@@ -184,13 +215,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
184
215
  version: "0"
185
216
  required_rubygems_version: !ruby/object:Gem::Requirement
186
217
  requirements:
187
- - - ">"
218
+ - - ">="
188
219
  - !ruby/object:Gem::Version
189
220
  segments:
190
- - 1
191
- - 3
192
- - 1
193
- version: 1.3.1
221
+ - 0
222
+ version: "0"
194
223
  requirements: []
195
224
 
196
225
  rubyforge_project: sunshine
@@ -203,6 +232,7 @@ test_files:
203
232
  - test/unit/test_app.rb
204
233
  - test/unit/test_binder.rb
205
234
  - test/unit/test_crontab.rb
235
+ - test/unit/test_daemon.rb
206
236
  - test/unit/test_git_repo.rb
207
237
  - test/unit/test_healthcheck.rb
208
238
  - test/unit/test_nginx.rb