sunshine 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,17 @@
1
+ === 1.2.3 / 2011-02-11
2
+
3
+ * Bugfixes:
4
+
5
+ * Completely removed the Healthcheck implementation.
6
+
7
+ * Removed superfluous App#upload_tasks method.
8
+
9
+ * Changed Apache#bin from apachectl to apache2ctl.
10
+
11
+ * Made RsyncRepo available for remote checkout only.
12
+
13
+ * Lots of rdoc updates.
14
+
1
15
  === 1.2.2 / 2010-10-13
2
16
 
3
17
  * Bugfixes:
data/Manifest.txt CHANGED
@@ -33,7 +33,6 @@ lib/sunshine/daemons/unicorn.rb
33
33
  lib/sunshine/dependencies.rb
34
34
  lib/sunshine/dependency_lib.rb
35
35
  lib/sunshine/exceptions.rb
36
- lib/sunshine/healthcheck.rb
37
36
  lib/sunshine/output.rb
38
37
  lib/sunshine/package_managers/apt.rb
39
38
  lib/sunshine/package_managers/dependency.rb
@@ -53,7 +52,6 @@ templates/nginx/nginx.conf.erb
53
52
  templates/nginx/nginx_optimize.conf
54
53
  templates/nginx/nginx_proxy.conf
55
54
  templates/rainbows/rainbows.conf.erb
56
- templates/sunshine/middleware/health.rb
57
55
  templates/sunshine/sunshine.rake
58
56
  templates/thin/thin.conf.erb
59
57
  templates/unicorn/unicorn.conf.erb
@@ -68,7 +66,6 @@ test/unit/test_binder.rb
68
66
  test/unit/test_crontab.rb
69
67
  test/unit/test_daemon.rb
70
68
  test/unit/test_git_repo.rb
71
- test/unit/test_healthcheck.rb
72
69
  test/unit/test_nginx.rb
73
70
  test/unit/test_rainbows.rb
74
71
  test/unit/test_remote_shell.rb
data/README.txt CHANGED
@@ -26,19 +26,22 @@ Call sunshine to create the config file:
26
26
  Missing config file was created for you: /Users/jsmith/.sunshine
27
27
 
28
28
  ---
29
- web_directory: /var/www
30
- max_deploy_versions: 5
31
29
  auto_dependencies: true
30
+ deploy_env: :development
31
+ exception_behavior: :revert
32
+ exclude_paths: []
33
+ interactive: true
32
34
  level: info
33
- auto: false
35
+ max_deploy_versions: 5
34
36
  remote_checkouts: false
35
- deploy_env: :development
36
-
37
+ timeout: 300
38
+ sigint_behavior: :revert
39
+ web_directory: /srv/http
37
40
 
38
41
  You can either use sunshine by requiring the gem in your script, such as
39
42
  in a rakefile (which is more common):
40
43
 
41
- $ rake sunshine:deploy
44
+ $ rake sunshine:deploy env=qa
42
45
 
43
46
  Or you can also call built-in sunshine commands:
44
47
 
@@ -58,11 +61,11 @@ You have the deploy information and you need to do things involving that
58
61
  specific deploy. Rake tasks are great for that, and Sunshine comes with a
59
62
  template rake file that you can modify to fit your needs.
60
63
 
61
- You can copy the template rake file to lib/tasks/ by running:
62
- $ sunshine --rakefile lib/tasks/.
64
+ You can copy the template rake file to rake/ by running:
65
+ $ sunshine --rakefile rake/.
63
66
 
64
67
  If you open the file, you'll see a variety of tasks that handle deployment, to
65
- application start/stop/restart-ing, to health checks. Most likely, the two tasks
68
+ application start/stop/restart-ing, to status checks. Most likely, the two tasks
66
69
  you'll need to update are the :app (for instantiation) and the :deploy tasks.
67
70
 
68
71
  First off, if you're using rails, you'll probably want to update "task :app" to
@@ -110,12 +113,7 @@ to the @app.deploy block. Here's a sample of completed :app and :deploy tasks:
110
113
  And that's it! Try running your Sunshine rake tasks!
111
114
 
112
115
  rake sunshine:app # Instantiate Sunshine
113
- rake sunshine:db_migrate # Run db:migrate on remote :db servers
114
116
  rake sunshine:deploy # Deploy the app
115
- rake sunshine:health # Get the health state
116
- rake sunshine:health:disable # Turn off health check
117
- rake sunshine:health:enable # Turn on health check
118
- rake sunshine:health:remove # Remove health check
119
117
  rake sunshine:info # Get deployed app info
120
118
  rake sunshine:restart # Run the remote restart script
121
119
  rake sunshine:start # Run the remote start script
@@ -149,9 +147,9 @@ a block to its deploy method:
149
147
  Sunshine::App.deploy(options) do |app|
150
148
 
151
149
  app_server = Sunshine::Rainbows.new(app)
152
- app_server.restart
150
+ app_server.setup
153
151
 
154
- Sunshine::Nginx.new(app, :point_to => app_server).restart
152
+ Sunshine::Nginx.new(app, :point_to => app_server).setup
155
153
 
156
154
  end
157
155
 
@@ -177,7 +175,7 @@ using configuration files.
177
175
  The App::new methods support passing a path to a yaml config file:
178
176
 
179
177
  app = Sunshine::App.new("path/to/config.yml")
180
- app.deploy{|app| Sunshine::Rainbows.new(app).restart }
178
+ app.deploy{|app| Sunshine::Rainbows.new(app).setup }
181
179
 
182
180
 
183
181
  The yaml file can also be any IO stream who's output will parse to yaml.
@@ -188,7 +186,7 @@ information in one place:
188
186
  app = Sunshine::App.new
189
187
  app = Sunshine::App.new Sunshine::DATA
190
188
 
191
- app.deploy{|app| Sunshine::Rainbows.new(app).restart }
189
+ app.deploy{|app| Sunshine::Rainbows.new(app).setup }
192
190
 
193
191
  __END__
194
192
 
@@ -461,6 +459,21 @@ Note: You may notice that you can set a sudo config value on the Sunshine
461
459
  module. This is used for the default value of Sunshine::App#sudo and is passed
462
460
  along to an app's shells on instantiation.
463
461
 
462
+ ==== Servers
463
+
464
+ Because of how unix works with servers and ports, it's not uncommon to have to
465
+ run start/stop/restart server commands with upgraded permissions. This is true
466
+ for Apache and Nginx on ports below 1024. Due to this, servers automatically try
467
+ to adjust their permissions to run their commands correctly. Since servers
468
+ should run their commands consistantly, the only way to affect their sudo value
469
+ is on a server instance basis:
470
+
471
+ server = Nginx.new app, :sudo => nil # let the shell handle sudo
472
+
473
+ However, the above will most likely cause Nginx's start command to fail if
474
+ shell permissions don't allow running root processes.
475
+
476
+ Note: Servers will ONLY touch permissions if their port is smaller than 1024.
464
477
 
465
478
  ==== Dependencies
466
479
 
@@ -488,38 +501,27 @@ It can also be set on an individual basis:
488
501
  dep.install! :call => shell, :sudo => nil
489
502
 
490
503
 
491
- ==== Servers
492
-
493
- Because of how unix works with servers and ports, it's not uncommon to have to
494
- run start/stop/restart server commands with upgraded permissions. This is true
495
- for Apache and Nginx on ports below 1024. Due to this, servers automatically try
496
- to adjust their permissions to run their commands correctly. Since servers
497
- should run their commands consistantly, the only way to affect their sudo value
498
- is on a server instance basis:
499
-
500
- server = Nginx.new app, :sudo => nil # let the shell handle sudo
501
-
502
- However, the above will most likely cause Nginx's start command to fail if
503
- shell permissions don't allow running root processes.
504
-
505
- Note: Servers will ONLY touch permissions if their port is smaller than 1024.
506
-
507
-
508
504
  == Sunshine Configuration
509
505
 
510
506
  Aside from passing the sunshine command options, Sunshine can be configured
511
507
  both in the deploy script by calling Sunshine.setup and globally in the
512
508
  ~/.sunshine file. The following is a list of supported config keys:
513
509
 
514
- 'auto' -> Automate calls; fail instead of prompting the user;
515
- defaults to false.
516
-
517
510
  'auto_dependencies' -> Check and install missing deploy dependencies;
518
511
  defaults to true.
519
512
 
520
513
  'deploy_env' -> The default deploy environment to use;
521
514
  defaults to :development.
522
515
 
516
+ 'exception_behavior' -> The behavior called when an exception is raised during
517
+ a deploy; defaults to :revert.
518
+
519
+ 'exclude_paths' -> Paths to exclude in the checkout when deploying code
520
+ with via rsync; defaults to empty Array.
521
+
522
+ 'interactive' -> Automate calls; fail instead of prompting the user;
523
+ defaults to false.
524
+
523
525
  'level' -> Logger's debug level; defaults to 'info'.
524
526
 
525
527
  'max_deploy_versions' -> The maximum number of deploys to keep on a server;
@@ -530,10 +532,16 @@ defaults to false.
530
532
 
531
533
  'require' -> Require external ruby libs or gems; defaults to nil.
532
534
 
535
+ 'timeout' -> The amount of time in seconds for shells to wait with
536
+ no incoming data before timing out; defaults to 300.
537
+
538
+ 'sigint_behavior' -> The behavior called when a SIGINT is received during
539
+ a deploy; defaults to :revert.
540
+
533
541
  'trace' -> Show detailed output messages; defaults to false.
534
542
 
535
543
  'web_directory' -> Path to where apps should be deployed to;
536
- defaults to '/var/www'.
544
+ defaults to '/srv/http'.
537
545
 
538
546
 
539
547
  == Deployed Application Control
@@ -541,13 +549,12 @@ defaults to '/var/www'.
541
549
  Sunshine has a variety of commands that allow simple control of
542
550
  remote or locally deployed applications. These include start, stop, restart
543
551
  actions to be taken application-wide, as well as querying for the
544
- health and state of the app:
552
+ state of the app:
545
553
 
546
554
  Examples:
547
555
  sunshine run deploy_script.rb
548
556
  sunshine restart myapp -r user@server.com,user@host.com
549
- sunshine list myapp myotherapp --health -r user@server.com
550
- sunshine list myapp --status
557
+ sunshine list myapp myotherapp --status -r user@server.com
551
558
 
552
559
  The Sunshine commands are as follows:
553
560
  add Register an app with sunshine
@@ -603,7 +610,7 @@ This is true for the following commands:
603
610
 
604
611
  (The MIT License)
605
612
 
606
- Copyright (c) 2010
613
+ Copyright (c) 2010 At&t Interactive
607
614
 
608
615
  Permission is hereby granted, free of charge, to any person obtaining
609
616
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -37,10 +37,10 @@ Hoe.plugin :isolate
37
37
 
38
38
  Hoe.spec 'sunshine' do |p|
39
39
  developer('Jeremie Castagna', 'jcastagna@attinteractive.com')
40
- self.extra_deps << ['open4', '>= 1.0.1']
41
- self.extra_deps << ['rainbow', '>= 1.0.4']
42
- self.extra_deps << ['highline', '>= 1.5.1']
43
- self.extra_deps << ['json', '>= 1.2.0']
40
+ self.extra_deps << ['open4', '~> 1.0.1']
41
+ self.extra_deps << ['rainbow', '~> 1.0.4']
42
+ self.extra_deps << ['highline', '~> 1.5.1']
43
+ self.extra_deps << ['json', '~> 1.2.0']
44
44
  end
45
45
 
46
46
  # vim: syntax=Ruby
data/bin/sunshine CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby -w
1
+ #!/usr/bin/env ruby
2
2
 
3
3
  begin
4
4
  require 'sunshine'
@@ -80,31 +80,4 @@ namespace :sunshine do
80
80
  task :info => :app do
81
81
  puts @app.deploy_details.to_yaml
82
82
  end
83
-
84
-
85
- desc "Get the health state"
86
- task :health => :app do
87
- puts @app.health.to_yaml
88
- end
89
-
90
-
91
- namespace :health do
92
-
93
- desc "Turn on health check"
94
- task :enable => :app do
95
- puts @app.health(:enable).to_yaml
96
- end
97
-
98
-
99
- desc "Turn off health check"
100
- task :disable => :app do
101
- puts @app.health(:disable).to_yaml
102
- end
103
-
104
-
105
- desc "Remove health check"
106
- task :remove => :app do
107
- puts @app.health(:remove).to_yaml
108
- end
109
- end
110
83
  end
data/lib/commands/list.rb CHANGED
@@ -11,8 +11,6 @@ module Sunshine
11
11
  # Options:
12
12
  # -s, --status Check if an app is running.
13
13
  # -d, --details Get details about the deployed apps.
14
- # -h, --health [STATUS] Set or get the healthcheck status.
15
- # (enable, disable, remove)
16
14
  # -f, --format FORMAT Set the output format (txt, yml, json)
17
15
  # -u, --user USER User to use for remote login. Use with -r
18
16
  # -r, --remote svr1,svr2 Run on one or more remote servers.
@@ -157,20 +155,6 @@ module Sunshine
157
155
  end
158
156
 
159
157
 
160
- ##
161
- # Get or set the healthcheck state.
162
- # Returns a response hash (see ListCommand#each_app).
163
-
164
- def health(*app_names)
165
- action = app_names.delete_at(0) if Symbol === app_names.first
166
-
167
- each_app(*app_names) do |server_app|
168
- server_app.health.send action if action
169
- server_app.health.status
170
- end
171
- end
172
-
173
-
174
158
  ##
175
159
  # Checks if the apps' pids are present.
176
160
  # Returns a response hash (see ListCommand#each_app).
@@ -313,14 +297,6 @@ Arguments:
313
297
  options['return'] = :details
314
298
  end
315
299
 
316
-
317
- vals = [:enable, :disable, :remove]
318
- desc = "Set or get the healthcheck status. (#{vals.join(", ")})"
319
-
320
- opt.on('-h', '--health [STATUS]', vals, desc) do |status|
321
- options['health'] = status.to_sym if status
322
- options['return'] = :health
323
- end
324
300
  end
325
301
  end
326
302
  end
data/lib/sunshine.rb CHANGED
@@ -4,7 +4,6 @@ require 'rainbow'
4
4
  require 'highline'
5
5
  require 'json'
6
6
 
7
- require 'yaml'
8
7
  require 'erb'
9
8
  require 'logger'
10
9
  require 'optparse'
@@ -12,6 +11,7 @@ require 'time'
12
11
  require 'fileutils'
13
12
  require 'tmpdir'
14
13
  require 'irb'
14
+ require 'yaml'
15
15
 
16
16
 
17
17
  # Turn off EOF tracking to be able to prompt on deploy exceptions.
@@ -25,7 +25,7 @@ module Sunshine
25
25
 
26
26
  ##
27
27
  # Sunshine version.
28
- VERSION = '1.2.2'
28
+ VERSION = '1.2.3'
29
29
 
30
30
  ##
31
31
  # Path to the list of installed sunshine apps.
@@ -42,14 +42,15 @@ module Sunshine
42
42
  ##
43
43
  # Default configuration.
44
44
  DEFAULT_CONFIG = {
45
- 'interactive' => true,
46
45
  'auto_dependencies' => true,
47
46
  'deploy_env' => :development,
48
47
  'exception_behavior' => :revert,
49
48
  'exclude_paths' => [],
49
+ 'interactive' => true,
50
50
  'level' => 'info',
51
51
  'max_deploy_versions' => 5,
52
52
  'remote_checkouts' => false,
53
+ 'threads_enabled' => true,
53
54
  'timeout' => 300,
54
55
  'sigint_behavior' => :revert,
55
56
  'web_directory' => '/srv/http'
@@ -217,6 +218,15 @@ module Sunshine
217
218
  end
218
219
 
219
220
 
221
+ ##
222
+ # Check if App objects should use threads when iterating over ServerApps.
223
+ # Defaults to true, overridden with the 'threads_enabled' config.
224
+
225
+ def self.use_threads?
226
+ @config['threads_enabled']
227
+ end
228
+
229
+
220
230
  ##
221
231
  # The default directory where apps should be deployed to:
222
232
  # '/var/www' by default. Overridden in the config.
@@ -259,15 +269,7 @@ module Sunshine
259
269
  # config file and exits if not present.
260
270
 
261
271
  def self.load_user_config
262
- unless File.file? USER_CONFIG_FILE
263
- File.open(USER_CONFIG_FILE, "w+"){|f| f.write DEFAULT_CONFIG.to_yaml}
264
-
265
- msg = "Missing config file was created for you: #{USER_CONFIG_FILE}\n\n"
266
- msg << DEFAULT_CONFIG.to_yaml
267
-
268
- self.exit 1, msg
269
- end
270
-
272
+ create_default_config!
271
273
  load_config_file USER_CONFIG_FILE
272
274
 
273
275
  @config['deploy_env'] =
@@ -280,6 +282,16 @@ module Sunshine
280
282
  @config
281
283
  end
282
284
 
285
+ def self.create_default_config!
286
+ unless File.file? USER_CONFIG_FILE
287
+ File.open(USER_CONFIG_FILE, "w+"){|f| f.write DEFAULT_CONFIG.to_yaml}
288
+
289
+ msg = "Missing config file was created for you: #{USER_CONFIG_FILE}\n\n"
290
+ msg << DEFAULT_CONFIG.to_yaml
291
+
292
+ self.exit 1, msg
293
+ end
294
+ end
283
295
 
284
296
  ##
285
297
  # Loads an array of libraries or gems.
@@ -423,8 +435,6 @@ module Sunshine
423
435
 
424
436
  require 'sunshine/crontab'
425
437
 
426
- require 'sunshine/healthcheck'
427
-
428
438
  require 'commands/default'
429
439
  require 'commands/list'
430
440
  require 'commands/add'
data/lib/sunshine/app.rb CHANGED
@@ -3,19 +3,34 @@ module Sunshine
3
3
  ##
4
4
  # App objects are the core of Sunshine deployment. The Sunshine paradygm
5
5
  # is to construct an app object, and run custom deploy code by passing
6
- # a block to its deploy method:
6
+ # a block to its deploy method. The following is the simplest way to
7
+ # instantiate an app:
8
+ #
9
+ # app = Sunshine::App.new :remote_shells => "deploy_server.com"
10
+ #
11
+ # By default, Sunshine will look in the pwd for scm information and will
12
+ # extract the app's name. The default root deploy path is specified by
13
+ # Sunshine.web_directory, in this case: "/srv/http/app_name".
14
+ #
15
+ # More complex setups may look like the following:
7
16
  #
8
17
  # someserver = Sunshine::RemoteShell.new "user@someserver.com",
9
18
  # :roles => [:web, :app]
10
19
  #
11
- # options = {
12
- # :name => 'myapp',
13
- # :repo => {:type => :svn, :url => 'svn://blah...'},
14
- # :root_path => '/usr/local/myapp',
15
- # :remote_shells => 'user@someserver.com'
16
- # }
20
+ # myapprepo = Sunshine::SvnRepo.new "svn://my_repo/myapp/tags/release"
17
21
  #
18
- # app = Sunshine::App.new(options)
22
+ # app = Sunshine::App.new :name => 'myapp',
23
+ # :repo => myapprepo,
24
+ # :root_path => '/usr/local/myapp',
25
+ # :remote_shells => someserver
26
+ #
27
+ # Note: The instantiation options :repo and :remote_shells support
28
+ # the same data format that their respective initialize methods support.
29
+ # The :remote_shells option also supports arrays of remote shell instance
30
+ # arguments.
31
+ #
32
+ # Once an App is instantiated it can be manipulated in a variety of ways,
33
+ # including deploying it:
19
34
  #
20
35
  # app.deploy do |app|
21
36
  #
@@ -26,36 +41,18 @@ module Sunshine
26
41
  # web_server.setup
27
42
  # end
28
43
  #
29
- # Multiple apps can be defined, and deployed from a single deploy script.
30
- # The constructor also supports passing a yaml file path:
31
- #
32
- # Sunshine::App.new("path/to/config.yml")
33
- #
34
- # Deployment can be expressed more concisely by calling App::deploy:
35
- #
36
- # App.deploy("path/to/config.yml") do |app|
37
- # Sunshine::Rainbows.new(app).setup
38
- # end
39
- #
40
- #
41
- # An App holds information about where to deploy an application to and
42
- # how to deploy it, as well as many convenience methods to setup and
43
- # manipulate the deployment process. Most of these methods support passing
44
- # remote shell find options:
44
+ # The constructor also supports reading multi-env configs fom a yaml file,
45
+ # which can also be the deploy script's DATA, to allow for concise,
46
+ # encapsulated deploy files:
45
47
  #
46
- # app.rake 'db:migrate', :role => :db
47
- # app.deploy :host => 'server1.com'
48
+ # # Load from an explicit yaml file:
49
+ # Sunshine::App.new "path/to/config.yml"
48
50
  #
49
- # See App#find for more information.
50
- #
51
- # App instantiation can be done in several ways:
52
- # App.new instantiation_hash
53
- # App.new "path/to/config.yml", optional_extra_hash
54
- # App.new #=> will attempt to load ruby's file DATA as yaml
51
+ # # Load from the yaml in the script file's DATA:
52
+ # Sunshine::App.new
55
53
  #
56
54
  # Yaml files must define settings on a per-environment basis. The default
57
- # environment will be used if the deploy_env is not found in the config.
58
- # Let's consider the following config:
55
+ # environment will be used as a base for all other environments:
59
56
  #
60
57
  # #config.yml:
61
58
  # ---
@@ -65,78 +62,23 @@ module Sunshine
65
62
  # :url: http://subversion/repo/tags/release-001
66
63
  # :remote_shells: dev.myserver.com
67
64
  #
68
- # :qa:
65
+ # qa:
69
66
  # :remote_shells:
70
67
  # - qa1.myserver.com
71
68
  # - qa2.myserver.com
72
69
  #
73
- # :qa_special:
74
- # :inherits: :qa
70
+ # qa_special:
71
+ # :inherits: qa
75
72
  # :root_path: /path/to/application
73
+ # :deploy_env: qa
76
74
  #
77
- # By default, environment definitions inherit the :default environment. In
78
- # this instance, :qa_special also inherits from :qa.
79
- # With the given config, I could setup the App instance as so:
80
- #
81
- # App.new "config.yml", :deploy_env => :development
82
- # # Note: by default, App will get the deploy_env value
83
- # # from Sunshine.deploy_env
84
- #
85
- # The above will simply load the default config. The following, however,
86
- # will load the :qa_special config which inherits from
87
- # both :qa and :default:
88
- #
89
- # App.new "config.yml", :deploy_env => :qa_special
90
- #
91
- #
92
- # Another way of instantiating an App is to pass it a hash. Unlike the yaml
93
- # config file, the hash is not on a per-environment basis and isexpected
94
- # to already have the correct values for the given environment.
95
- # The following is equivalent to loading the above :default environment:
96
- #
97
- # App.new :remote_shells => "dev.myserver.com",
98
- # :repo => {
99
- # :type => :svn,
100
- # :url => "http://subversion/repo/tags/release-001"
101
- # }
102
- #
103
- # In theory, the minimum amount of information required to instantiate
104
- # an app is the repo and remote_shells. If the repo option is omitted,
105
- # the App will attempt to detect if the pwd is a checkout out repo and
106
- # use that information. If you would like to deploy an application that
107
- # is not under source countrol, you may do so by using Sunshine::RsyncRepo,
108
- # or passing :rsync in your hash as your repo type.
109
- #
110
- #
111
- # Options supported by App.new are the following:
112
- #
113
- # :deploy_env:: String - specify the env to deploy with; defaults to
114
- # Sunshine#deploy_env.
115
- #
116
- # :deploy_name:: String - if you want to specify a name for your deploy and
117
- # checkout directory (affects the checkout_path); defaults to Time.now.to_i.
118
- #
119
- # :remote_shells:: String|Array|Sunshine::Shell - the shell(s) to use for
120
- # deployment. Accepts any single instance or array of a Sunshine::Shell
121
- # type instance or Sunshine::Shell instantiator-friendly arguments.
122
- #
123
- # :repo:: Hash|Sunshine::Repo - the scm and repo to use for deployment.
124
- # Accepts any hash that can be passed to Sunshine::Repo::new_of_type
125
- # or any Sunshine::Repo object.
126
- #
127
- # :root_path:: String - the absolute path the deployed application
128
- # should live in; defaults to "#{Sunshine.web_directory}/#{@name}".
129
- #
130
- # :shell_env:: Hash - environment variables to add to deploy shells.
131
- #
132
- # :sudo:: true|false|nil|String - which sudo value should be assigned to
133
- # deploy shells; defaults to Sunshine#sudo. For more information on using
134
- # sudo, see the Using Permissions section in README.txt.
75
+ # By default, App will get the deploy_env value from Sunshine.deploy_env, but
76
+ # it may also be passed in explicitely as an option.
135
77
 
136
78
  class App
137
79
 
138
80
  ##
139
- # Initialize and deploy an application.
81
+ # Initialize and deploy an application in a single step.
140
82
  # Takes any arguments supported by the constructor.
141
83
 
142
84
  def self.deploy(*args, &block)
@@ -156,6 +98,34 @@ module Sunshine
156
98
  # App.new instantiation_hash
157
99
  # App.new "path/to/config.yml", optional_extra_hash
158
100
  # App.new #=> will attempt to load ruby's file DATA as yaml
101
+ #
102
+ # Options supported are:
103
+ #
104
+ # :deploy_env:: String - specify the env to deploy with; defaults to
105
+ # Sunshine#deploy_env.
106
+ #
107
+ # :deploy_name:: String - if you want to specify a name for your deploy and
108
+ # checkout directory (affects the checkout_path); defaults to Time.now.to_i.
109
+ #
110
+ # :remote_checkout:: Boolean - when true, will checkout the codebase
111
+ # directly from the deploy servers; defaults to false.
112
+ #
113
+ # :remote_shells:: String|Array|Sunshine::Shell - the shell(s) to use for
114
+ # deployment. Accepts any single instance or array of a Sunshine::Shell
115
+ # type instance or Sunshine::Shell instantiator-friendly arguments.
116
+ #
117
+ # :repo:: Hash|Sunshine::Repo - the scm and repo to use for deployment.
118
+ # Accepts any hash that can be passed to Sunshine::Repo::new_of_type
119
+ # or any Sunshine::Repo object.
120
+ #
121
+ # :root_path:: String - the absolute path the deployed application
122
+ # should live in; defaults to "#{Sunshine.web_directory}/#{@name}".
123
+ #
124
+ # :shell_env:: Hash - environment variables to add to deploy shells.
125
+ #
126
+ # :sudo:: true|false|nil|String - which sudo value should be assigned to
127
+ # deploy shells; defaults to Sunshine#sudo. For more information on using
128
+ # sudo, see the Using Permissions section in README.txt.
159
129
 
160
130
  def initialize config_file=Sunshine::DATA, options={}
161
131
  options, config_file = config_file, Sunshine::DATA if Hash === config_file
@@ -199,8 +169,10 @@ module Sunshine
199
169
 
200
170
 
201
171
  ##
202
- # Call a command on specified server apps.
203
- # Supports any App#find and Shell#call options.
172
+ # Call a command on specified server apps. Returns an array of responses.
173
+ # Supports any App#find and Shell#call options:
174
+ # app.call "ls -1", :sudo => true, :host => "web.app.com"
175
+ # #=> [".\n..\ndir1", ".\n..\ndir1", ".\n..\ndir2"]
204
176
 
205
177
  def call cmd, options=nil, &block
206
178
  with_server_apps options, :msg => "Running #{cmd}" do |server_app|
@@ -210,7 +182,8 @@ module Sunshine
210
182
 
211
183
 
212
184
  ##
213
- # Connect server apps. Supports any App#find options.
185
+ # Start a persistant connection to app servers.
186
+ # Supports any App#find options.
214
187
 
215
188
  def connect options=nil
216
189
  Sunshine.logger.info :app, "Connecting..." do
@@ -248,7 +221,7 @@ module Sunshine
248
221
 
249
222
 
250
223
  ##
251
- # Disconnect server apps. Supports any App#find options.
224
+ # Disconnect from app servers. Supports any App#find options.
252
225
 
253
226
  def disconnect options=nil
254
227
  Sunshine.logger.info :app, "Disconnecting..." do
@@ -264,17 +237,19 @@ module Sunshine
264
237
  # call user's post-deploy code. Supports any App#find options.
265
238
  #
266
239
  # If the deploy fails or an exception is raised, it will attempt to
267
- # run the Sunshine.failed_deploy_behavior, which is set to :revert by
240
+ # run the Sunshine.exception_behavior, which is set to :revert by
268
241
  # default. However, this is not true of ssh connection failures.
269
242
  #
270
243
  # If the deploy is interrupted by a SIGINT, it will attempt to run
271
244
  # the Sunshine.sigint_behavior, which is set to :revert by default.
272
245
  #
273
- # Note: The deploy method will stop the former deploy just before
246
+ # The deploy method will stop the former deploy just before
274
247
  # symlink and the passed block is run.
275
248
  #
276
- # Note: Once deployment is complete, the deploy method will attempt to
277
- # run App#start.
249
+ # Once deployment is complete, the deploy method will attempt to
250
+ # run App#start! which will run any start script checked into
251
+ # App#scripts_path, or the start script that will have been generated
252
+ # by using Sunshine server setups.
278
253
 
279
254
  def deploy options=nil
280
255
 
@@ -302,8 +277,6 @@ module Sunshine
302
277
 
303
278
  run_post_user_lambdas
304
279
 
305
- health :enable
306
-
307
280
  build_control_scripts
308
281
  build_deploy_info_file
309
282
  build_crontab
@@ -325,9 +298,10 @@ module Sunshine
325
298
 
326
299
 
327
300
  ##
328
- # Handles SIGINTs and exceptions according to rules set by
329
- # Sunshine.sigint_behavior and Sunshine.exception_behavior
330
- # or with the override hooks App#on_sigint and App#on_exception.
301
+ # Runs the given block while handling SIGINTs and exceptions
302
+ # according to rules set by Sunshine.sigint_behavior and
303
+ # Sunshine.exception_behavior or with the override hooks
304
+ # App#on_sigint and App#on_exception.
331
305
 
332
306
  def interruptable options={}
333
307
  interrupt_trap =
@@ -446,8 +420,9 @@ module Sunshine
446
420
  ##
447
421
  # Symlink current directory to previous checkout and remove
448
422
  # the current deploy directory. Supports any App#find options.
423
+ # app.revert! :role => :web
449
424
 
450
- def revert!(options=nil)
425
+ def revert! options=nil
451
426
  with_server_apps options,
452
427
  :msg => "Reverting to previous deploy.",
453
428
  :send => :revert!
@@ -455,7 +430,7 @@ module Sunshine
455
430
 
456
431
 
457
432
  ##
458
- # Add paths the the shell $PATH env.
433
+ # Add paths the the shell $PATH env on all app shells.
459
434
 
460
435
  def add_shell_paths(*paths)
461
436
  path = @shell_env["PATH"] || "$PATH"
@@ -596,12 +571,14 @@ module Sunshine
596
571
  # Checks out the app's codebase to one or all deploy servers.
597
572
  # Supports all App#find options, plus:
598
573
  # :copy:: Bool - Checkout locally and rsync; defaults to false.
574
+ # :exclude:: String|Array - Exclude the specified paths during
575
+ # a deploy via copy.
599
576
 
600
577
  def checkout_codebase options=nil
601
578
  copy_option = options[:copy] if options
602
- exclude = options.delete(:exclude) if options
579
+ exclude = options.delete :exclude if options
603
580
 
604
- if @remote_checkout && !copy_option
581
+ if RsyncRepo === @repo || (@remote_checkout && !copy_option)
605
582
  with_server_apps options,
606
583
  :msg => "Checking out codebase (remotely)",
607
584
  :send => [:checkout_repo, @repo]
@@ -638,7 +615,8 @@ module Sunshine
638
615
 
639
616
 
640
617
  ##
641
- # Check if app has been deployed successfully.
618
+ # Check if app has been deployed successfully by checking the name of the
619
+ # deploy on every app server with the instance's deploy name.
642
620
 
643
621
  def deployed? options=nil
644
622
  with_server_apps options,
@@ -651,10 +629,11 @@ module Sunshine
651
629
 
652
630
 
653
631
  ##
654
- # Iterate over each server app.
632
+ # Iterate over each server app. Supports all App#find options.
633
+ # See Sunshine::ServerApp for more information.
655
634
 
656
- def each(options=nil, &block)
657
- server_apps = find(options)
635
+ def each options=nil, &block
636
+ server_apps = find options
658
637
  server_apps.each(&block)
659
638
  end
660
639
 
@@ -686,61 +665,6 @@ module Sunshine
686
665
  end
687
666
 
688
667
 
689
- ##
690
- # Decrypt a file using gpg. Allows all DeployServerDispatcher#find
691
- # options, plus:
692
- # :output:: str - the path the output file should go to
693
- # :passphrase:: str - the passphrase gpg should use
694
-
695
- def gpg_decrypt gpg_file, options={}
696
- options[:passphrase] ||=
697
- Sunshine.shell.ask("Enter gpg passphrase:") do |q|
698
- q.echo = false
699
- end
700
-
701
- with_server_apps options,
702
- :msg => "Gpg decrypt: #{gpg_file}",
703
- :send => [:gpg_decrypt, gpg_file, options]
704
- end
705
-
706
-
707
- ##
708
- # Gets or sets the healthcheck state. Returns a hash of host/state
709
- # pairs. State values are :enabled, :disabled, and :down. The method
710
- # argument can be omitted or take a value of :enable, :disable, or :remove:
711
- # app.health
712
- # #=> Returns the health status for all server_apps
713
- #
714
- # app.health :role => :web
715
- # #=> Returns the status of all server_apps of role :web
716
- #
717
- # app.health :enable
718
- # #=> Enables all health checking and returns the status
719
- #
720
- # app.health :disable, :role => :web
721
- # #=> Disables health checking for :web server_apps and returns the status
722
-
723
- def health method=nil, options=nil
724
- valid_methods = [:enable, :disable, :remove]
725
- options = method if options.nil? && Hash === method
726
-
727
- valid_method = valid_methods.include? method
728
-
729
- message = "#{method.to_s.capitalize[0..-2]}ing" if valid_method
730
- message ||= "Getting status of"
731
- message = "#{message} healthcheck"
732
-
733
- statuses = {}
734
- with_server_apps options, :msg => message do |server_app|
735
- server_app.health.send method if valid_method
736
-
737
- statuses[server_app.shell.host] = server_app.health.status
738
- end
739
-
740
- statuses
741
- end
742
-
743
-
744
668
  ##
745
669
  # Install dependencies defined as a Sunshine dependency object:
746
670
  # rake = Sunshine.dependencies.gem 'rake', :version => '~>0.8'
@@ -768,6 +692,7 @@ module Sunshine
768
692
 
769
693
  ##
770
694
  # Creates the required application directories.
695
+ # Supports all App#find options.
771
696
 
772
697
  def make_app_directories options=nil
773
698
  with_server_apps options,
@@ -778,10 +703,11 @@ module Sunshine
778
703
 
779
704
  ##
780
705
  # Assign the prefered package manager to all server_apps:
781
- # app.prefer_pkg_manager Settler::Yum
706
+ # app.prefer_pkg_manager Sunshine::Yum
782
707
  #
783
708
  # Package managers are typically detected automatically by each
784
709
  # individual server_apps.
710
+ # Supports all App#find options.
785
711
 
786
712
  def prefer_pkg_manager pkg_manager, options=nil
787
713
  with_server_apps options,
@@ -791,6 +717,7 @@ module Sunshine
791
717
 
792
718
  ##
793
719
  # Run a rake task on any or all deploy servers.
720
+ # Supports all App#find options.
794
721
 
795
722
  def rake command, options=nil
796
723
  with_server_apps options,
@@ -801,6 +728,7 @@ module Sunshine
801
728
 
802
729
  ##
803
730
  # Adds the app to the deploy servers deployed-apps list.
731
+ # Supports all App#find options.
804
732
 
805
733
  def register_as_deployed options=nil
806
734
  with_server_apps options,
@@ -814,6 +742,7 @@ module Sunshine
814
742
  # remove_cronjob "reboot", :role => :web
815
743
  # remove_cronjob :all
816
744
  # #=> deletes all cronjobs related to this app
745
+ # Supports all App#find options.
817
746
 
818
747
  def remove_cronjob name, options=nil
819
748
  with_server_apps options,
@@ -830,6 +759,7 @@ module Sunshine
830
759
  ##
831
760
  # Removes old deploys from the checkout_dir
832
761
  # based on Sunshine's max_deploy_versions.
762
+ # Supports all App#find options.
833
763
 
834
764
  def remove_old_deploys options=nil
835
765
  with_server_apps options,
@@ -841,7 +771,7 @@ module Sunshine
841
771
  ##
842
772
  # Run the restart script of a deployed app on the specified
843
773
  # deploy servers.
844
- # Post-deploy only.
774
+ # Post-deploy only. Supports all App#find options.
845
775
 
846
776
  def restart options=nil
847
777
  with_server_apps options,
@@ -853,7 +783,7 @@ module Sunshine
853
783
  ##
854
784
  # Run the restart script of a deployed app on the specified
855
785
  # deploy servers. Raises an exception on failure.
856
- # Post-deploy only.
786
+ # Post-deploy only. Supports all App#find options.
857
787
 
858
788
  def restart! options=nil
859
789
  with_server_apps options,
@@ -863,7 +793,7 @@ module Sunshine
863
793
 
864
794
 
865
795
  ##
866
- # Runs bundler on deploy servers.
796
+ # Runs bundler on deploy servers. Supports all App#find options.
867
797
 
868
798
  def run_bundler options=nil
869
799
  with_server_apps options,
@@ -873,7 +803,7 @@ module Sunshine
873
803
 
874
804
 
875
805
  ##
876
- # Runs GemInstaller on deploy servers.
806
+ # Runs GemInstaller on deploy servers. Supports all App#find options.
877
807
 
878
808
  def run_geminstaller options=nil
879
809
  with_server_apps options,
@@ -896,7 +826,7 @@ module Sunshine
896
826
  ##
897
827
  # Run the given script of a deployed app on the specified
898
828
  # deploy servers.
899
- # Post-deploy only.
829
+ # Post-deploy only. Supports all App#find options.
900
830
 
901
831
  def run_script name, options=nil
902
832
  with_server_apps options,
@@ -908,7 +838,7 @@ module Sunshine
908
838
  ##
909
839
  # Run the given script of a deployed app on the specified
910
840
  # deploy servers. Raises an exception on failure.
911
- # Post-deploy only.
841
+ # Post-deploy only. Supports all App#find options.
912
842
 
913
843
  def run_script! name, options=nil
914
844
  with_server_apps options,
@@ -919,6 +849,7 @@ module Sunshine
919
849
 
920
850
  ##
921
851
  # Run a sass task on any or all deploy servers.
852
+ # Supports all App#find options.
922
853
 
923
854
  def sass *sass_names
924
855
  options = sass_names.delete_at(-1) if Hash === sass_names.last
@@ -932,13 +863,14 @@ module Sunshine
932
863
  ##
933
864
  # Set and return the remote shell env variables.
934
865
  # Also assigns shell environment to the app's deploy servers.
866
+ # Supports all App#find options.
935
867
 
936
- def shell_env env_hash=nil
868
+ def shell_env env_hash=nil, options=nil
937
869
  env_hash ||= {}
938
870
 
939
871
  @shell_env.merge!(env_hash)
940
872
 
941
- with_server_apps :all,
873
+ with_server_apps options,
942
874
  :no_threads => true,
943
875
  :no_session => true,
944
876
  :msg => "Shell env: #{@shell_env.inspect}" do |server_app|
@@ -952,7 +884,7 @@ module Sunshine
952
884
  ##
953
885
  # Run the start script of a deployed app on the specified
954
886
  # deploy servers.
955
- # Post-deploy only.
887
+ # Post-deploy only. Supports all App#find options.
956
888
 
957
889
  def start options=nil
958
890
  with_server_apps options,
@@ -964,7 +896,7 @@ module Sunshine
964
896
  ##
965
897
  # Run the start script of a deployed app on the specified
966
898
  # deploy servers. Raises an exception on failure.
967
- # Post-deploy only.
899
+ # Post-deploy only. Supports all App#find options.
968
900
 
969
901
  def start! options=nil
970
902
  with_server_apps options,
@@ -975,7 +907,7 @@ module Sunshine
975
907
 
976
908
  ##
977
909
  # Get a hash of which deploy server apps are :running or :down.
978
- # Post-deploy only.
910
+ # Post-deploy only. Supports all App#find options.
979
911
 
980
912
  def status options=nil
981
913
  statuses = {}
@@ -991,7 +923,7 @@ module Sunshine
991
923
  ##
992
924
  # Run the stop script of a deployed app on the specified
993
925
  # deploy servers.
994
- # Post-deploy only.
926
+ # Post-deploy only. Supports all App#find options.
995
927
 
996
928
  def stop options=nil
997
929
  with_server_apps options,
@@ -1003,7 +935,7 @@ module Sunshine
1003
935
  ##
1004
936
  # Run the stop script of a deployed app on the specified
1005
937
  # deploy servers. Raises an exception on failure.
1006
- # Post-deploy only.
938
+ # Post-deploy only. Supports all App#find options.
1007
939
 
1008
940
  def stop! options=nil
1009
941
  with_server_apps options,
@@ -1013,7 +945,7 @@ module Sunshine
1013
945
 
1014
946
 
1015
947
  ##
1016
- # Use sudo on deploy servers. Set to true/false, or
948
+ # Use sudo on all the app's deploy servers. Set to true/false, or
1017
949
  # a username to use 'sudo -u'.
1018
950
 
1019
951
  def sudo=(value)
@@ -1030,6 +962,7 @@ module Sunshine
1030
962
 
1031
963
  ##
1032
964
  # Creates a symlink to the app's checkout path.
965
+ # Supports all App#find options.
1033
966
 
1034
967
  def symlink_current_dir options=nil
1035
968
  with_server_apps options,
@@ -1041,8 +974,12 @@ module Sunshine
1041
974
  ##
1042
975
  # Iterate over all deploy servers but create a thread for each
1043
976
  # deploy server. Means you can't return from the passed block!
977
+ # Calls App#each if Sunshine.use_threads? is false.
978
+ # Supports all App#find options.
979
+
980
+ def threaded_each options=nil, &block
981
+ return each options, &block unless Sunshine.use_threads?
1044
982
 
1045
- def threaded_each(options=nil, &block)
1046
983
  mutex = Mutex.new
1047
984
  threads = []
1048
985
  error = nil
@@ -1072,34 +1009,13 @@ module Sunshine
1072
1009
  end
1073
1010
 
1074
1011
 
1075
- ##
1076
- # Upload common rake tasks from the sunshine lib.
1077
- # app.upload_tasks
1078
- # #=> upload all tasks
1079
- # app.upload_tasks 'app', 'common', :role => :web
1080
- # #=> upload app and common rake files
1081
- #
1082
- # Allows standard DeployServerDispatcher#find options, plus:
1083
- # :remote_path:: str - the remote absolute path to upload the files to
1084
-
1085
- def upload_tasks *files
1086
- options = Hash === files.last ? files.last.dup : {}
1087
-
1088
- options.delete(:remote_path)
1089
- options = :all if options.empty?
1090
-
1091
- with_server_apps options,
1092
- :msg => "Uploading tasks: #{files.join(" ")}",
1093
- :send => [:upload_tasks, *files]
1094
- end
1095
-
1096
-
1097
1012
  ##
1098
1013
  # Execute a block with a specified server app filter:
1099
1014
  # app.with_filter :role => :cdn do |app|
1100
1015
  # app.sass 'file1', 'file2', 'file3'
1101
1016
  # app.rake 'asset:packager:build_all'
1102
1017
  # end
1018
+ # Supports all App#find options.
1103
1019
 
1104
1020
  def with_filter filter_hash
1105
1021
  old_server_apps, @server_apps = @server_apps, find(filter_hash)
@@ -1200,7 +1116,7 @@ module Sunshine
1200
1116
  @shared_path = "#{@root_path}/shared"
1201
1117
  @log_path = "#{@shared_path}/log"
1202
1118
  @checkout_path = "#{@deploys_path}/#{@deploy_name}"
1203
- @scripts_path = "#{@checkout_path}/sunshine_scripts"
1119
+ @scripts_path = "#{@current_path}/script"
1204
1120
  end
1205
1121
 
1206
1122