engineyard-serverside 1.4.3.nodestack → 1.4.7.pre

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.
Files changed (33) hide show
  1. data/lib/core-ext/README.md +3 -0
  2. data/lib/core-ext/string.rb +9 -0
  3. data/lib/engineyard-serverside.rb +3 -1
  4. data/lib/engineyard-serverside/cli.rb +3 -2
  5. data/lib/engineyard-serverside/configuration.rb +1 -1
  6. data/lib/engineyard-serverside/deploy.rb +117 -23
  7. data/lib/engineyard-serverside/lockfile_parser.rb +3 -3
  8. data/lib/engineyard-serverside/logged_output.rb +0 -5
  9. data/lib/engineyard-serverside/task.rb +1 -0
  10. data/lib/engineyard-serverside/version.rb +1 -1
  11. data/lib/vendor/ruby_1.8.6_openssl.patch +7 -0
  12. data/spec/custom_deploy_spec.rb +14 -7
  13. data/spec/fixtures/gemfiles/activerecord_jdbcmysql/Gemfile +5 -0
  14. data/spec/fixtures/gemfiles/activerecord_jdbcmysql/Gemfile.lock +29 -0
  15. data/spec/fixtures/gemfiles/activerecord_jdbcpostgresql/Gemfile +5 -0
  16. data/spec/fixtures/gemfiles/activerecord_jdbcpostgresql/Gemfile.lock +29 -0
  17. data/spec/fixtures/gemfiles/activerecord_mysql/Gemfile +5 -0
  18. data/spec/fixtures/gemfiles/activerecord_mysql/Gemfile.lock +25 -0
  19. data/spec/fixtures/gemfiles/activerecord_mysql2/Gemfile +5 -0
  20. data/spec/fixtures/gemfiles/activerecord_mysql2/Gemfile.lock +25 -0
  21. data/spec/fixtures/gemfiles/activerecord_pg/Gemfile +5 -0
  22. data/spec/fixtures/gemfiles/activerecord_pg/Gemfile.lock +25 -0
  23. data/spec/fixtures/gemfiles/activerecord_sqlite3/Gemfile +5 -0
  24. data/spec/fixtures/gemfiles/activerecord_sqlite3/Gemfile.lock +25 -0
  25. data/spec/fixtures/gemfiles/diy_database_yml/Gemfile +5 -0
  26. data/spec/fixtures/gemfiles/diy_database_yml/Gemfile.lock +25 -0
  27. data/spec/fixtures/gemfiles/diy_database_yml/config/database.yml +7 -0
  28. data/spec/generate_configs_spec.rb +228 -0
  29. data/spec/lib/full_test_deploy.rb +86 -0
  30. data/spec/real_deploy_spec.rb +42 -121
  31. data/spec/spec_helper.rb +62 -1
  32. metadata +75 -9
  33. data/spec/fixtures/gitrepo/bar +0 -0
@@ -0,0 +1,5 @@
1
+ # A sample Gemfile
2
+ source "http://rubygems.org"
3
+
4
+ gem "activerecord"
5
+ gem "mysql"
@@ -0,0 +1,25 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activemodel (3.0.10)
5
+ activesupport (= 3.0.10)
6
+ builder (~> 2.1.2)
7
+ i18n (~> 0.5.0)
8
+ activerecord (3.0.10)
9
+ activemodel (= 3.0.10)
10
+ activesupport (= 3.0.10)
11
+ arel (~> 2.0.10)
12
+ tzinfo (~> 0.3.23)
13
+ activesupport (3.0.10)
14
+ arel (2.0.10)
15
+ builder (2.1.2)
16
+ i18n (0.5.0)
17
+ mysql (2.8.1)
18
+ tzinfo (0.3.29)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ activerecord
25
+ mysql
@@ -0,0 +1,5 @@
1
+ # A sample Gemfile
2
+ source "http://rubygems.org"
3
+
4
+ gem "activerecord"
5
+ gem "mysql2"
@@ -0,0 +1,25 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activemodel (3.0.10)
5
+ activesupport (= 3.0.10)
6
+ builder (~> 2.1.2)
7
+ i18n (~> 0.5.0)
8
+ activerecord (3.0.10)
9
+ activemodel (= 3.0.10)
10
+ activesupport (= 3.0.10)
11
+ arel (~> 2.0.10)
12
+ tzinfo (~> 0.3.23)
13
+ activesupport (3.0.10)
14
+ arel (2.0.10)
15
+ builder (2.1.2)
16
+ i18n (0.5.0)
17
+ mysql2 (0.3.7)
18
+ tzinfo (0.3.29)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ activerecord
25
+ mysql2
@@ -0,0 +1,5 @@
1
+ # A sample Gemfile
2
+ source "http://rubygems.org"
3
+
4
+ gem "activerecord"
5
+ gem "pg"
@@ -0,0 +1,25 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activemodel (3.0.10)
5
+ activesupport (= 3.0.10)
6
+ builder (~> 2.1.2)
7
+ i18n (~> 0.5.0)
8
+ activerecord (3.0.10)
9
+ activemodel (= 3.0.10)
10
+ activesupport (= 3.0.10)
11
+ arel (~> 2.0.10)
12
+ tzinfo (~> 0.3.23)
13
+ activesupport (3.0.10)
14
+ arel (2.0.10)
15
+ builder (2.1.2)
16
+ i18n (0.5.0)
17
+ pg (0.11.0)
18
+ tzinfo (0.3.29)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ activerecord
25
+ pg
@@ -0,0 +1,5 @@
1
+ # A sample Gemfile
2
+ source "http://rubygems.org"
3
+
4
+ gem "activerecord"
5
+ gem "sqlite3"
@@ -0,0 +1,25 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activemodel (3.0.10)
5
+ activesupport (= 3.0.10)
6
+ builder (~> 2.1.2)
7
+ i18n (~> 0.5.0)
8
+ activerecord (3.0.10)
9
+ activemodel (= 3.0.10)
10
+ activesupport (= 3.0.10)
11
+ arel (~> 2.0.10)
12
+ tzinfo (~> 0.3.23)
13
+ activesupport (3.0.10)
14
+ arel (2.0.10)
15
+ builder (2.1.2)
16
+ i18n (0.5.0)
17
+ sqlite3 (1.3.4)
18
+ tzinfo (0.3.29)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ activerecord
25
+ sqlite3
@@ -0,0 +1,5 @@
1
+ # A sample Gemfile
2
+ source "http://rubygems.org"
3
+
4
+ gem "activerecord", '3.0.10'
5
+ gem "mysql2", '0.3.7'
@@ -0,0 +1,25 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activemodel (3.0.10)
5
+ activesupport (= 3.0.10)
6
+ builder (~> 2.1.2)
7
+ i18n (~> 0.5.0)
8
+ activerecord (3.0.10)
9
+ activemodel (= 3.0.10)
10
+ activesupport (= 3.0.10)
11
+ arel (~> 2.0.10)
12
+ tzinfo (~> 0.3.23)
13
+ activesupport (3.0.10)
14
+ arel (2.0.10)
15
+ builder (2.1.2)
16
+ i18n (0.5.0)
17
+ mysql2 (0.3.7)
18
+ tzinfo (0.3.29)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ activerecord (= 3.0.10)
25
+ mysql2 (= 0.3.7)
@@ -0,0 +1,7 @@
1
+ production:
2
+ adapter: foobarbaz
3
+ database: myfirstapp
4
+ username: deploy
5
+ password: 12345678
6
+ host: localhost
7
+ reconnect: true
@@ -0,0 +1,228 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require File.dirname(__FILE__) + '/lib/full_test_deploy'
3
+
4
+ module EY::Serverside::Strategies::GenerateDatabaseYmlIntegrationSpec
5
+ module Helpers
6
+ attr_accessor :db_gemfile_folder
7
+ attr_accessor :db_keepfile
8
+
9
+ def update_repository_cache
10
+ cached_copy = File.join(c.shared_path, 'cached-copy')
11
+ FileUtils.mkdir_p(cached_copy)
12
+ FileUtils.mkdir_p(shared_config = File.join(c.shared_path, 'config'))
13
+
14
+ # set engineyard.apps[0].type? default: rack
15
+ # set engineyard.environment.components[0].key? default: ruby_187
16
+ # copy over Gemfile & Gemfile.lock from fixtures/gemfiles/<db_gemfile_folder>
17
+ gemfile_fixtures_dir = File.expand_path("../fixtures/gemfiles/#{db_gemfile_folder}", __FILE__)
18
+
19
+ Dir.chdir(cached_copy) do
20
+ Dir[gemfile_fixtures_dir + "/*"].each {|f| FileUtils.cp_r(f, File.basename(f))}
21
+ FileUtils.mkdir_p('config')
22
+ Dir.chdir('config') do
23
+ Dir[gemfile_fixtures_dir + "/config/*"].each {|f| FileUtils.cp_r(f, File.basename(f))}
24
+
25
+ `touch keep.database.yml` if db_keepfile
26
+ end
27
+ end
28
+
29
+ # FileUtils.cp_r(gemfile_fixtures_dir + "/", cached_copy) FIXME - why do you work?
30
+ end
31
+
32
+ def create_revision_file_command
33
+ "echo 'revision, yo' > #{c.release_path}/REVISION"
34
+ end
35
+
36
+ def short_log_message(revision)
37
+ end
38
+ end
39
+ end
40
+
41
+ describe "generate database.yml for a solo" do
42
+ def deploy_with_gemfile(db_gemfile_folder, db_type, cluster_type = :solo, config_overrides = {})
43
+ tmp = "deploy_with_gemfile-#{Time.now.to_i}-#{$$}"
44
+ @deploy_dir = File.join(Dir.tmpdir, tmp)
45
+ FileUtils.mkdir_p(@deploy_dir)
46
+
47
+ # set up EY::Serverside::Server like we're on a solo
48
+ roles = %w[solo]
49
+ EY::Serverside::Server.reset
50
+ server = EY::Serverside::Server.add(:hostname => 'localhost', :roles => roles)
51
+
52
+ setup_dna_json(:cluster_type => cluster_type, :db_stack_name => db_type)
53
+
54
+ # run a deploy
55
+ @config = EY::Serverside::Deploy::Configuration.new(config_overrides.merge({
56
+ "strategy" => "GenerateDatabaseYmlIntegrationSpec",
57
+ "deploy_to" => @deploy_dir,
58
+ "group" => `id -gn`.strip,
59
+ "stack" => 'nginx_passenger',
60
+ "migrate" => "ruby -e 'puts ENV[\"PATH\"]' > #{@deploy_dir}/path-when-migrating",
61
+ 'app' => 'myfirstapp',
62
+ 'framework_env' => 'production'
63
+ }))
64
+
65
+ FileUtils.mkdir_p(@config.release_path)
66
+ FileUtils.mkdir_p(File.join(@deploy_dir, 'shared'))
67
+
68
+ gemfile_lock = File.expand_path("../fixtures/gemfiles/#{db_gemfile_folder}/Gemfile.lock", __FILE__)
69
+ if config_overrides[:keepfile_base]
70
+ FileUtils.cp_r(File.expand_path("../fixtures/gemfiles/#{db_gemfile_folder}/config", __FILE__), @config.release_path)
71
+ `touch #{@config.release_path}/config/keep.database.yml`
72
+ FileUtils.cp_r(File.expand_path("../fixtures/gemfiles/#{db_gemfile_folder}/config", __FILE__), File.join(@deploy_dir, config_overrides[:keepfile_base]))
73
+ end
74
+
75
+ FileUtils.mkdir_p(File.join(@config.release_path, 'config'))
76
+ FileUtils.cp(gemfile_lock, @config.release_path)
77
+ Dir.chdir(File.join(@deploy_dir, 'shared')) do
78
+ # pretend there is a shared bundled_gems directory
79
+ FileUtils.mkdir_p('bundled_gems')
80
+
81
+ %w(RUBY_VERSION SYSTEM_VERSION).each do |name|
82
+ File.open(File.join('bundled_gems', name), "w") { |f| f.write("old\n") }
83
+ end
84
+
85
+ FileUtils.mkdir_p('config')
86
+ if config_overrides[:keepfile_base] == 'shared'
87
+ `touch config/keep.database.yml`
88
+ end
89
+ end
90
+
91
+ @binpath = $0 = File.expand_path(File.join(File.dirname(__FILE__), '..', 'bin', 'engineyard-serverside'))
92
+ @deployer = FullTestDeploy.new(@config)
93
+ @deployer.db_gemfile_folder = db_gemfile_folder
94
+ @deployer.db_keepfile = config_overrides[:keepfile_base] == 'shared/cached-copy'
95
+
96
+ @deployer.generate_database_yml(@config.release_path)
97
+ end
98
+
99
+ [
100
+ [ 'activerecord_sqlite3', 'mysql', 'mysql'],
101
+ [ 'activerecord_sqlite3', 'postgresql', 'postgresql'],
102
+ [ 'activerecord_mysql', 'mysql', 'mysql'],
103
+ [ 'activerecord_mysql2', 'mysql', 'mysql2'],
104
+ [ 'activerecord_pg', 'postgresql', 'postgresql'],
105
+ [ 'activerecord_jdbcmysql', 'mysql', 'mysql'], # jruby
106
+ [ 'activerecord_jdbcpostgresql', 'postgresql', 'postgresql'] # jruby
107
+ ].each do | db_gemfile_folder, db_type, expected_adapter |
108
+ it "from Gemfile tagged '#{db_gemfile_folder}' generates a database.yml with adapter #{expected_adapter}" do
109
+ deploy_with_gemfile(db_gemfile_folder, db_type)
110
+
111
+ database_yml_file = File.join(@config.release_path, 'config', 'database.yml')
112
+ File.exist?(database_yml_file).should be_true
113
+ database_yml = File.read(database_yml_file)
114
+
115
+ # Expected database.yml to look like:
116
+ expected = <<-EOS.gsub(/^\s{6}/, '')
117
+ production:
118
+ adapter: #{expected_adapter}
119
+ database: myfirstapp
120
+ username: deploy
121
+ password: 12345678
122
+ host: solo.compute-1.amazonaws.com
123
+ reconnect: true
124
+ EOS
125
+ expected.should == database_yml
126
+ end
127
+ end
128
+
129
+ it "overrides the adapter from (ey.yml derived) configuration" do
130
+ deploy_with_gemfile('activerecord_mysql2', 'mysql', :solo, :db_adapter => 'foobar')
131
+
132
+ expected = <<-EOS.gsub(/^\s{4}/, '')
133
+ production:
134
+ adapter: foobar
135
+ database: myfirstapp
136
+ username: deploy
137
+ password: 12345678
138
+ host: solo.compute-1.amazonaws.com
139
+ reconnect: true
140
+ EOS
141
+ File.read(File.join(@config.release_path, 'config', 'database.yml')).should == expected
142
+ end
143
+
144
+ it "separate db_master instance and slave instances" do
145
+ deploy_with_gemfile('activerecord_mysql2', 'mysql', :slaves)
146
+
147
+ expected = <<-EOS.gsub(/^\s{4}/, '')
148
+ production:
149
+ adapter: mysql2
150
+ database: myfirstapp
151
+ username: deploy
152
+ password: 12345678
153
+ host: db_master.compute-1.amazonaws.com
154
+ reconnect: true
155
+ slave:
156
+ adapter: mysql2
157
+ database: myfirstapp
158
+ username: deploy
159
+ password: 12345678
160
+ host: db_slave1.compute-1.amazonaws.com
161
+ reconnect: true
162
+ slave_1:
163
+ adapter: mysql2
164
+ database: myfirstapp
165
+ username: deploy
166
+ password: 12345678
167
+ host: db_slave2.compute-1.amazonaws.com
168
+ reconnect: true
169
+ EOS
170
+ File.read(File.join(@config.release_path, 'config', 'database.yml')).should == expected
171
+ end
172
+
173
+ it "generates a database.yml even if file already exists" do
174
+ deploy_with_gemfile('diy_database_yml', 'mysql', :solo)
175
+
176
+ expected = <<-EOS.gsub(/^\s{4}/, '')
177
+ production:
178
+ adapter: mysql2
179
+ database: myfirstapp
180
+ username: deploy
181
+ password: 12345678
182
+ host: solo.compute-1.amazonaws.com
183
+ reconnect: true
184
+ EOS
185
+ File.read(File.join(@config.release_path, 'config', 'database.yml')).should == expected
186
+ end
187
+
188
+ %w[shared shared/cached-copy].each do |base|
189
+ it "do not override the database.yml if a keepfile exists at #{base}/config/database.yml" do
190
+ deploy_with_gemfile('diy_database_yml', 'mysql', :solo, :keepfile_base => base)
191
+
192
+ expected = <<-EOS.gsub(/^\s{6}/, '')
193
+ production:
194
+ adapter: foobarbaz
195
+ database: myfirstapp
196
+ username: deploy
197
+ password: 12345678
198
+ host: localhost
199
+ reconnect: true
200
+ EOS
201
+ File.read(File.join(@config.release_path, 'config', 'database.yml')).should == expected
202
+ end
203
+ end
204
+ end
205
+
206
+ # framework type: rails vs sinatra vs node vs php
207
+ # rails 2 adapters: mysql/oracle/postgresql/sqlite2/sqlite3/frontbase/ibm_db
208
+ # rails 3 adapters: mysql/oracle/postgresql/sqlite3/frontbase/ibm_db/jdbcmysql/jdbcsqlite3/jdbcpostgresql/jdbc
209
+ # permutations to test:
210
+ # - rails/sinatra version? - hopefully not - just gems installed
211
+ # - ruby version / ruby type (mri vs jruby, mri 1.8.6 vs mri 1.9.2)?
212
+ # - Gemfile vs System gems? (look in Gemfile vs "gem list <name>")
213
+ # - gems installed - mysql, mysql2, pg, datamapper, activerecord, sqlite3?
214
+
215
+ # $ bundle -v
216
+ # Bundler version 1.0.18
217
+ # $ bundle list
218
+ # Gems included by the bundle:
219
+ # * activemodel (3.0.10)
220
+ # * activerecord (3.0.10)
221
+ # * activesupport (3.0.10)
222
+ # * arel (2.0.10)
223
+ # * builder (2.1.2)
224
+ # * bundler (1.0.18)
225
+ # * i18n (0.5.0)
226
+ # * mysql (2.8.1)
227
+ # * tzinfo (0.3.29)
228
+ #
@@ -0,0 +1,86 @@
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
+ # we're probably running this spec under bundler, but a real
64
+ # deploy does not
65
+ def gems_include?(*gems)
66
+ my_env = ENV.to_hash
67
+
68
+ ENV.delete("BUNDLE_GEMFILE")
69
+ ENV.delete("BUNDLE_BIN_PATH")
70
+
71
+ result = super
72
+
73
+ ENV.replace(my_env)
74
+ result
75
+ end
76
+
77
+ def get_bundler_installer(lockfile, options = '')
78
+ super(lockfile, ' --quiet')
79
+ end
80
+
81
+ def bundler_10_installer(version, options = '')
82
+ options << ' --quiet' unless options.include?('--quiet')
83
+ super(version, options)
84
+ end
85
+
86
+ end