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
@@ -0,0 +1,80 @@
|
|
1
|
+
module EY
|
2
|
+
class DeployHook < Task
|
3
|
+
def initialize(options)
|
4
|
+
super(EY::Deploy::Configuration.new(options))
|
5
|
+
end
|
6
|
+
|
7
|
+
def callback_context
|
8
|
+
@context ||= CallbackContext.new(config)
|
9
|
+
end
|
10
|
+
|
11
|
+
def run(hook)
|
12
|
+
hook_path = "#{c.release_path}/deploy/#{hook}.rb"
|
13
|
+
if File.exist?(hook_path)
|
14
|
+
Dir.chdir(c.release_path) do
|
15
|
+
puts "~> running deploy hook: deploy/#{hook}.rb"
|
16
|
+
if desc = syntax_error(hook_path)
|
17
|
+
hook_name = File.basename(hook_path)
|
18
|
+
abort "*** [Error] Invalid Ruby syntax in hook: #{hook_name} ***\n*** #{desc.chomp} ***"
|
19
|
+
else
|
20
|
+
callback_context.instance_eval(IO.read(hook_path))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def syntax_error(file)
|
27
|
+
valid = Kernel.system("ruby -c #{file} 2>/tmp/ey_invalid_deploy_hook | grep 'Syntax OK' --quiet")
|
28
|
+
File.new("/tmp/ey_invalid_deploy_hook").gets unless valid
|
29
|
+
end
|
30
|
+
|
31
|
+
class CallbackContext
|
32
|
+
def initialize(config)
|
33
|
+
@configuration = config
|
34
|
+
@node = node
|
35
|
+
end
|
36
|
+
|
37
|
+
def method_missing(meth, *args, &blk)
|
38
|
+
if @configuration.respond_to?(meth)
|
39
|
+
@configuration.send(meth, *args, &blk)
|
40
|
+
else
|
41
|
+
super
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def respond_to?(meth, include_private=false)
|
46
|
+
@configuration.respond_to?(meth, include_private) || super
|
47
|
+
end
|
48
|
+
|
49
|
+
def run(cmd)
|
50
|
+
system(Escape.shell_command(["sh", "-l", "-c", cmd]))
|
51
|
+
end
|
52
|
+
|
53
|
+
def sudo(cmd)
|
54
|
+
system(Escape.shell_command(["sudo", "sh", "-l", "-c", cmd]))
|
55
|
+
end
|
56
|
+
|
57
|
+
# convenience functions for running on certain instance types
|
58
|
+
def on_app_master(&blk) on_roles(%w[solo app_master], &blk) end
|
59
|
+
def on_app_servers(&blk) on_roles(%w[solo app_master app], &blk) end
|
60
|
+
def on_db_master(&blk) on_roles(%w[solo db_master], &blk) end
|
61
|
+
def on_db_slaves(&blk) on_roles(%w[db_slave], &blk) end
|
62
|
+
def on_db_servers(&blk) on_roles(%w[solo db_master db_slave], &blk) end
|
63
|
+
def on_app_servers_and_utilities(&blk) on_roles(%w[solo app_master app util], &blk) end
|
64
|
+
|
65
|
+
def on_utilities(*names, &blk)
|
66
|
+
names.flatten!
|
67
|
+
on_roles(%w[util]) do
|
68
|
+
blk.call if names.empty? || names.include?(current_name)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
def on_roles(desired_roles)
|
74
|
+
yield if desired_roles.include?(current_role.to_s)
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
module EY
|
3
|
+
class LockfileParser
|
4
|
+
|
5
|
+
attr_reader :bundler_version, :lockfile_version
|
6
|
+
|
7
|
+
def initialize(lockfile_contents)
|
8
|
+
@contents = lockfile_contents
|
9
|
+
@lockfile_version, @bundler_version = parse
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
def parse
|
14
|
+
from_yaml = safe_yaml_load(@contents)
|
15
|
+
if from_yaml # 0.9
|
16
|
+
bundler_version = from_yaml['specs'].map do |spec|
|
17
|
+
# spec is a one-element hash: the key is the gem name, and
|
18
|
+
# the value is {"version" => the-version}.
|
19
|
+
if spec.keys.first == "bundler"
|
20
|
+
spec.values.first["version"]
|
21
|
+
end
|
22
|
+
end.compact.first
|
23
|
+
[:bundler09, bundler_version]
|
24
|
+
else # 1.0 or bust
|
25
|
+
dep_section = ""
|
26
|
+
in_dependencies_section = false
|
27
|
+
@contents.each_line do |line|
|
28
|
+
if line =~ /^DEPENDENCIES/
|
29
|
+
in_dependencies_section = true
|
30
|
+
elsif line =~ /^\S/
|
31
|
+
in_dependencies_section = false
|
32
|
+
elsif in_dependencies_section
|
33
|
+
dep_section << line
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
unless dep_section.length > 0
|
38
|
+
raise "Couldn't parse #{lockfile}; exiting"
|
39
|
+
exit(1)
|
40
|
+
end
|
41
|
+
|
42
|
+
result = dep_section.scan(/^\s*bundler\s*\(=\s*([^\)]+)\)/).first
|
43
|
+
bundler_version = result ? result.first : nil
|
44
|
+
[:bundler10, bundler_version]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def safe_yaml_load(loadable)
|
49
|
+
YAML.load(loadable)
|
50
|
+
rescue ArgumentError # not yaml
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'open4'
|
2
|
+
|
3
|
+
module EY
|
4
|
+
module LoggedOutput
|
5
|
+
|
6
|
+
class Tee
|
7
|
+
def initialize(*streams)
|
8
|
+
@streams = streams.flatten
|
9
|
+
end
|
10
|
+
|
11
|
+
def <<(output)
|
12
|
+
@streams.each do |s|
|
13
|
+
s << output
|
14
|
+
s.flush
|
15
|
+
end
|
16
|
+
self
|
17
|
+
end
|
18
|
+
end # Tee
|
19
|
+
|
20
|
+
@@logfile = File.join(ENV['HOME'], 'ey.log')
|
21
|
+
def self.logfile=(filename)
|
22
|
+
File.unlink filename if File.exist?(filename) # start fresh
|
23
|
+
@@logfile = filename
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.logfile
|
27
|
+
@@logfile
|
28
|
+
end
|
29
|
+
|
30
|
+
@@verbose = false
|
31
|
+
def self.verbose=(v)
|
32
|
+
@@verbose = !!v
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.verbose?
|
36
|
+
@@verbose
|
37
|
+
end
|
38
|
+
|
39
|
+
def verbose?
|
40
|
+
EY::LoggedOutput.verbose?
|
41
|
+
end
|
42
|
+
|
43
|
+
def info(msg)
|
44
|
+
with_logfile do |log|
|
45
|
+
Tee.new($stdout, log) << (msg + "\n")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def debug(msg)
|
50
|
+
with_logfile do |log|
|
51
|
+
log << "#{msg}\n"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def logged_system(cmd)
|
56
|
+
with_logfile do |log|
|
57
|
+
out = verbose? ? Tee.new($stdout, log) : log
|
58
|
+
err = Tee.new($stderr, log) # we always want to see errors
|
59
|
+
|
60
|
+
out << ":: running #{cmd}\n"
|
61
|
+
|
62
|
+
# :quiet means don't raise an error on nonzero exit status
|
63
|
+
status = Open4.spawn cmd, 0 => '', 1 => out, 2 => err, :quiet => true
|
64
|
+
status.exitstatus == 0
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
def with_logfile
|
70
|
+
File.open(logfile, 'a') {|f| yield f }
|
71
|
+
end
|
72
|
+
|
73
|
+
def logfile
|
74
|
+
EY::LoggedOutput.logfile
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'engineyard-serverside/logged_output'
|
3
|
+
|
4
|
+
module EY
|
5
|
+
class Server < Struct.new(:hostname, :role, :name)
|
6
|
+
include LoggedOutput
|
7
|
+
|
8
|
+
def initialize(*fields)
|
9
|
+
super
|
10
|
+
self.role = self.role.to_sym
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.config=(config)
|
14
|
+
@@config = config
|
15
|
+
end
|
16
|
+
|
17
|
+
def config
|
18
|
+
@@config
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_writer :default_task
|
22
|
+
|
23
|
+
def self.from_roles(*roles)
|
24
|
+
roles = roles.flatten.compact
|
25
|
+
return all if !roles || roles.include?(:all) || roles.empty?
|
26
|
+
|
27
|
+
all.select do |s|
|
28
|
+
roles.include?(s.role) || roles.include?(s.name)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.from_hash(h)
|
33
|
+
new(h[:hostname], h[:role], h[:name])
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.all
|
37
|
+
@all
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.all=(server_hashes)
|
41
|
+
@all = server_hashes.map { |s| from_hash(s) }
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.current
|
45
|
+
all.find {|s| s.local? }
|
46
|
+
end
|
47
|
+
|
48
|
+
def local?
|
49
|
+
[:app_master, :solo].include?(role)
|
50
|
+
end
|
51
|
+
|
52
|
+
def push_code
|
53
|
+
return if local?
|
54
|
+
run "mkdir -p #{config.repository_cache}"
|
55
|
+
logged_system(%|rsync --delete -aq -e "#{ssh_command}" #{config.repository_cache}/ #{config.user}@#{hostname}:#{config.repository_cache}|)
|
56
|
+
end
|
57
|
+
|
58
|
+
def run(command)
|
59
|
+
if local?
|
60
|
+
logged_system(command)
|
61
|
+
else
|
62
|
+
logged_system(ssh_command + " " + Escape.shell_command(["#{config.user}@#{hostname}", command]))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def ssh_command
|
67
|
+
"ssh -i #{ENV['HOME']}/.ssh/internal -o StrictHostKeyChecking=no -o PasswordAuthentication=no"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'engineyard-serverside/logged_output'
|
2
|
+
|
3
|
+
module EY
|
4
|
+
module Strategies
|
5
|
+
class Git
|
6
|
+
module Helpers
|
7
|
+
def update_repository_cache
|
8
|
+
strategy.fetch
|
9
|
+
unless strategy.checkout
|
10
|
+
abort "*** [Error] Git could not checkout (#{strategy.to_checkout}) ***"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_revision_file_command
|
15
|
+
strategy.create_revision_file_command(c.release_path)
|
16
|
+
end
|
17
|
+
|
18
|
+
def short_log_message(revision)
|
19
|
+
strategy.short_log_message(revision)
|
20
|
+
end
|
21
|
+
|
22
|
+
def strategy
|
23
|
+
klass = Module.nesting[1]
|
24
|
+
# Use [] to access attributes instead of calling methods so
|
25
|
+
# that we get nils instead of NoMethodError.
|
26
|
+
#
|
27
|
+
# Rollback doesn't know about the repository location (nor
|
28
|
+
# should it need to), but it would like to use #short_log_message.
|
29
|
+
klass.new(
|
30
|
+
:repository_cache => c[:repository_cache],
|
31
|
+
:app => c[:app],
|
32
|
+
:repo => c[:repo],
|
33
|
+
:ref => c[:branch]
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
include LoggedOutput
|
39
|
+
|
40
|
+
attr_reader :opts
|
41
|
+
|
42
|
+
def initialize(opts)
|
43
|
+
@opts = opts
|
44
|
+
set_up_git_ssh(@opts[:app])
|
45
|
+
end
|
46
|
+
|
47
|
+
def usable_repository?
|
48
|
+
File.directory?(opts[:repository_cache]) && `#{git} remote -v | grep origin`[opts[:repo]]
|
49
|
+
end
|
50
|
+
|
51
|
+
def fetch
|
52
|
+
if usable_repository?
|
53
|
+
logged_system("#{git} fetch -q origin 2>&1")
|
54
|
+
else
|
55
|
+
FileUtils.rm_rf(opts[:repository_cache])
|
56
|
+
logged_system("git clone -q #{opts[:repo]} #{opts[:repository_cache]} 2>&1")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def checkout
|
61
|
+
info "~> Deploying revision #{short_log_message(to_checkout)}"
|
62
|
+
in_git_work_tree do
|
63
|
+
(logged_system("git checkout -q '#{to_checkout}'") ||
|
64
|
+
logged_system("git reset -q --hard '#{to_checkout}'")) &&
|
65
|
+
logged_system("git submodule update --init") &&
|
66
|
+
logged_system("git clean -dfq")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_checkout
|
71
|
+
return @to_checkout if @opts_ref == opts[:ref]
|
72
|
+
@opts_ref = opts[:ref]
|
73
|
+
@to_checkout = if branch?(opts[:ref])
|
74
|
+
"origin/#{opts[:ref]}"
|
75
|
+
else
|
76
|
+
opts[:ref]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def create_revision_file_command(dir)
|
81
|
+
%Q{#{git} show --pretty=format:"%H" | head -1 > "#{dir}/REVISION"}
|
82
|
+
end
|
83
|
+
|
84
|
+
def short_log_message(rev)
|
85
|
+
`#{git} log --pretty=oneline --abbrev-commit '#{rev}^..#{rev}'`.strip
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
def in_git_work_tree
|
90
|
+
Dir.chdir(git_work_tree) { yield }
|
91
|
+
end
|
92
|
+
|
93
|
+
def git_work_tree
|
94
|
+
opts[:repository_cache]
|
95
|
+
end
|
96
|
+
|
97
|
+
def git
|
98
|
+
"git --git-dir #{git_work_tree}/.git --work-tree #{git_work_tree}"
|
99
|
+
end
|
100
|
+
|
101
|
+
def branch?(ref)
|
102
|
+
`#{git} branch -r`.map { |x| x.strip }.include?("origin/#{ref}")
|
103
|
+
end
|
104
|
+
|
105
|
+
def set_up_git_ssh(app)
|
106
|
+
# hold references to the tempfiles so they don't get finalized
|
107
|
+
# unexpectedly; tempfile finalization unlinks the files
|
108
|
+
@git_ssh = Tempfile.open("git-ssh")
|
109
|
+
@config = Tempfile.open("git-ssh-config")
|
110
|
+
|
111
|
+
@config.write "StrictHostKeyChecking no\n"
|
112
|
+
@config.write "CheckHostIP no\n"
|
113
|
+
@config.write "PasswordAuthentication no\n"
|
114
|
+
@config.write "LogLevel DEBUG\n"
|
115
|
+
@config.write "IdentityFile ~/.ssh/#{app}-deploy-key\n"
|
116
|
+
@config.chmod(0600)
|
117
|
+
@config.close
|
118
|
+
|
119
|
+
@git_ssh.write "#!/bin/sh\n"
|
120
|
+
@git_ssh.write "unset SSH_AUTH_SOCK\n"
|
121
|
+
@git_ssh.write "ssh -F \"#{@config.path}\" $*\n"
|
122
|
+
@git_ssh.chmod(0700)
|
123
|
+
# NB: this file _must_ be closed before git looks at it.
|
124
|
+
#
|
125
|
+
# Linux won't let you execve a file that's open for writing,
|
126
|
+
# so if this file stays open, then git will complain about
|
127
|
+
# being unable to exec it and will exit with a message like
|
128
|
+
#
|
129
|
+
# fatal: exec /tmp/git-ssh20100417-21417-d040rm-0 failed.
|
130
|
+
@git_ssh.close
|
131
|
+
|
132
|
+
ENV['GIT_SSH'] = @git_ssh.path
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module EY
|
2
|
+
class Task
|
3
|
+
include Dataflow
|
4
|
+
|
5
|
+
attr_reader :config
|
6
|
+
alias :c :config
|
7
|
+
|
8
|
+
def initialize(conf)
|
9
|
+
@config = conf
|
10
|
+
@roles = :all
|
11
|
+
end
|
12
|
+
|
13
|
+
def require_custom_tasks
|
14
|
+
deploy_file = ["config/eydeploy.rb", "eydeploy.rb"].map do |short_file|
|
15
|
+
File.join(c.repository_cache, short_file)
|
16
|
+
end.detect do |file|
|
17
|
+
File.exist?(file)
|
18
|
+
end
|
19
|
+
|
20
|
+
if deploy_file
|
21
|
+
puts "~> Loading deployment task overrides from #{deploy_file}"
|
22
|
+
instance_eval(File.read(deploy_file))
|
23
|
+
true
|
24
|
+
else
|
25
|
+
false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def roles(*task_roles)
|
30
|
+
raise "Roles must be passed a block" unless block_given?
|
31
|
+
|
32
|
+
begin
|
33
|
+
@roles = task_roles
|
34
|
+
yield
|
35
|
+
ensure
|
36
|
+
@roles = :all
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def run(cmd, &blk)
|
41
|
+
run_on_roles(cmd, &blk)
|
42
|
+
end
|
43
|
+
|
44
|
+
def sudo(cmd, &blk)
|
45
|
+
run_on_roles(cmd, %w[sudo sh -l -c], &blk)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def run_on_roles(cmd, wrapper=%w[sh -l -c])
|
51
|
+
results = EY::Server.from_roles(@roles).map do |server|
|
52
|
+
to_run = block_given? ? yield(server, cmd.dup) : cmd
|
53
|
+
need_later { server.run(Escape.shell_command(wrapper + [to_run])) }
|
54
|
+
end
|
55
|
+
barrier *results
|
56
|
+
# MRI's truthiness check is an internal C thing that does not call
|
57
|
+
# any methods... so Dataflow cannot proxy it & we must "x == true"
|
58
|
+
# Rubinius, wherefore art thou!?
|
59
|
+
results.all?{|x| x == true } || raise(EY::RemoteFailure)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|