engineyard-serverside 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +19 -0
- data/bin/engineyard-serverside +10 -0
- data/lib/engineyard-serverside.rb +49 -0
- data/lib/engineyard-serverside/bundle_installer.rb +4 -0
- data/lib/engineyard-serverside/cli.rb +146 -0
- data/lib/engineyard-serverside/configuration.rb +130 -0
- data/lib/engineyard-serverside/default_maintenance_page.html +29 -0
- data/lib/engineyard-serverside/deploy.rb +321 -0
- data/lib/engineyard-serverside/deploy_hook.rb +80 -0
- data/lib/engineyard-serverside/lockfile_parser.rb +55 -0
- data/lib/engineyard-serverside/logged_output.rb +78 -0
- data/lib/engineyard-serverside/server.rb +70 -0
- data/lib/engineyard-serverside/strategies/git.rb +136 -0
- data/lib/engineyard-serverside/task.rb +62 -0
- data/lib/engineyard-serverside/version.rb +3 -0
- data/lib/vendor/dataflow/HISTORY +52 -0
- data/lib/vendor/dataflow/LICENSE +19 -0
- data/lib/vendor/dataflow/README.textile +290 -0
- data/lib/vendor/dataflow/Rakefile +36 -0
- data/lib/vendor/dataflow/dataflow.rb +120 -0
- data/lib/vendor/dataflow/dataflow/actor.rb +22 -0
- data/lib/vendor/dataflow/dataflow/equality.rb +28 -0
- data/lib/vendor/dataflow/dataflow/future_queue.rb +24 -0
- data/lib/vendor/dataflow/dataflow/port.rb +54 -0
- data/lib/vendor/dataflow/examples/barrier.rb +9 -0
- data/lib/vendor/dataflow/examples/data_driven.rb +17 -0
- data/lib/vendor/dataflow/examples/dataflow_http_gets.rb +13 -0
- data/lib/vendor/dataflow/examples/flow.rb +20 -0
- data/lib/vendor/dataflow/examples/future_http_gets.rb +12 -0
- data/lib/vendor/dataflow/examples/future_queue.rb +11 -0
- data/lib/vendor/dataflow/examples/instance_variables.rb +15 -0
- data/lib/vendor/dataflow/examples/laziness.rb +9 -0
- data/lib/vendor/dataflow/examples/local_variables.rb +11 -0
- data/lib/vendor/dataflow/examples/messages.rb +26 -0
- data/lib/vendor/dataflow/examples/port_http_gets.rb +13 -0
- data/lib/vendor/dataflow/examples/port_send.rb +10 -0
- data/lib/vendor/dataflow/examples/ring.rb +21 -0
- data/lib/vendor/dataflow/spec/actor_spec.rb +28 -0
- data/lib/vendor/dataflow/spec/anonymous_variables_spec.rb +21 -0
- data/lib/vendor/dataflow/spec/barrier_spec.rb +25 -0
- data/lib/vendor/dataflow/spec/by_need_spec.rb +55 -0
- data/lib/vendor/dataflow/spec/dataflow_spec.rb +151 -0
- data/lib/vendor/dataflow/spec/equality_spec.rb +40 -0
- data/lib/vendor/dataflow/spec/flow_spec.rb +25 -0
- data/lib/vendor/dataflow/spec/forker_spec.rb +28 -0
- data/lib/vendor/dataflow/spec/future_queue_spec.rb +31 -0
- data/lib/vendor/dataflow/spec/inspect_spec.rb +19 -0
- data/lib/vendor/dataflow/spec/need_later_spec.rb +12 -0
- data/lib/vendor/dataflow/spec/port_spec.rb +26 -0
- data/lib/vendor/dataflow/spec/spec.opts +1 -0
- data/lib/vendor/dataflow/spec/spec_helper.rb +10 -0
- data/lib/vendor/escape/Readme +21 -0
- data/lib/vendor/escape/doc_include/template/qualitysmith.rb +631 -0
- data/lib/vendor/escape/lib/escape.rb +247 -0
- data/lib/vendor/json_pure/CHANGES +166 -0
- data/lib/vendor/json_pure/COPYING +58 -0
- data/lib/vendor/json_pure/GPL +340 -0
- data/lib/vendor/json_pure/README +358 -0
- data/lib/vendor/json_pure/Rakefile +292 -0
- data/lib/vendor/json_pure/TODO +1 -0
- data/lib/vendor/json_pure/VERSION +1 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkComparison.log +52 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast-autocorrelation.dat +1000 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast.dat +1001 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty-autocorrelation.dat +900 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty.dat +901 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe-autocorrelation.dat +1000 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe.dat +1001 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt.log +261 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast-autocorrelation.dat +1000 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast.dat +1001 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty-autocorrelation.dat +1000 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty.dat +1001 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe-autocorrelation.dat +1000 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe.dat +1001 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure.log +262 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator-autocorrelation.dat +1000 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator.dat +1001 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails.log +82 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkComparison.log +34 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser-autocorrelation.dat +900 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser.dat +901 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt.log +81 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser-autocorrelation.dat +1000 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser.dat +1001 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure.log +82 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser-autocorrelation.dat +1000 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser.dat +1001 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails.log +82 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser-autocorrelation.dat +1000 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser.dat +1001 -0
- data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML.log +82 -0
- data/lib/vendor/json_pure/benchmarks/generator2_benchmark.rb +222 -0
- data/lib/vendor/json_pure/benchmarks/generator_benchmark.rb +224 -0
- data/lib/vendor/json_pure/benchmarks/ohai.json +1216 -0
- data/lib/vendor/json_pure/benchmarks/ohai.ruby +1 -0
- data/lib/vendor/json_pure/benchmarks/parser2_benchmark.rb +251 -0
- data/lib/vendor/json_pure/benchmarks/parser_benchmark.rb +259 -0
- data/lib/vendor/json_pure/bin/edit_json.rb +9 -0
- data/lib/vendor/json_pure/bin/prettify_json.rb +75 -0
- data/lib/vendor/json_pure/data/example.json +1 -0
- data/lib/vendor/json_pure/data/index.html +38 -0
- data/lib/vendor/json_pure/data/prototype.js +4184 -0
- data/lib/vendor/json_pure/ext/json/ext/generator/extconf.rb +16 -0
- data/lib/vendor/json_pure/ext/json/ext/generator/generator.c +1323 -0
- data/lib/vendor/json_pure/ext/json/ext/generator/generator.h +170 -0
- data/lib/vendor/json_pure/ext/json/ext/parser/extconf.rb +15 -0
- data/lib/vendor/json_pure/ext/json/ext/parser/parser.c +1935 -0
- data/lib/vendor/json_pure/ext/json/ext/parser/parser.h +71 -0
- data/lib/vendor/json_pure/ext/json/ext/parser/parser.rl +792 -0
- data/lib/vendor/json_pure/install.rb +26 -0
- data/lib/vendor/json_pure/lib/json.rb +10 -0
- data/lib/vendor/json_pure/lib/json/Array.xpm +21 -0
- data/lib/vendor/json_pure/lib/json/FalseClass.xpm +21 -0
- data/lib/vendor/json_pure/lib/json/Hash.xpm +21 -0
- data/lib/vendor/json_pure/lib/json/Key.xpm +73 -0
- data/lib/vendor/json_pure/lib/json/NilClass.xpm +21 -0
- data/lib/vendor/json_pure/lib/json/Numeric.xpm +28 -0
- data/lib/vendor/json_pure/lib/json/String.xpm +96 -0
- data/lib/vendor/json_pure/lib/json/TrueClass.xpm +21 -0
- data/lib/vendor/json_pure/lib/json/add/core.rb +148 -0
- data/lib/vendor/json_pure/lib/json/add/rails.rb +58 -0
- data/lib/vendor/json_pure/lib/json/common.rb +397 -0
- data/lib/vendor/json_pure/lib/json/editor.rb +1371 -0
- data/lib/vendor/json_pure/lib/json/ext.rb +15 -0
- data/lib/vendor/json_pure/lib/json/json.xpm +1499 -0
- data/lib/vendor/json_pure/lib/json/pure.rb +77 -0
- data/lib/vendor/json_pure/lib/json/pure/generator.rb +452 -0
- data/lib/vendor/json_pure/lib/json/pure/parser.rb +307 -0
- data/lib/vendor/json_pure/lib/json/version.rb +8 -0
- data/lib/vendor/json_pure/tests/fixtures/fail1.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail10.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail11.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail12.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail13.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail14.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail18.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail19.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail2.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail20.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail21.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail22.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail23.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail24.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail25.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail27.json +2 -0
- data/lib/vendor/json_pure/tests/fixtures/fail28.json +2 -0
- data/lib/vendor/json_pure/tests/fixtures/fail3.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail4.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail5.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail6.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail7.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail8.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/fail9.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/pass1.json +56 -0
- data/lib/vendor/json_pure/tests/fixtures/pass15.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/pass16.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/pass17.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/pass2.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/pass26.json +1 -0
- data/lib/vendor/json_pure/tests/fixtures/pass3.json +6 -0
- data/lib/vendor/json_pure/tests/test_json.rb +361 -0
- data/lib/vendor/json_pure/tests/test_json_addition.rb +162 -0
- data/lib/vendor/json_pure/tests/test_json_encoding.rb +68 -0
- data/lib/vendor/json_pure/tests/test_json_fixtures.rb +34 -0
- data/lib/vendor/json_pure/tests/test_json_generate.rb +122 -0
- data/lib/vendor/json_pure/tests/test_json_rails.rb +144 -0
- data/lib/vendor/json_pure/tests/test_json_unicode.rb +76 -0
- data/lib/vendor/json_pure/tools/fuzz.rb +139 -0
- data/lib/vendor/json_pure/tools/server.rb +61 -0
- data/lib/vendor/open4/lib/open4.rb +403 -0
- data/lib/vendor/thor/CHANGELOG.rdoc +89 -0
- data/lib/vendor/thor/LICENSE +20 -0
- data/lib/vendor/thor/README.rdoc +297 -0
- data/lib/vendor/thor/Thorfile +69 -0
- data/lib/vendor/thor/bin/rake2thor +86 -0
- data/lib/vendor/thor/bin/thor +6 -0
- data/lib/vendor/thor/lib/thor.rb +244 -0
- data/lib/vendor/thor/lib/thor/actions.rb +275 -0
- data/lib/vendor/thor/lib/thor/actions/create_file.rb +103 -0
- data/lib/vendor/thor/lib/thor/actions/directory.rb +91 -0
- data/lib/vendor/thor/lib/thor/actions/empty_directory.rb +134 -0
- data/lib/vendor/thor/lib/thor/actions/file_manipulation.rb +223 -0
- data/lib/vendor/thor/lib/thor/actions/inject_into_file.rb +104 -0
- data/lib/vendor/thor/lib/thor/base.rb +540 -0
- data/lib/vendor/thor/lib/thor/core_ext/file_binary_read.rb +9 -0
- data/lib/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
- data/lib/vendor/thor/lib/thor/core_ext/ordered_hash.rb +100 -0
- data/lib/vendor/thor/lib/thor/error.rb +30 -0
- data/lib/vendor/thor/lib/thor/group.rb +271 -0
- data/lib/vendor/thor/lib/thor/invocation.rb +180 -0
- data/lib/vendor/thor/lib/thor/parser.rb +4 -0
- data/lib/vendor/thor/lib/thor/parser/argument.rb +67 -0
- data/lib/vendor/thor/lib/thor/parser/arguments.rb +150 -0
- data/lib/vendor/thor/lib/thor/parser/option.rb +128 -0
- data/lib/vendor/thor/lib/thor/parser/options.rb +169 -0
- data/lib/vendor/thor/lib/thor/rake_compat.rb +66 -0
- data/lib/vendor/thor/lib/thor/runner.rb +314 -0
- data/lib/vendor/thor/lib/thor/shell.rb +83 -0
- data/lib/vendor/thor/lib/thor/shell/basic.rb +239 -0
- data/lib/vendor/thor/lib/thor/shell/color.rb +108 -0
- data/lib/vendor/thor/lib/thor/task.rb +102 -0
- data/lib/vendor/thor/lib/thor/util.rb +230 -0
- data/lib/vendor/thor/lib/thor/version.rb +3 -0
- data/lib/vendor/thor/thor.gemspec +120 -0
- data/spec/custom_deploy_spec.rb +95 -0
- data/spec/deploy_hook_spec.rb +211 -0
- data/spec/fixtures/gitrepo.tar.gz +0 -0
- data/spec/fixtures/gitrepo/foo +0 -0
- data/spec/fixtures/invalid_hook.rb +1 -0
- data/spec/fixtures/valid_hook.rb +1 -0
- data/spec/git_strategy_spec.rb +22 -0
- data/spec/lockfile_parser_spec.rb +30 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/support/lockfiles/0.9-no-bundler +111 -0
- data/spec/support/lockfiles/0.9-with-bundler +117 -0
- data/spec/support/lockfiles/1.0-no-bundler +54 -0
- data/spec/support/lockfiles/1.0.0.rc.1-with-bundler +162 -0
- data/spec/support/lockfiles/not-a-lockfile +10 -0
- metadata +279 -0
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2010 Engine Yard, Inc
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
@@ -0,0 +1,49 @@
|
|
1
|
+
$LOAD_PATH.push(File.expand_path("engineyard-serverside", File.dirname(__FILE__)))
|
2
|
+
$LOAD_PATH.unshift File.expand_path('vendor/thor/lib', File.dirname(__FILE__))
|
3
|
+
$LOAD_PATH.unshift File.expand_path('vendor/open4/lib', File.dirname(__FILE__))
|
4
|
+
$LOAD_PATH.unshift File.expand_path('vendor/escape/lib', File.dirname(__FILE__))
|
5
|
+
$LOAD_PATH.unshift File.expand_path('vendor/json_pure/lib', File.dirname(__FILE__))
|
6
|
+
$LOAD_PATH.unshift File.expand_path('vendor/dataflow', File.dirname(__FILE__))
|
7
|
+
|
8
|
+
require 'escape'
|
9
|
+
require 'json'
|
10
|
+
require 'dataflow'
|
11
|
+
|
12
|
+
require 'version'
|
13
|
+
require 'strategies/git'
|
14
|
+
require 'task'
|
15
|
+
require 'server'
|
16
|
+
require 'deploy'
|
17
|
+
require 'deploy_hook'
|
18
|
+
require 'lockfile_parser'
|
19
|
+
require 'bundle_installer'
|
20
|
+
require 'cli'
|
21
|
+
require 'configuration'
|
22
|
+
|
23
|
+
module EY
|
24
|
+
def self.node
|
25
|
+
@node ||= deep_indifferentize(JSON.parse(dna_json))
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.dna_json
|
29
|
+
@dna_json ||= `sudo cat /etc/chef/dna.json`
|
30
|
+
end
|
31
|
+
|
32
|
+
RemoteFailure = Class.new StandardError
|
33
|
+
|
34
|
+
private
|
35
|
+
def self.deep_indifferentize(thing)
|
36
|
+
if thing.kind_of?(Hash)
|
37
|
+
indifferent_hash = Thor::CoreExt::HashWithIndifferentAccess.new
|
38
|
+
thing.each do |k, v|
|
39
|
+
indifferent_hash[k] = deep_indifferentize(v)
|
40
|
+
end
|
41
|
+
indifferent_hash
|
42
|
+
elsif thing.kind_of?(Array)
|
43
|
+
thing.map {|x| deep_indifferentize(x)}
|
44
|
+
else
|
45
|
+
thing
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module EY
|
4
|
+
class CLI < Thor
|
5
|
+
include Dataflow
|
6
|
+
|
7
|
+
def self.start(*)
|
8
|
+
super
|
9
|
+
rescue RemoteFailure
|
10
|
+
exit(1)
|
11
|
+
end
|
12
|
+
|
13
|
+
method_option :migrate, :type => :string,
|
14
|
+
:desc => "Run migrations with this deploy",
|
15
|
+
:aliases => ["-m"]
|
16
|
+
|
17
|
+
method_option :branch, :type => :string,
|
18
|
+
:desc => "Git ref to deploy, defaults to master. May be a branch, a tag, or a SHA",
|
19
|
+
:aliases => %w[-b --ref --tag]
|
20
|
+
|
21
|
+
method_option :repo, :type => :string,
|
22
|
+
:desc => "Remote repo to deploy",
|
23
|
+
:aliases => ["-r"]
|
24
|
+
|
25
|
+
method_option :app, :type => :string,
|
26
|
+
:required => true,
|
27
|
+
:desc => "Application to deploy",
|
28
|
+
:aliases => ["-a"]
|
29
|
+
|
30
|
+
method_option :framework_env, :type => :string,
|
31
|
+
:required => true,
|
32
|
+
:desc => "Ruby web framework environment",
|
33
|
+
:aliases => ["-e"]
|
34
|
+
|
35
|
+
method_option :config, :type => :string,
|
36
|
+
:desc => "Additional configuration"
|
37
|
+
|
38
|
+
method_option :stack, :type => :string,
|
39
|
+
:desc => "Web stack (so we can restart it correctly)"
|
40
|
+
|
41
|
+
method_option :instances, :type => :array,
|
42
|
+
:desc => "Instances in cluster"
|
43
|
+
|
44
|
+
method_option :verbose, :type => :boolean,
|
45
|
+
:default => false,
|
46
|
+
:desc => "Verbose output",
|
47
|
+
:aliases => ["-v"]
|
48
|
+
|
49
|
+
desc "deploy", "Deploy code from /data/<app>"
|
50
|
+
def deploy(default_task=:deploy)
|
51
|
+
EY::Server.all = parse_instances(options[:instances])
|
52
|
+
EY::LoggedOutput.verbose = options[:verbose]
|
53
|
+
EY::LoggedOutput.logfile = File.join(ENV['HOME'], "#{options[:app]}-deploy.log")
|
54
|
+
|
55
|
+
invoke :propagate
|
56
|
+
EY::Deploy.run(options.merge("default_task" => default_task))
|
57
|
+
end
|
58
|
+
|
59
|
+
method_option :app, :type => :string,
|
60
|
+
:required => true,
|
61
|
+
:desc => "Which application's hooks to run",
|
62
|
+
:aliases => ["-a"]
|
63
|
+
|
64
|
+
method_option :release_path, :type => :string,
|
65
|
+
:desc => "Value for #release_path in hooks (mostly for internal coordination)",
|
66
|
+
:aliases => ["-r"]
|
67
|
+
|
68
|
+
method_option :current_role, :type => :string,
|
69
|
+
:desc => "Value for #current_role in hooks"
|
70
|
+
|
71
|
+
method_option :framework_env, :type => :string,
|
72
|
+
:required => true,
|
73
|
+
:desc => "Ruby web framework environment",
|
74
|
+
:aliases => ["-e"]
|
75
|
+
|
76
|
+
method_option :config, :type => :string,
|
77
|
+
:desc => "Additional configuration"
|
78
|
+
|
79
|
+
method_option :current_name, :type => :string,
|
80
|
+
:desc => "Value for #current_name in hooks"
|
81
|
+
|
82
|
+
desc "hook [NAME]", "Run a particular deploy hook"
|
83
|
+
def hook(hook_name)
|
84
|
+
EY::DeployHook.new(options).run(hook_name)
|
85
|
+
end
|
86
|
+
|
87
|
+
desc "install_bundler [VERSION]", "Make sure VERSION of bundler is installed (in system ruby)"
|
88
|
+
def install_bundler(version)
|
89
|
+
egrep_escaped_version = version.gsub(/\./, '\.')
|
90
|
+
# the grep "bundler " is so that gems like bundler08 don't get
|
91
|
+
# their versions considered too
|
92
|
+
#
|
93
|
+
# the [,$] is to stop us from looking for e.g. 0.9.2, seeing
|
94
|
+
# 0.9.22, and mistakenly thinking 0.9.2 is there
|
95
|
+
has_bundler_cmd = "gem list bundler | grep \"bundler \" | egrep -q '#{egrep_escaped_version}[,)]'"
|
96
|
+
|
97
|
+
unless system(has_bundler_cmd)
|
98
|
+
system("gem install bundler -q --no-rdoc --no-ri -v '#{version}'")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
desc "propagate", "Propagate the engineyard-serverside gem to the other instances in the cluster. This will install exactly version #{VERSION} and remove other versions if found."
|
103
|
+
def propagate
|
104
|
+
config = EY::Deploy::Configuration.new
|
105
|
+
gem_filename = "engineyard-serverside-#{VERSION}.gem"
|
106
|
+
local_gem_file = File.join(Gem.dir, 'cache', gem_filename)
|
107
|
+
remote_gem_file = File.join(Dir.tmpdir, gem_filename)
|
108
|
+
gem_binary = File.join(Gem.default_bindir, 'gem')
|
109
|
+
|
110
|
+
EY::Server.config = config
|
111
|
+
|
112
|
+
barrier(*(EY::Server.all.find_all do |server|
|
113
|
+
!server.local? # of course this machine has it
|
114
|
+
end.map do |server|
|
115
|
+
need_later do
|
116
|
+
egrep_escaped_version = VERSION.gsub(/\./, '\.')
|
117
|
+
# the [,)] is to stop us from looking for e.g. 0.5.1, seeing
|
118
|
+
# 0.5.11, and mistakenly thinking 0.5.1 is there
|
119
|
+
has_gem_cmd = "#{gem_binary} list engineyard-serverside | grep \"engineyard-serverside\" | egrep -q '#{egrep_escaped_version}[,)]'"
|
120
|
+
|
121
|
+
if !server.run(has_gem_cmd) # doesn't have this exact version
|
122
|
+
puts "~> Installing engineyard-serverside on #{server.hostname}"
|
123
|
+
|
124
|
+
system(Escape.shell_command([
|
125
|
+
'scp', '-i', "#{ENV['HOME']}/.ssh/internal",
|
126
|
+
"-o", "StrictHostKeyChecking=no",
|
127
|
+
local_gem_file,
|
128
|
+
"#{config.user}@#{server.hostname}:#{remote_gem_file}",
|
129
|
+
]))
|
130
|
+
server.run("sudo #{gem_binary} install --no-rdoc --no-ri '#{remote_gem_file}'")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end))
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
137
|
+
|
138
|
+
def parse_instances(instance_strings)
|
139
|
+
instance_strings.map do |s|
|
140
|
+
tuple = s.split(/,/)
|
141
|
+
{:hostname => tuple[0], :role => tuple[1], :name => tuple[2]}
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'thor'
|
3
|
+
|
4
|
+
module EY
|
5
|
+
class Deploy::Configuration
|
6
|
+
DEFAULT_CONFIG = Thor::CoreExt::HashWithIndifferentAccess.new({
|
7
|
+
"branch" => "master",
|
8
|
+
"strategy" => "Git",
|
9
|
+
})
|
10
|
+
|
11
|
+
attr_reader :configuration
|
12
|
+
alias :c :configuration
|
13
|
+
|
14
|
+
attr_writer :release_path
|
15
|
+
|
16
|
+
def initialize(opts={})
|
17
|
+
@release_path = opts[:release_path]
|
18
|
+
config = JSON.parse(opts["config"] || "{}")
|
19
|
+
@configuration = DEFAULT_CONFIG.merge(config).merge(opts)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Delegate to the configuration objects
|
23
|
+
def method_missing(meth, *args, &blk)
|
24
|
+
c.key?(meth.to_s) ? c[meth.to_s] : super
|
25
|
+
end
|
26
|
+
|
27
|
+
def respond_to?(meth, include_private=false)
|
28
|
+
c.key?(meth.to_s) ? true : super
|
29
|
+
end
|
30
|
+
|
31
|
+
def [](key)
|
32
|
+
if respond_to?(key.to_sym)
|
33
|
+
send(key.to_sym)
|
34
|
+
else
|
35
|
+
c[key]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def has_key?(key)
|
40
|
+
if respond_to?(key.to_sym)
|
41
|
+
true
|
42
|
+
else
|
43
|
+
c.has_key?(key)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def node
|
48
|
+
EY.node
|
49
|
+
end
|
50
|
+
|
51
|
+
def revision
|
52
|
+
IO.read(File.join(latest_release, 'REVISION'))
|
53
|
+
end
|
54
|
+
|
55
|
+
def repository_cache
|
56
|
+
configuration['repository_cache'] || File.join(deploy_to, "/shared/cached-copy")
|
57
|
+
end
|
58
|
+
|
59
|
+
def deploy_to
|
60
|
+
configuration['deploy_to'] || "/data/#{app}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def migrate?
|
64
|
+
!!configuration['migrate']
|
65
|
+
end
|
66
|
+
|
67
|
+
def migration_command
|
68
|
+
configuration['migrate'] == "migrate" ? DEFAULT_CONFIG["migrate"] : configuration['migrate']
|
69
|
+
end
|
70
|
+
|
71
|
+
def user
|
72
|
+
ENV['USER']
|
73
|
+
end
|
74
|
+
alias :group :user
|
75
|
+
|
76
|
+
def role
|
77
|
+
node['instance_role']
|
78
|
+
end
|
79
|
+
|
80
|
+
def copy_exclude
|
81
|
+
@copy_exclude ||= Array(configuration.fetch("copy_exclude", []))
|
82
|
+
end
|
83
|
+
|
84
|
+
def environment
|
85
|
+
configuration['framework_env']
|
86
|
+
end
|
87
|
+
|
88
|
+
def latest_release
|
89
|
+
all_releases.last
|
90
|
+
end
|
91
|
+
|
92
|
+
def previous_release(current=latest_release)
|
93
|
+
index = all_releases.index(current)
|
94
|
+
all_releases[index-1]
|
95
|
+
end
|
96
|
+
|
97
|
+
def oldest_release
|
98
|
+
all_releases.first
|
99
|
+
end
|
100
|
+
|
101
|
+
def all_releases
|
102
|
+
Dir.glob("#{release_dir}/*").sort
|
103
|
+
end
|
104
|
+
|
105
|
+
def framework_envs
|
106
|
+
"RAILS_ENV=#{environment} RACK_ENV=#{environment} MERB_ENV=#{environment}"
|
107
|
+
end
|
108
|
+
|
109
|
+
def current_path
|
110
|
+
File.join(deploy_to, "current")
|
111
|
+
end
|
112
|
+
|
113
|
+
def shared_path
|
114
|
+
File.join(deploy_to, "shared")
|
115
|
+
end
|
116
|
+
|
117
|
+
def release_dir
|
118
|
+
File.join(deploy_to, "releases")
|
119
|
+
end
|
120
|
+
|
121
|
+
def release_path
|
122
|
+
@release_path ||= File.join(release_dir, Time.now.utc.strftime("%Y%m%d%H%M%S"))
|
123
|
+
end
|
124
|
+
|
125
|
+
def exclusions
|
126
|
+
copy_exclude.map { |e| %|--exclude="#{e}"| }.join(' ')
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<!DOCTYPE html >
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Undergoing Maintenance</title>
|
5
|
+
|
6
|
+
<style type="text/css">
|
7
|
+
body{font-size: 75%;font-family: Helvetica,Arial,sans-serif;color:#333;background:#FDFDFD;}
|
8
|
+
.container{font-size:1.1em;width:700px;text-align:center;margin:80px auto;}
|
9
|
+
.message{background:#FFF;border:1px solid #EEE;padding:30px;}
|
10
|
+
h1{margin:0 0 0.5em;font-weight:normal;}
|
11
|
+
p{margin:0;line-height:1.75em;}
|
12
|
+
.foot{color:#999;margin-top:30px}
|
13
|
+
.foot a{color:#666;text-decoration:none}
|
14
|
+
</style>
|
15
|
+
</head>
|
16
|
+
|
17
|
+
<body>
|
18
|
+
<div class="container">
|
19
|
+
<div class="message">
|
20
|
+
<h1>This site is currently undergoing some maintenance.</h1>
|
21
|
+
<p>Customize this maintenance page by updating the file located at: /public/maintenance.html</p>
|
22
|
+
</div>
|
23
|
+
<div class="foot">
|
24
|
+
Hosted by <a href="http://www.engineyard.com">Engine Yard</a>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
</body>
|
28
|
+
|
29
|
+
</html>
|
@@ -0,0 +1,321 @@
|
|
1
|
+
# stolen wholesale from capistrano, thanks Jamis!
|
2
|
+
require 'base64'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module EY
|
7
|
+
class DeployBase < Task
|
8
|
+
include LoggedOutput
|
9
|
+
|
10
|
+
# default task
|
11
|
+
def deploy
|
12
|
+
debug "Starting deploy at #{Time.now.asctime}"
|
13
|
+
update_repository_cache
|
14
|
+
require_custom_tasks
|
15
|
+
push_code
|
16
|
+
|
17
|
+
info "~> Starting full deploy"
|
18
|
+
copy_repository_cache
|
19
|
+
|
20
|
+
with_failed_release_cleanup do
|
21
|
+
create_revision_file
|
22
|
+
bundle
|
23
|
+
symlink_configs
|
24
|
+
conditionally_enable_maintenance_page
|
25
|
+
run_with_callbacks(:migrate)
|
26
|
+
callback(:before_symlink)
|
27
|
+
symlink
|
28
|
+
end
|
29
|
+
|
30
|
+
callback(:after_symlink)
|
31
|
+
run_with_callbacks(:restart)
|
32
|
+
disable_maintenance_page
|
33
|
+
|
34
|
+
cleanup_old_releases
|
35
|
+
debug "Finished deploy at #{Time.now.asctime}"
|
36
|
+
rescue Exception
|
37
|
+
debug "Finished failing to deploy at #{Time.now.asctime}"
|
38
|
+
puts_deploy_failure
|
39
|
+
raise
|
40
|
+
end
|
41
|
+
|
42
|
+
def enable_maintenance_page
|
43
|
+
maintenance_page_candidates = [
|
44
|
+
"public/maintenance.html.custom",
|
45
|
+
"public/maintenance.html.tmp",
|
46
|
+
"public/maintenance.html",
|
47
|
+
"public/system/maintenance.html.default",
|
48
|
+
].map do |file|
|
49
|
+
File.join(c.latest_release, file)
|
50
|
+
end
|
51
|
+
|
52
|
+
# this one is guaranteed to exist
|
53
|
+
maintenance_page_candidates << File.expand_path(
|
54
|
+
"default_maintenance_page.html",
|
55
|
+
File.dirname(__FILE__)
|
56
|
+
)
|
57
|
+
|
58
|
+
# put in the maintenance page
|
59
|
+
maintenance_file = maintenance_page_candidates.detect do |file|
|
60
|
+
File.exists?(file)
|
61
|
+
end
|
62
|
+
|
63
|
+
@maintenance_up = true
|
64
|
+
roles :app_master, :app, :solo do
|
65
|
+
visible_maint_page = File.join(c.shared_path, "system", "maintenance.html")
|
66
|
+
run "cp '#{maintenance_file}' '#{visible_maint_page}'"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def conditionally_enable_maintenance_page
|
71
|
+
if c.migrate? || c.stack == "nginx_mongrel"
|
72
|
+
enable_maintenance_page
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def disable_maintenance_page
|
77
|
+
@maintenance_up = false
|
78
|
+
roles :app_master, :app, :solo do
|
79
|
+
run "rm -f #{File.join(c.shared_path, "system", "maintenance.html")}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def run_with_callbacks(task, *args)
|
84
|
+
callback(:"before_#{task}")
|
85
|
+
send(task, *args)
|
86
|
+
callback(:"after_#{task}")
|
87
|
+
end
|
88
|
+
|
89
|
+
# task
|
90
|
+
def push_code
|
91
|
+
info "~> Pushing code to all servers"
|
92
|
+
barrier *(EY::Server.all.map do |server|
|
93
|
+
need_later { server.push_code }
|
94
|
+
end)
|
95
|
+
end
|
96
|
+
|
97
|
+
# task
|
98
|
+
def restart
|
99
|
+
@restart_failed = true
|
100
|
+
info "~> Restarting app servers"
|
101
|
+
roles :app_master, :app, :solo do
|
102
|
+
restart_command = case c.stack
|
103
|
+
when "nginx_unicorn"
|
104
|
+
pidfile = "/var/run/engineyard/unicorn_#{c.app}.pid"
|
105
|
+
condition = "[ -e #{pidfile} ] && [ ! -d /proc/`cat #{pidfile}` ]"
|
106
|
+
run("if #{condition}; then rm -f #{pidfile}; fi")
|
107
|
+
run("/engineyard/bin/app_#{c.app} deploy")
|
108
|
+
when "nginx_mongrel"
|
109
|
+
sudo("monit restart all -g #{c.app}")
|
110
|
+
when "nginx_passenger"
|
111
|
+
run("touch #{c.current_path}/tmp/restart.txt")
|
112
|
+
else
|
113
|
+
raise "Unknown stack #{c.stack}; restart failed!"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
@restart_failed = false
|
117
|
+
end
|
118
|
+
|
119
|
+
# task
|
120
|
+
def bundle
|
121
|
+
if File.exist?("#{c.release_path}/Gemfile")
|
122
|
+
info "~> Gemfile detected, bundling gems"
|
123
|
+
lockfile = File.join(c.release_path, "Gemfile.lock")
|
124
|
+
|
125
|
+
bundler_installer = if File.exist?(lockfile)
|
126
|
+
get_bundler_installer(lockfile)
|
127
|
+
else
|
128
|
+
warn_about_missing_lockfile
|
129
|
+
BundleInstaller.new(DEFAULT_09_BUNDLER, "--without=development --without=test")
|
130
|
+
end
|
131
|
+
|
132
|
+
sudo "#{$0} _#{VERSION}_ install_bundler #{bundler_installer.version}"
|
133
|
+
|
134
|
+
run "cd #{c.release_path} && bundle _#{bundler_installer.version}_ install #{bundler_installer.options}"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# task
|
139
|
+
def cleanup_old_releases
|
140
|
+
@cleanup_failed = true
|
141
|
+
info "~> Cleaning up old releases"
|
142
|
+
sudo "ls #{c.release_dir} | head -n -3 | xargs -I{} rm -rf #{c.release_dir}/{}"
|
143
|
+
@cleanup_failed = false
|
144
|
+
end
|
145
|
+
|
146
|
+
# task
|
147
|
+
def rollback
|
148
|
+
if c.all_releases.size > 1
|
149
|
+
c.release_path = c.previous_release
|
150
|
+
|
151
|
+
revision = File.read(File.join(c.release_path, 'REVISION')).strip
|
152
|
+
info "~> Rolling back to previous release: #{short_log_message(revision)}"
|
153
|
+
|
154
|
+
run_with_callbacks(:symlink, c.previous_release)
|
155
|
+
cleanup_current_release
|
156
|
+
bundle
|
157
|
+
info "~> Restarting with previous release"
|
158
|
+
with_maintenance_page { run_with_callbacks(:restart) }
|
159
|
+
else
|
160
|
+
info "~> Already at oldest release, nothing to roll back to"
|
161
|
+
exit(1)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# task
|
166
|
+
def migrate
|
167
|
+
return unless c.migrate?
|
168
|
+
@migrations_reached = true
|
169
|
+
roles :app_master, :solo do
|
170
|
+
cmd = "cd #{c.release_path} && #{c.framework_envs} #{c.migration_command}"
|
171
|
+
info "~> Migrating: #{cmd}"
|
172
|
+
run(cmd)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# task
|
177
|
+
def copy_repository_cache
|
178
|
+
info "~> Copying to #{c.release_path}"
|
179
|
+
run("mkdir -p #{c.release_path} && rsync -aq #{c.exclusions} #{c.repository_cache}/ #{c.release_path}")
|
180
|
+
|
181
|
+
info "~> Ensuring proper ownership"
|
182
|
+
sudo("chown -R #{c.user}:#{c.group} #{c.deploy_to}")
|
183
|
+
end
|
184
|
+
|
185
|
+
def create_revision_file
|
186
|
+
run create_revision_file_command
|
187
|
+
end
|
188
|
+
|
189
|
+
def symlink_configs(release_to_link=c.release_path)
|
190
|
+
info "~> Symlinking configs"
|
191
|
+
[ "chmod -R g+w #{release_to_link}",
|
192
|
+
"rm -rf #{release_to_link}/log #{release_to_link}/public/system #{release_to_link}/tmp/pids",
|
193
|
+
"mkdir -p #{release_to_link}/tmp",
|
194
|
+
"ln -nfs #{c.shared_path}/log #{release_to_link}/log",
|
195
|
+
"mkdir -p #{release_to_link}/public",
|
196
|
+
"mkdir -p #{release_to_link}/config",
|
197
|
+
"ln -nfs #{c.shared_path}/system #{release_to_link}/public/system",
|
198
|
+
"ln -nfs #{c.shared_path}/pids #{release_to_link}/tmp/pids",
|
199
|
+
"ln -nfs #{c.shared_path}/config/database.yml #{release_to_link}/config/database.yml",
|
200
|
+
"ln -nfs #{c.shared_path}/config/mongrel_cluster.yml #{release_to_link}/config/mongrel_cluster.yml",
|
201
|
+
].each do |cmd|
|
202
|
+
run cmd
|
203
|
+
end
|
204
|
+
|
205
|
+
sudo "chown -R #{c.user}:#{c.group} #{release_to_link}"
|
206
|
+
run "if [ -f \"#{c.shared_path}/config/newrelic.yml\" ]; then ln -nfs #{c.shared_path}/config/newrelic.yml #{release_to_link}/config/newrelic.yml; fi"
|
207
|
+
end
|
208
|
+
|
209
|
+
# task
|
210
|
+
def symlink(release_to_link=c.release_path)
|
211
|
+
info "~> Symlinking code"
|
212
|
+
run "rm -f #{c.current_path} && ln -nfs #{release_to_link} #{c.current_path} && chown -R #{c.user}:#{c.group} #{c.current_path}"
|
213
|
+
@symlink_changed = true
|
214
|
+
rescue Exception
|
215
|
+
sudo "rm -f #{c.current_path} && ln -nfs #{c.previous_release(release_to_link)} #{c.current_path} && chown -R #{c.user}:#{c.group} #{c.current_path}"
|
216
|
+
@symlink_changed = false
|
217
|
+
raise
|
218
|
+
end
|
219
|
+
|
220
|
+
def callback(what)
|
221
|
+
@callbacks_reached ||= true
|
222
|
+
if File.exist?("#{c.release_path}/deploy/#{what}.rb")
|
223
|
+
eydeploy_path = $0 # invoke others just like we were invoked
|
224
|
+
run "#{eydeploy_path} _#{VERSION}_ hook '#{what}' --app '#{config.app}' --release-path #{config.release_path}" do |server, cmd|
|
225
|
+
cmd << " --framework-env '#{c.environment}'"
|
226
|
+
cmd << " --current-role '#{server.role}'"
|
227
|
+
cmd << " --current-name '#{server.name}'" if server.name
|
228
|
+
cmd << " --config '#{c[:config]}'" if c.has_key?(:config)
|
229
|
+
cmd
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
protected
|
235
|
+
|
236
|
+
def puts_deploy_failure
|
237
|
+
if @cleanup_failed
|
238
|
+
info "~> [Relax] Your site is running new code, but cleaning up old deploys failed"
|
239
|
+
elsif @maintenance_up
|
240
|
+
info "~> [Attention] Maintenance page still up, consider the following before removing:"
|
241
|
+
info " * any deploy hooks ran, be careful if they were destructive" if @callbacks_reached
|
242
|
+
info " * any migrations ran, be careful if they were destructive" if @migrations_reached
|
243
|
+
if @symlink_changed
|
244
|
+
info " * your new code is symlinked as current"
|
245
|
+
else
|
246
|
+
info " * your old code is still symlinked as current"
|
247
|
+
end
|
248
|
+
info " * application servers failed to restart" if @restart_failed
|
249
|
+
else
|
250
|
+
info "~> [Relax] Your site is still running old code and nothing destructive could have occurred"
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
def with_maintenance_page
|
255
|
+
conditionally_enable_maintenance_page
|
256
|
+
yield if block_given?
|
257
|
+
disable_maintenance_page
|
258
|
+
end
|
259
|
+
|
260
|
+
def with_failed_release_cleanup
|
261
|
+
yield
|
262
|
+
rescue Exception
|
263
|
+
cleanup_current_release
|
264
|
+
raise
|
265
|
+
end
|
266
|
+
|
267
|
+
def cleanup_current_release
|
268
|
+
sudo "rm -rf #{c.release_path}"
|
269
|
+
end
|
270
|
+
|
271
|
+
DEFAULT_09_BUNDLER = '0.9.26'
|
272
|
+
DEFAULT_10_BUNDLER = '1.0.0.rc.3'
|
273
|
+
|
274
|
+
def warn_about_missing_lockfile
|
275
|
+
info "!>"
|
276
|
+
info "!> WARNING: Gemfile.lock is missing!"
|
277
|
+
info "!> You can get different gems in production than what you tested with."
|
278
|
+
info "!> You can get different gems on every deployment even if your Gemfile hasn't changed."
|
279
|
+
info "!> Deploying may take a long time."
|
280
|
+
info "!>"
|
281
|
+
info "!> Fix this by running \"git add Gemfile.lock; git commit\" and deploying again."
|
282
|
+
info "!> If you don't have a Gemfile.lock, run \"bundle lock\" to create one."
|
283
|
+
info "!>"
|
284
|
+
info "!> This deployment will use bundler #{DEFAULT_09_BUNDLER} to run 'bundle install'."
|
285
|
+
info "!>"
|
286
|
+
end
|
287
|
+
|
288
|
+
def get_bundler_installer(lockfile)
|
289
|
+
parser = LockfileParser.new(File.read(lockfile))
|
290
|
+
case parser.lockfile_version
|
291
|
+
when :bundler09
|
292
|
+
BundleInstaller.new(
|
293
|
+
parser.bundler_version || DEFAULT_09_BUNDLER,
|
294
|
+
"--without=development --without=test")
|
295
|
+
when :bundler10
|
296
|
+
BundleInstaller.new(
|
297
|
+
parser.bundler_version || DEFAULT_10_BUNDLER,
|
298
|
+
"--deployment --path #{c.shared_path}/bundled_gems --without development test"
|
299
|
+
)
|
300
|
+
else
|
301
|
+
raise "Unknown lockfile version #{parser.lockfile_version}"
|
302
|
+
end
|
303
|
+
end
|
304
|
+
public :get_bundler_installer
|
305
|
+
|
306
|
+
end # DeployBase
|
307
|
+
|
308
|
+
class Deploy < DeployBase
|
309
|
+
def self.new(opts={})
|
310
|
+
# include the correct fetch strategy
|
311
|
+
include EY::Strategies.const_get(opts.strategy)::Helpers
|
312
|
+
super
|
313
|
+
end
|
314
|
+
|
315
|
+
def self.run(opts={})
|
316
|
+
conf = EY::Deploy::Configuration.new(opts)
|
317
|
+
EY::Server.config = conf
|
318
|
+
new(conf).send(opts["default_task"])
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|