engineyard-serverside 1.4.12 → 1.4.13
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/lib/engineyard-serverside/deploy.rb +15 -5
- data/lib/engineyard-serverside/deprecation.rb +4 -5
- data/lib/engineyard-serverside/lockfile_parser.rb +4 -1
- data/lib/engineyard-serverside/strategies/git.rb +5 -1
- data/lib/engineyard-serverside/version.rb +1 -1
- data/lib/vendor/dataflow/dataflow.rb +10 -6
- data/lib/vendor/dataflow/dataflow/equality.rb +22 -6
- data/lib/vendor/dataflow/spec/equality_spec.rb +1 -1
- data/spec/basic_deploy_spec.rb +47 -0
- data/spec/bundler_deploy_spec.rb +107 -0
- data/spec/custom_deploy_spec.rb +1 -1
- data/spec/deploy_hook_spec.rb +1 -1
- data/spec/deprecation_spec.rb +37 -17
- data/spec/git_strategy_spec.rb +1 -1
- data/spec/lockfile_parser_spec.rb +1 -1
- data/spec/restart_spec.rb +1 -1
- data/spec/server_spec.rb +1 -1
- data/spec/spec_helper.rb +15 -2
- data/spec/support/integration.rb +139 -0
- metadata +17 -15
- data/spec/fixtures/gitrepo/bar +0 -0
- data/spec/real_deploy_spec.rb +0 -219
@@ -137,7 +137,7 @@ module EY
|
|
137
137
|
get_bundler_installer(lockfile)
|
138
138
|
else
|
139
139
|
warn_about_missing_lockfile
|
140
|
-
|
140
|
+
get_default_bundler_installer
|
141
141
|
end
|
142
142
|
|
143
143
|
sudo "#{serverside_bin} install_bundler #{bundler_installer.version}"
|
@@ -320,7 +320,7 @@ module EY
|
|
320
320
|
info "!> Fix this by running \"git add Gemfile.lock; git commit\" and deploying again."
|
321
321
|
info "!> If you don't have a Gemfile.lock, run \"bundle lock\" to create one."
|
322
322
|
info "!>"
|
323
|
-
info "!> This deployment will use bundler #{
|
323
|
+
info "!> This deployment will use bundler #{LockfileParser.default_version} to run 'bundle install'."
|
324
324
|
info "!>"
|
325
325
|
end
|
326
326
|
|
@@ -337,13 +337,23 @@ module EY
|
|
337
337
|
end
|
338
338
|
public :get_bundler_installer
|
339
339
|
|
340
|
+
def get_default_bundler_installer
|
341
|
+
# deployment mode is not supported without a Gemfile.lock, so we turn that off.
|
342
|
+
bundler_10_installer(LockfileParser.default_version, deployment_mode = false)
|
343
|
+
end
|
344
|
+
public :get_default_bundler_installer
|
345
|
+
|
340
346
|
def bundler_09_installer(version)
|
341
347
|
BundleInstaller.new(version, '--without=development --without=test')
|
342
348
|
end
|
343
349
|
|
344
|
-
|
345
|
-
|
346
|
-
|
350
|
+
# Set +deploymemt_mode+ to false to avoid passing the --deployment flag.
|
351
|
+
def bundler_10_installer(version, deployment_mode = true)
|
352
|
+
options = ["--path #{c.shared_path}/bundled_gems",
|
353
|
+
"--binstubs #{c.binstubs_path}",
|
354
|
+
"--without development test"]
|
355
|
+
options.unshift('--deployment') if deployment_mode
|
356
|
+
BundleInstaller.new(version, options.join(' '))
|
347
357
|
end
|
348
358
|
end # DeployBase
|
349
359
|
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module EY
|
2
2
|
module Serverside
|
3
3
|
def self.deprecation_warning(msg)
|
4
|
-
|
4
|
+
$stderr.puts "DEPRECATION WARNING: #{msg}"
|
5
5
|
end
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
def self.const_missing(const)
|
9
9
|
if EY::Serverside.const_defined?(const)
|
10
10
|
EY::Serverside.deprecation_warning("EY::#{const} has been deprecated. use EY::Serverside::#{const} instead")
|
@@ -13,7 +13,7 @@ module EY
|
|
13
13
|
super
|
14
14
|
end
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
def self.node
|
18
18
|
EY::Serverside.deprecation_warning("EY.node has been deprecated. use EY::Serverside.node instead")
|
19
19
|
EY::Serverside.node
|
@@ -23,5 +23,4 @@ module EY
|
|
23
23
|
EY::Serverside.deprecation_warning("EY.dna_json has been deprecated. use EY::Serverside.dna_json instead")
|
24
24
|
EY::Serverside.dna_json
|
25
25
|
end
|
26
|
-
|
27
|
-
end
|
26
|
+
end
|
@@ -2,6 +2,9 @@ require 'yaml'
|
|
2
2
|
module EY
|
3
3
|
module Serverside
|
4
4
|
class LockfileParser
|
5
|
+
def self.default_version
|
6
|
+
Parse10::DEFAULT
|
7
|
+
end
|
5
8
|
|
6
9
|
attr_reader :bundler_version, :lockfile_version
|
7
10
|
|
@@ -37,7 +40,7 @@ module EY
|
|
37
40
|
end
|
38
41
|
def safe_yaml_load(loadable)
|
39
42
|
YAML.load(loadable) #won't always raise... soemtimes parses the contents as 1 big string
|
40
|
-
rescue ArgumentError
|
43
|
+
rescue ArgumentError, SyntaxError # not yaml
|
41
44
|
nil
|
42
45
|
end
|
43
46
|
end
|
@@ -101,7 +101,11 @@ module EY
|
|
101
101
|
end
|
102
102
|
|
103
103
|
def branch?(ref)
|
104
|
-
`#{git} branch -r
|
104
|
+
remote_branches = `#{git} branch -r`
|
105
|
+
remote_branches.each_line do |line|
|
106
|
+
return true if line.include?("origin/#{ref}")
|
107
|
+
end
|
108
|
+
false
|
105
109
|
end
|
106
110
|
|
107
111
|
def set_up_git_ssh(app)
|
@@ -6,7 +6,7 @@ module Dataflow
|
|
6
6
|
attr_accessor :forker
|
7
7
|
end
|
8
8
|
self.forker = Thread.method(:fork)
|
9
|
-
|
9
|
+
|
10
10
|
def self.included(cls)
|
11
11
|
class << cls
|
12
12
|
def declare(*readers)
|
@@ -21,7 +21,7 @@ module Dataflow
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def local(&block)
|
26
26
|
return Variable.new unless block_given?
|
27
27
|
vars = Array.new(block.arity) { Variable.new }
|
@@ -60,13 +60,17 @@ module Dataflow
|
|
60
60
|
# initialized instance variables in get/set methods for memory and
|
61
61
|
# performance reasons
|
62
62
|
class Variable
|
63
|
-
|
63
|
+
# Briefly disable the warning we would get when undefining object_id.
|
64
|
+
# We actually rely on the ability to do that, so...
|
65
|
+
v = $VERBOSE; $VERBOSE = nil
|
66
|
+
instance_methods.each { |m| undef_method(m) unless m =~ /^__|instance_eval/ }
|
67
|
+
$VERBOSE = v # back to sanity
|
64
68
|
LOCK = Monitor.new
|
65
69
|
def initialize(&block) @__trigger__ = block if block_given? end
|
66
|
-
|
70
|
+
|
67
71
|
# Lazy-load conditions to be nice on memory usage
|
68
72
|
def __binding_condition__() @__binding_condition__ ||= LOCK.new_cond end
|
69
|
-
|
73
|
+
|
70
74
|
def __unify__(value)
|
71
75
|
LOCK.synchronize do
|
72
76
|
__activate_trigger__ if @__trigger__
|
@@ -91,7 +95,7 @@ module Dataflow
|
|
91
95
|
|
92
96
|
def __wait__
|
93
97
|
LOCK.synchronize do
|
94
|
-
unless @__bound__
|
98
|
+
unless @__bound__
|
95
99
|
if @__trigger__
|
96
100
|
__activate_trigger__
|
97
101
|
else
|
@@ -6,23 +6,39 @@
|
|
6
6
|
# ears. Please run the rubyspec before committing changes to this file.
|
7
7
|
|
8
8
|
class Object
|
9
|
+
alias original_equality ==
|
10
|
+
|
9
11
|
def ==(other)
|
10
12
|
object_id == other.object_id
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
14
16
|
class Symbol
|
17
|
+
alias original_equality ==
|
18
|
+
|
15
19
|
def ==(other)
|
16
20
|
object_id == other.object_id
|
17
21
|
end
|
18
22
|
end
|
19
23
|
|
20
24
|
class Regexp
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
alias original_equality ==
|
26
|
+
|
27
|
+
if /lol/.respond_to?(:encoding)
|
28
|
+
def ==(other)
|
29
|
+
other.is_a?(Regexp) &&
|
30
|
+
casefold? == other.casefold? &&
|
31
|
+
encoding == other.encoding &&
|
32
|
+
options == other.options &&
|
33
|
+
source == other.source
|
34
|
+
end
|
35
|
+
else
|
36
|
+
def ==(other)
|
37
|
+
other.is_a?(Regexp) &&
|
38
|
+
casefold? == other.casefold? &&
|
39
|
+
kcode == other.kcode &&
|
40
|
+
options == other.options &&
|
41
|
+
source == other.source
|
42
|
+
end
|
27
43
|
end
|
28
44
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Deploying an application without Bundler" do
|
4
|
+
before(:all) do
|
5
|
+
$DISABLE_GEMFILE = true # Don't generate Gemfile/Gemfile.lock
|
6
|
+
$DISABLE_LOCKFILE = true
|
7
|
+
@deploy_dir = File.join(Dir.tmpdir, "serverside-deploy-#{Time.now.to_i}-#{$$}")
|
8
|
+
|
9
|
+
# set up EY::Serverside::Server like we're on a solo
|
10
|
+
EY::Serverside::Server.reset
|
11
|
+
EY::Serverside::Server.add(:hostname => 'localhost', :roles => %w[solo])
|
12
|
+
|
13
|
+
# run a deploy
|
14
|
+
config = EY::Serverside::Deploy::Configuration.new({
|
15
|
+
"strategy" => "IntegrationSpec",
|
16
|
+
"deploy_to" => @deploy_dir,
|
17
|
+
"group" => `id -gn`.strip,
|
18
|
+
"stack" => 'nginx_passenger',
|
19
|
+
"migrate" => nil,
|
20
|
+
'app' => 'foo',
|
21
|
+
'framework_env' => 'staging'
|
22
|
+
})
|
23
|
+
|
24
|
+
@binpath = File.expand_path(File.join(File.dirname(__FILE__), '..', 'bin', 'engineyard-serverside'))
|
25
|
+
@deployer = FullTestDeploy.new(config)
|
26
|
+
@deployer.deploy
|
27
|
+
end
|
28
|
+
|
29
|
+
it "creates a REVISION file" do
|
30
|
+
File.exist?(File.join(@deploy_dir, 'current', 'REVISION')).should be_true
|
31
|
+
end
|
32
|
+
|
33
|
+
it "restarts the app servers" do
|
34
|
+
File.exist?(File.join(@deploy_dir, 'current', 'restart')).should be_true
|
35
|
+
end
|
36
|
+
|
37
|
+
it "runs all the hooks" do
|
38
|
+
File.exist?(File.join(@deploy_dir, 'current', 'before_bundle.ran' )).should be_true
|
39
|
+
File.exist?(File.join(@deploy_dir, 'current', 'after_bundle.ran' )).should be_true
|
40
|
+
File.exist?(File.join(@deploy_dir, 'current', 'before_migrate.ran')).should be_true
|
41
|
+
File.exist?(File.join(@deploy_dir, 'current', 'after_migrate.ran' )).should be_true
|
42
|
+
File.exist?(File.join(@deploy_dir, 'current', 'before_symlink.ran')).should be_true
|
43
|
+
File.exist?(File.join(@deploy_dir, 'current', 'after_symlink.ran' )).should be_true
|
44
|
+
File.exist?(File.join(@deploy_dir, 'current', 'before_restart.ran')).should be_true
|
45
|
+
File.exist?(File.join(@deploy_dir, 'current', 'after_restart.ran' )).should be_true
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Deploying an application that uses Bundler" do
|
4
|
+
def deploy_test_application
|
5
|
+
@deploy_dir = File.join(Dir.tmpdir, "serverside-deploy-#{Time.now.to_i}-#{$$}")
|
6
|
+
|
7
|
+
# set up EY::Serverside::Server like we're on a solo
|
8
|
+
EY::Serverside::Server.reset
|
9
|
+
EY::Serverside::Server.add(:hostname => 'localhost', :roles => %w[solo])
|
10
|
+
|
11
|
+
# run a deploy
|
12
|
+
config = EY::Serverside::Deploy::Configuration.new({
|
13
|
+
"strategy" => "IntegrationSpec",
|
14
|
+
"deploy_to" => @deploy_dir,
|
15
|
+
"group" => `id -gn`.strip,
|
16
|
+
"stack" => 'nginx_passenger',
|
17
|
+
"migrate" => "ruby -e 'puts ENV[\"PATH\"]' > #{@deploy_dir}/path-when-migrating",
|
18
|
+
'app' => 'foo',
|
19
|
+
'framework_env' => 'staging'
|
20
|
+
})
|
21
|
+
|
22
|
+
# pretend there is a shared bundled_gems directory
|
23
|
+
FileUtils.mkdir_p(File.join(@deploy_dir, 'shared', 'bundled_gems'))
|
24
|
+
%w(RUBY_VERSION SYSTEM_VERSION).each do |name|
|
25
|
+
File.open(File.join(@deploy_dir, 'shared', 'bundled_gems', name), "w") { |f| f.write("old\n") }
|
26
|
+
end
|
27
|
+
|
28
|
+
@binpath = File.expand_path(File.join(File.dirname(__FILE__), '..', 'bin', 'engineyard-serverside'))
|
29
|
+
@deployer = FullTestDeploy.new(config)
|
30
|
+
@deployer.deploy
|
31
|
+
end
|
32
|
+
|
33
|
+
context "with a Gemfile.lock" do
|
34
|
+
before(:all) do
|
35
|
+
$DISABLE_GEMFILE = false
|
36
|
+
$DISABLE_LOCKFILE = false
|
37
|
+
deploy_test_application
|
38
|
+
end
|
39
|
+
|
40
|
+
it "runs the right bundler command" do
|
41
|
+
install_bundler_command_ran = @deployer.commands.detect{ |command| command.index("install_bundler") }
|
42
|
+
install_bundler_command_ran.should_not be_nil
|
43
|
+
install_bundler_command_ran.should == "#{@binpath} install_bundler 1.0.10"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "runs 'bundle install' with --deployment" do
|
47
|
+
bundle_install_cmd = @deployer.commands.grep(/bundle _\S+_ install/).first
|
48
|
+
bundle_install_cmd.should_not be_nil
|
49
|
+
bundle_install_cmd.should include('--deployment')
|
50
|
+
end
|
51
|
+
|
52
|
+
it "removes bundled_gems directory if the ruby version changed" do
|
53
|
+
clear_bundle_cmd = @deployer.commands.grep(/rm -Rf \S+\/bundled_gems/).first
|
54
|
+
clear_bundle_cmd.should_not be_nil
|
55
|
+
end
|
56
|
+
|
57
|
+
it "removes bundled_gems directory if the system version changed" do
|
58
|
+
clear_bundle_cmd = @deployer.commands.grep(/rm -Rf \S+\/bundled_gems/).first
|
59
|
+
clear_bundle_cmd.should_not be_nil
|
60
|
+
end
|
61
|
+
|
62
|
+
it "has the binstubs in the path when migrating" do
|
63
|
+
File.read(File.join(@deploy_dir, 'path-when-migrating')).should include('ey_bundler_binstubs')
|
64
|
+
end
|
65
|
+
|
66
|
+
it "creates a ruby version file" do
|
67
|
+
File.exist?(File.join(@deploy_dir, 'shared', 'bundled_gems', 'RUBY_VERSION')).should be_true
|
68
|
+
end
|
69
|
+
|
70
|
+
it "creates a system version file" do
|
71
|
+
File.exist?(File.join(@deploy_dir, 'shared', 'bundled_gems', 'SYSTEM_VERSION')).should be_true
|
72
|
+
end
|
73
|
+
|
74
|
+
it "generates bundler binstubs" do
|
75
|
+
File.exist?(File.join(@deploy_dir, 'current', 'ey_bundler_binstubs', 'rake')).should be_true
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "without a Gemfile.lock" do
|
80
|
+
before(:all) do
|
81
|
+
$DISABLE_GEMFILE = false
|
82
|
+
$DISABLE_LOCKFILE = true
|
83
|
+
deploy_test_application
|
84
|
+
end
|
85
|
+
|
86
|
+
it "default to Bundler 1.0.10" do
|
87
|
+
install_bundler_command_ran = @deployer.commands.detect{ |command| command.index("install_bundler") }
|
88
|
+
install_bundler_command_ran.should_not be_nil
|
89
|
+
install_bundler_command_ran.should == "#{@binpath} install_bundler 1.0.10"
|
90
|
+
end
|
91
|
+
|
92
|
+
it "runs 'bundle install' without --deployment" do
|
93
|
+
bundle_install_cmd = @deployer.commands.grep(/bundle _\S+_ install/).first
|
94
|
+
bundle_install_cmd.should_not be_nil
|
95
|
+
bundle_install_cmd.should_not include('--deployment')
|
96
|
+
end
|
97
|
+
|
98
|
+
it "creates a ruby version file" do
|
99
|
+
File.exist?(File.join(@deploy_dir, 'shared', 'bundled_gems', 'RUBY_VERSION')).should be_true
|
100
|
+
end
|
101
|
+
|
102
|
+
it "creates a system version file" do
|
103
|
+
File.exist?(File.join(@deploy_dir, 'shared', 'bundled_gems', 'SYSTEM_VERSION')).should be_true
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
data/spec/custom_deploy_spec.rb
CHANGED
data/spec/deploy_hook_spec.rb
CHANGED
data/spec/deprecation_spec.rb
CHANGED
@@ -1,25 +1,45 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stringio'
|
2
3
|
|
3
4
|
describe EY::Serverside do
|
4
|
-
|
5
|
+
before do
|
6
|
+
@original_stderr = $stderr
|
7
|
+
@warnings = StringIO.new
|
8
|
+
$stderr = @warnings
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
$stderr = @original_stderr
|
13
|
+
end
|
14
|
+
|
15
|
+
def check_deprecation(new_const, prints_warning = true)
|
16
|
+
old_name = new_const.to_s.gsub('EY::Serverside::', 'EY::')
|
17
|
+
eval(old_name).should == new_const
|
18
|
+
@warnings.string.should include(old_name) if prints_warning
|
19
|
+
end
|
20
|
+
|
5
21
|
it "preserves the old constants" do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
EY::DeployBase.should == EY::Serverside::DeployBase
|
10
|
-
EY::Deploy::Configuration.should == EY::Serverside::Deploy::Configuration
|
11
|
-
EY::DeployHook.should == EY::Serverside::DeployHook
|
12
|
-
EY::LockfileParser.should == EY::Serverside::LockfileParser
|
13
|
-
EY::LoggedOutput.should == EY::Serverside::LoggedOutput
|
14
|
-
EY::Server.should == EY::Serverside::Server
|
15
|
-
EY::Task.should == EY::Serverside::Task
|
16
|
-
EY::Strategies.should == EY::Serverside::Strategies
|
17
|
-
EY::Strategies::Git.should == EY::Serverside::Strategies::Git
|
18
|
-
|
19
|
-
lambda{ EY::WTFNotDefined }.should raise_error(NameError, /uninitialized constant EY::WTFNotDefined/)
|
22
|
+
names = %w[BundleInstaller CLI Deploy DeployBase Deploy::Configuration
|
23
|
+
DeployHook LockfileParser LoggedOutput Server Task
|
24
|
+
Strategies Strategies::Git]
|
20
25
|
|
21
|
-
|
26
|
+
names.map do |name|
|
27
|
+
const = eval("::EY::Serverside::#{name}")
|
28
|
+
# The way deprecations are implemented currently, we don't print
|
29
|
+
# warning messages for constants that aren't directly under EY::
|
30
|
+
prints_warning = name.include?('::') ? false : true
|
31
|
+
check_deprecation(const, prints_warning)
|
32
|
+
end
|
33
|
+
end
|
22
34
|
|
35
|
+
it "deprecates EY.dna_json and EY.node" do
|
36
|
+
EY.dna_json.should == EY::Serverside.dna_json
|
37
|
+
@warnings.string.should include("EY.dna_json")
|
38
|
+
EY.node.should == EY::Serverside.node
|
39
|
+
@warnings.string.should include("EY.node")
|
23
40
|
end
|
24
41
|
|
42
|
+
it "doesn't interfere with unrelated constants" do
|
43
|
+
lambda{ EY::WTFNotDefined }.should raise_error(NameError, /uninitialized constant.*EY::WTFNotDefined/)
|
44
|
+
end
|
25
45
|
end
|
data/spec/git_strategy_spec.rb
CHANGED
data/spec/restart_spec.rb
CHANGED
data/spec/server_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
$LOAD_PATH.push File.expand_path("../lib", File.dirname(__FILE__))
|
2
2
|
|
3
|
-
Bundler
|
3
|
+
if defined?(Bundler)
|
4
|
+
Bundler.require :default, :test
|
5
|
+
else
|
6
|
+
require 'rubygems'
|
7
|
+
end
|
8
|
+
|
4
9
|
require 'pp'
|
5
10
|
require 'engineyard-serverside'
|
11
|
+
require File.expand_path('../support/integration', __FILE__)
|
6
12
|
|
7
13
|
module EY
|
8
14
|
module Serverside
|
@@ -15,7 +21,12 @@ module EY
|
|
15
21
|
def info(_) end
|
16
22
|
|
17
23
|
def logged_system(cmd)
|
18
|
-
|
24
|
+
output = `#{cmd} 2>&1`
|
25
|
+
successful = ($? == 0)
|
26
|
+
if ENV['VERBOSE'] && !successful
|
27
|
+
$stderr.puts "\nCommand `#{cmd}` exited with status #{$?.exitstatus}: '#{output.strip}'"
|
28
|
+
end
|
29
|
+
successful
|
19
30
|
end
|
20
31
|
end
|
21
32
|
|
@@ -33,6 +44,8 @@ Kernel.system "tar xzf #{GITREPO_DIR}.tar.gz -C #{FIXTURES_DIR}"
|
|
33
44
|
|
34
45
|
Spec::Runner.configure do |config|
|
35
46
|
config.before(:all) do
|
47
|
+
$DISABLE_GEMFILE = false
|
48
|
+
$DISABLE_LOCKFILE = false
|
36
49
|
EY::Serverside.dna_json = {}.to_json
|
37
50
|
end
|
38
51
|
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
class FullTestDeploy < EY::Serverside::Deploy
|
2
|
+
attr_reader :infos, :debugs, :commands
|
3
|
+
|
4
|
+
def initialize(*)
|
5
|
+
super
|
6
|
+
@infos = []
|
7
|
+
@debugs = []
|
8
|
+
@commands = []
|
9
|
+
end
|
10
|
+
|
11
|
+
# stfu
|
12
|
+
def info(msg)
|
13
|
+
@infos << msg
|
14
|
+
end
|
15
|
+
|
16
|
+
# no really, stfu
|
17
|
+
def debug(msg)
|
18
|
+
@debugs << msg
|
19
|
+
end
|
20
|
+
|
21
|
+
# passwordless sudo is neither guaranteed nor desired
|
22
|
+
def sudo(cmd)
|
23
|
+
run(cmd)
|
24
|
+
end
|
25
|
+
|
26
|
+
def run(cmd)
|
27
|
+
@commands << cmd
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
def version_specifier
|
32
|
+
# Normally, the deploy task invokes the hook task by executing
|
33
|
+
# the rubygems-generated wrapper (it's what's in $PATH). It
|
34
|
+
# specifies the version to make sure that the pieces don't get
|
35
|
+
# out of sync. However, in test mode, there's no
|
36
|
+
# rubygems-generated wrapper, and so the hook task doesn't get
|
37
|
+
# run because thor thinks we're trying to invoke the _$VERSION_
|
38
|
+
# task instead, which doesn't exist.
|
39
|
+
#
|
40
|
+
# By stripping that out, we can get the hooks to actually run
|
41
|
+
# inside this test.
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def restart
|
46
|
+
FileUtils.touch("#{c.release_path}/restart")
|
47
|
+
end
|
48
|
+
|
49
|
+
# we're probably running this spec under bundler, but a real
|
50
|
+
# deploy does not
|
51
|
+
def bundle
|
52
|
+
my_env = ENV.to_hash
|
53
|
+
|
54
|
+
ENV.delete("BUNDLE_GEMFILE")
|
55
|
+
ENV.delete("BUNDLE_BIN_PATH")
|
56
|
+
|
57
|
+
result = super
|
58
|
+
|
59
|
+
ENV.replace(my_env)
|
60
|
+
result
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_bundler_installer(lockfile)
|
64
|
+
installer = super
|
65
|
+
installer.options << ' --quiet' # stfu already!
|
66
|
+
installer
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
module EY::Serverside::Strategies::IntegrationSpec
|
71
|
+
module Helpers
|
72
|
+
|
73
|
+
def update_repository_cache
|
74
|
+
cached_copy = File.join(c.shared_path, 'cached-copy')
|
75
|
+
|
76
|
+
deploy_hook_dir = File.join(cached_copy, 'deploy')
|
77
|
+
FileUtils.mkdir_p(deploy_hook_dir)
|
78
|
+
%w[bundle migrate symlink restart].each do |action|
|
79
|
+
%w[before after].each do |prefix|
|
80
|
+
hook = "#{prefix}_#{action}"
|
81
|
+
File.open(File.join(deploy_hook_dir, "#{hook}.rb"), 'w') do |f|
|
82
|
+
f.write(%Q{run 'touch "#{c.release_path}/#{hook}.ran"'})
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
FileUtils.mkdir_p(File.join(c.shared_path, 'config'))
|
88
|
+
FileUtils.mkdir_p(cached_copy)
|
89
|
+
generate_gemfile_in(cached_copy)
|
90
|
+
end
|
91
|
+
|
92
|
+
def create_revision_file_command
|
93
|
+
"echo 'revision, yo' > #{c.release_path}/REVISION"
|
94
|
+
end
|
95
|
+
|
96
|
+
def short_log_message(revision)
|
97
|
+
"FONDLED THE CODE"
|
98
|
+
end
|
99
|
+
|
100
|
+
def gemfile_contents
|
101
|
+
<<-EOF
|
102
|
+
source :gemcutter
|
103
|
+
|
104
|
+
gem "bundler", "~> 1.0.0.rc.6"
|
105
|
+
gem "rake"
|
106
|
+
EOF
|
107
|
+
end
|
108
|
+
|
109
|
+
def lockfile_contents
|
110
|
+
<<-EOF
|
111
|
+
GEM
|
112
|
+
remote: http://rubygems.org/
|
113
|
+
specs:
|
114
|
+
rake (0.8.7)
|
115
|
+
|
116
|
+
PLATFORMS
|
117
|
+
ruby
|
118
|
+
|
119
|
+
DEPENDENCIES
|
120
|
+
bundler (~> 1.0.0.rc.6)
|
121
|
+
rake
|
122
|
+
EOF
|
123
|
+
end
|
124
|
+
|
125
|
+
def generate_gemfile_in(dir)
|
126
|
+
`echo "this is my file; there are many like it, but this one is mine" > #{dir}/file`
|
127
|
+
gemfile_path = File.join(dir, 'Gemfile')
|
128
|
+
lockfile_path = File.join(dir, 'Gemfile.lock')
|
129
|
+
|
130
|
+
unless $DISABLE_GEMFILE
|
131
|
+
File.open(gemfile_path, 'w') {|f| f.write(gemfile_contents) }
|
132
|
+
end
|
133
|
+
unless $DISABLE_LOCKFILE
|
134
|
+
File.open(lockfile_path, 'w') {|f| f.write(lockfile_contents) }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: engineyard-serverside
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 1.4.
|
9
|
+
- 13
|
10
|
+
version: 1.4.13
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- EY Cloud Team
|
@@ -15,10 +15,13 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-09-
|
18
|
+
date: 2011-09-21 00:00:00 -07:00
|
19
19
|
default_executable: engineyard-serverside
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
|
+
prerelease: false
|
23
|
+
type: :development
|
24
|
+
name: rspec
|
22
25
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
23
26
|
none: false
|
24
27
|
requirements:
|
@@ -30,11 +33,11 @@ dependencies:
|
|
30
33
|
- 3
|
31
34
|
- 2
|
32
35
|
version: 1.3.2
|
33
|
-
name: rspec
|
34
|
-
prerelease: false
|
35
|
-
type: :development
|
36
36
|
requirement: *id001
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
|
+
prerelease: false
|
39
|
+
type: :development
|
40
|
+
name: rake
|
38
41
|
version_requirements: &id002 !ruby/object:Gem::Requirement
|
39
42
|
none: false
|
40
43
|
requirements:
|
@@ -44,9 +47,6 @@ dependencies:
|
|
44
47
|
segments:
|
45
48
|
- 0
|
46
49
|
version: "0"
|
47
|
-
name: rake
|
48
|
-
prerelease: false
|
49
|
-
type: :development
|
50
50
|
requirement: *id002
|
51
51
|
description:
|
52
52
|
email: cloud@engineyard.com
|
@@ -263,20 +263,21 @@ files:
|
|
263
263
|
- lib/vendor/thor/thor.gemspec
|
264
264
|
- lib/vendor/thor/Thorfile
|
265
265
|
- LICENSE
|
266
|
+
- spec/basic_deploy_spec.rb
|
267
|
+
- spec/bundler_deploy_spec.rb
|
266
268
|
- spec/custom_deploy_spec.rb
|
267
269
|
- spec/deploy_hook_spec.rb
|
268
270
|
- spec/deprecation_spec.rb
|
269
|
-
- spec/fixtures/gitrepo/bar
|
270
271
|
- spec/fixtures/gitrepo/foo
|
271
272
|
- spec/fixtures/gitrepo.tar.gz
|
272
273
|
- spec/fixtures/invalid_hook.rb
|
273
274
|
- spec/fixtures/valid_hook.rb
|
274
275
|
- spec/git_strategy_spec.rb
|
275
276
|
- spec/lockfile_parser_spec.rb
|
276
|
-
- spec/real_deploy_spec.rb
|
277
277
|
- spec/restart_spec.rb
|
278
278
|
- spec/server_spec.rb
|
279
279
|
- spec/spec_helper.rb
|
280
|
+
- spec/support/integration.rb
|
280
281
|
- spec/support/lockfiles/0.9-no-bundler
|
281
282
|
- spec/support/lockfiles/0.9-with-bundler
|
282
283
|
- spec/support/lockfiles/1.0-no-bundler
|
@@ -316,25 +317,26 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
316
317
|
requirements: []
|
317
318
|
|
318
319
|
rubyforge_project:
|
319
|
-
rubygems_version: 1.
|
320
|
+
rubygems_version: 1.5.2
|
320
321
|
signing_key:
|
321
322
|
specification_version: 3
|
322
323
|
summary: A gem that deploys ruby applications on EY Cloud instances
|
323
324
|
test_files:
|
325
|
+
- spec/basic_deploy_spec.rb
|
326
|
+
- spec/bundler_deploy_spec.rb
|
324
327
|
- spec/custom_deploy_spec.rb
|
325
328
|
- spec/deploy_hook_spec.rb
|
326
329
|
- spec/deprecation_spec.rb
|
327
|
-
- spec/fixtures/gitrepo/bar
|
328
330
|
- spec/fixtures/gitrepo/foo
|
329
331
|
- spec/fixtures/gitrepo.tar.gz
|
330
332
|
- spec/fixtures/invalid_hook.rb
|
331
333
|
- spec/fixtures/valid_hook.rb
|
332
334
|
- spec/git_strategy_spec.rb
|
333
335
|
- spec/lockfile_parser_spec.rb
|
334
|
-
- spec/real_deploy_spec.rb
|
335
336
|
- spec/restart_spec.rb
|
336
337
|
- spec/server_spec.rb
|
337
338
|
- spec/spec_helper.rb
|
339
|
+
- spec/support/integration.rb
|
338
340
|
- spec/support/lockfiles/0.9-no-bundler
|
339
341
|
- spec/support/lockfiles/0.9-with-bundler
|
340
342
|
- spec/support/lockfiles/1.0-no-bundler
|
data/spec/fixtures/gitrepo/bar
DELETED
File without changes
|
data/spec/real_deploy_spec.rb
DELETED
@@ -1,219 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
-
|
3
|
-
module EY::Serverside::Strategies::IntegrationSpec
|
4
|
-
module Helpers
|
5
|
-
|
6
|
-
def update_repository_cache
|
7
|
-
cached_copy = File.join(c.shared_path, 'cached-copy')
|
8
|
-
|
9
|
-
deploy_hook_dir = File.join(cached_copy, 'deploy')
|
10
|
-
FileUtils.mkdir_p(deploy_hook_dir)
|
11
|
-
%w[bundle migrate symlink restart].each do |action|
|
12
|
-
%w[before after].each do |prefix|
|
13
|
-
hook = "#{prefix}_#{action}"
|
14
|
-
File.open(File.join(deploy_hook_dir, "#{hook}.rb"), 'w') do |f|
|
15
|
-
f.write(%Q{run 'touch "#{c.release_path}/#{hook}.ran"'})
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
FileUtils.mkdir_p(File.join(c.shared_path, 'config'))
|
21
|
-
|
22
|
-
FileUtils.mkdir_p(cached_copy)
|
23
|
-
Dir.chdir(cached_copy) do
|
24
|
-
`echo "this is my file; there are many like it, but this one is mine" > file`
|
25
|
-
File.open('Gemfile', 'w') do |f|
|
26
|
-
f.write <<-EOF
|
27
|
-
source :gemcutter
|
28
|
-
|
29
|
-
gem "bundler", "~> 1.0.0.rc.6"
|
30
|
-
gem "rake"
|
31
|
-
EOF
|
32
|
-
end
|
33
|
-
|
34
|
-
File.open("Gemfile.lock", "w") do |f|
|
35
|
-
f.write <<-EOF
|
36
|
-
GEM
|
37
|
-
remote: http://rubygems.org/
|
38
|
-
specs:
|
39
|
-
rake (0.8.7)
|
40
|
-
|
41
|
-
PLATFORMS
|
42
|
-
ruby
|
43
|
-
|
44
|
-
DEPENDENCIES
|
45
|
-
bundler (~> 1.0.0.rc.6)
|
46
|
-
rake
|
47
|
-
EOF
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def create_revision_file_command
|
53
|
-
"echo 'revision, yo' > #{c.release_path}/REVISION"
|
54
|
-
end
|
55
|
-
|
56
|
-
def short_log_message(revision)
|
57
|
-
"FONDLED THE CODE"
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe "deploying an application" do
|
64
|
-
class FullTestDeploy < EY::Serverside::Deploy
|
65
|
-
attr_reader :infos, :debugs, :commands
|
66
|
-
|
67
|
-
def initialize(*)
|
68
|
-
super
|
69
|
-
@infos = []
|
70
|
-
@debugs = []
|
71
|
-
@commands = []
|
72
|
-
end
|
73
|
-
|
74
|
-
# stfu
|
75
|
-
def info(msg)
|
76
|
-
@infos << msg
|
77
|
-
end
|
78
|
-
|
79
|
-
# no really, stfu
|
80
|
-
def debug(msg)
|
81
|
-
@debugs << msg
|
82
|
-
end
|
83
|
-
|
84
|
-
# passwordless sudo is neither guaranteed nor desired
|
85
|
-
def sudo(cmd)
|
86
|
-
run(cmd)
|
87
|
-
end
|
88
|
-
|
89
|
-
def run(cmd)
|
90
|
-
@commands << cmd
|
91
|
-
super
|
92
|
-
end
|
93
|
-
|
94
|
-
def version_specifier
|
95
|
-
# Normally, the deploy task invokes the hook task by executing
|
96
|
-
# the rubygems-generated wrapper (it's what's in $PATH). It
|
97
|
-
# specifies the version to make sure that the pieces don't get
|
98
|
-
# out of sync. However, in test mode, there's no
|
99
|
-
# rubygems-generated wrapper, and so the hook task doesn't get
|
100
|
-
# run because thor thinks we're trying to invoke the _$VERSION_
|
101
|
-
# task instead, which doesn't exist.
|
102
|
-
#
|
103
|
-
# By stripping that out, we can get the hooks to actually run
|
104
|
-
# inside this test.
|
105
|
-
nil
|
106
|
-
end
|
107
|
-
|
108
|
-
def restart
|
109
|
-
FileUtils.touch("#{c.release_path}/restart")
|
110
|
-
end
|
111
|
-
|
112
|
-
# we're probably running this spec under bundler, but a real
|
113
|
-
# deploy does not
|
114
|
-
def bundle
|
115
|
-
my_env = ENV.to_hash
|
116
|
-
|
117
|
-
ENV.delete("BUNDLE_GEMFILE")
|
118
|
-
ENV.delete("BUNDLE_BIN_PATH")
|
119
|
-
|
120
|
-
result = super
|
121
|
-
|
122
|
-
ENV.replace(my_env)
|
123
|
-
result
|
124
|
-
end
|
125
|
-
|
126
|
-
def get_bundler_installer(lockfile)
|
127
|
-
installer = super
|
128
|
-
installer.options << ' --quiet' # stfu already!
|
129
|
-
installer
|
130
|
-
end
|
131
|
-
|
132
|
-
end
|
133
|
-
|
134
|
-
before(:all) do
|
135
|
-
@deploy_dir = File.join(Dir.tmpdir, "serverside-deploy-#{Time.now.to_i}-#{$$}")
|
136
|
-
|
137
|
-
# set up EY::Serverside::Server like we're on a solo
|
138
|
-
EY::Serverside::Server.reset
|
139
|
-
EY::Serverside::Server.add(:hostname => 'localhost', :roles => %w[solo])
|
140
|
-
|
141
|
-
# run a deploy
|
142
|
-
config = EY::Serverside::Deploy::Configuration.new({
|
143
|
-
"strategy" => "IntegrationSpec",
|
144
|
-
"deploy_to" => @deploy_dir,
|
145
|
-
"group" => `id -gn`.strip,
|
146
|
-
"stack" => 'nginx_passenger',
|
147
|
-
"migrate" => "ruby -e 'puts ENV[\"PATH\"]' > #{@deploy_dir}/path-when-migrating",
|
148
|
-
'app' => 'foo',
|
149
|
-
'framework_env' => 'staging'
|
150
|
-
})
|
151
|
-
|
152
|
-
# pretend there is a shared bundled_gems directory
|
153
|
-
FileUtils.mkdir_p(File.join(@deploy_dir, 'shared', 'bundled_gems'))
|
154
|
-
%w(RUBY_VERSION SYSTEM_VERSION).each do |name|
|
155
|
-
File.open(File.join(@deploy_dir, 'shared', 'bundled_gems', name), "w") { |f| f.write("old\n") }
|
156
|
-
end
|
157
|
-
|
158
|
-
@binpath = File.expand_path(File.join(File.dirname(__FILE__), '..', 'bin', 'engineyard-serverside'))
|
159
|
-
@deployer = FullTestDeploy.new(config)
|
160
|
-
@deployer.deploy
|
161
|
-
end
|
162
|
-
|
163
|
-
it "runs the right bundler command" do
|
164
|
-
install_bundler_command_ran = @deployer.commands.detect{ |command| command.index("install_bundler") }
|
165
|
-
install_bundler_command_ran.should_not be_nil
|
166
|
-
install_bundler_command_ran.should == "#{@binpath} install_bundler 1.0.10"
|
167
|
-
end
|
168
|
-
|
169
|
-
it "creates a REVISION file" do
|
170
|
-
File.exist?(File.join(@deploy_dir, 'current', 'REVISION')).should be_true
|
171
|
-
end
|
172
|
-
|
173
|
-
it "restarts the app servers" do
|
174
|
-
File.exist?(File.join(@deploy_dir, 'current', 'restart')).should be_true
|
175
|
-
end
|
176
|
-
|
177
|
-
it "runs 'bundle install' with --deployment" do
|
178
|
-
bundle_install_cmd = @deployer.commands.grep(/bundle _\S+_ install/).first
|
179
|
-
bundle_install_cmd.should_not be_nil
|
180
|
-
bundle_install_cmd.should include('--deployment')
|
181
|
-
end
|
182
|
-
|
183
|
-
it "creates a ruby version file" do
|
184
|
-
File.exist?(File.join(@deploy_dir, 'shared', 'bundled_gems', 'RUBY_VERSION')).should be_true
|
185
|
-
end
|
186
|
-
|
187
|
-
it "creates a system version file" do
|
188
|
-
File.exist?(File.join(@deploy_dir, 'shared', 'bundled_gems', 'SYSTEM_VERSION')).should be_true
|
189
|
-
end
|
190
|
-
|
191
|
-
it "removes bundled_gems directory if the ruby version changed" do
|
192
|
-
clear_bundle_cmd = @deployer.commands.grep(/rm -Rf \S+\/bundled_gems/).first
|
193
|
-
clear_bundle_cmd.should_not be_nil
|
194
|
-
end
|
195
|
-
|
196
|
-
it "removes bundled_gems directory if the system version changed" do
|
197
|
-
clear_bundle_cmd = @deployer.commands.grep(/rm -Rf \S+\/bundled_gems/).first
|
198
|
-
clear_bundle_cmd.should_not be_nil
|
199
|
-
end
|
200
|
-
|
201
|
-
it "creates binstubs somewhere out of the way" do
|
202
|
-
File.exist?(File.join(@deploy_dir, 'current', 'ey_bundler_binstubs', 'rake')).should be_true
|
203
|
-
end
|
204
|
-
|
205
|
-
it "has the binstubs in the path when migrating" do
|
206
|
-
File.read(File.join(@deploy_dir, 'path-when-migrating')).should include('ey_bundler_binstubs')
|
207
|
-
end
|
208
|
-
|
209
|
-
it "runs all the hooks" do
|
210
|
-
File.exist?(File.join(@deploy_dir, 'current', 'before_bundle.ran' )).should be_true
|
211
|
-
File.exist?(File.join(@deploy_dir, 'current', 'after_bundle.ran' )).should be_true
|
212
|
-
File.exist?(File.join(@deploy_dir, 'current', 'before_migrate.ran')).should be_true
|
213
|
-
File.exist?(File.join(@deploy_dir, 'current', 'after_migrate.ran' )).should be_true
|
214
|
-
File.exist?(File.join(@deploy_dir, 'current', 'before_symlink.ran')).should be_true
|
215
|
-
File.exist?(File.join(@deploy_dir, 'current', 'after_symlink.ran' )).should be_true
|
216
|
-
File.exist?(File.join(@deploy_dir, 'current', 'before_restart.ran')).should be_true
|
217
|
-
File.exist?(File.join(@deploy_dir, 'current', 'after_restart.ran' )).should be_true
|
218
|
-
end
|
219
|
-
end
|