sunshine 1.0.0.pre → 1.0.0

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.
@@ -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