engineyard-serverside 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|