engineyard-serverside 1.4.12 → 1.4.13
Sign up to get free protection for your applications and to get access to all the features.
- 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
|