tdd_deploy 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/tasks/tdd_deploy.rake +1 -1
- data/lib/tdd_deploy/assertions.rb +1 -1
- data/lib/tdd_deploy/configurator.rb +1 -1
- data/lib/tdd_deploy/copy_methods.rb +78 -5
- data/lib/tdd_deploy/environ.rb +53 -17
- data/lib/tdd_deploy/server-templates/test_results.html.erb +42 -4
- data/lib/tdd_deploy/server.rb +7 -2
- data/lib/tdd_deploy/site-erb/{db_hosts → app_hosts}/config/one_thin_server.conf.erb +2 -2
- data/lib/tdd_deploy/site-erb/{db_hosts → app_hosts}/config/thin.conf.erb +2 -2
- data/lib/tdd_deploy/site-erb/{db_hosts → app_hosts}/site/monitrc.erb +3 -3
- data/lib/tdd_deploy/site-erb/{db_hosts → app_hosts}/site/one_thin_server.erb +1 -1
- data/lib/tdd_deploy/site-erb/balance_hosts/config/one_thin_server.conf.erb +2 -2
- data/lib/tdd_deploy/site-erb/balance_hosts/config/thin.conf.erb +2 -2
- data/lib/tdd_deploy/site-erb/balance_hosts/site/monitrc.erb +3 -3
- data/lib/tdd_deploy/site-erb/balance_hosts/site/nginx.conf.erb +1 -1
- data/lib/tdd_deploy/site-erb/balance_hosts/site/one_thin_server.erb +1 -1
- data/lib/tdd_deploy/site-erb/web_hosts/site/monitrc.erb +3 -3
- data/lib/tdd_deploy/site-erb/web_hosts/site/nginx.conf.erb +1 -1
- data/lib/tdd_deploy/site_tests/site_layout.rb +20 -20
- data/lib/tdd_deploy/site_tests/site_rvm.rb +26 -0
- data/lib/tdd_deploy/version.rb +1 -1
- data/tests/test_configurator.rb +2 -2
- data/tests/test_copy_methods.rb +139 -1
- data/tests/test_environ.rb +6 -6
- metadata +27 -19
- data/lib/tdd_deploy/site-erb/db_hosts/site/nginx.conf.erb +0 -29
- data/lib/tdd_deploy/site-erb/web_hosts/config/one_thin_server.conf.erb +0 -14
- data/lib/tdd_deploy/site-erb/web_hosts/config/thin.conf.erb +0 -14
- data/lib/tdd_deploy/site-erb/web_hosts/site/one_thin_server.erb +0 -6
data/lib/tasks/tdd_deploy.rake
CHANGED
@@ -14,7 +14,7 @@ namespace :tdd_deploy do
|
|
14
14
|
desc "deletes tdd_deploy_configs/ & all it's files"
|
15
15
|
task :rm_configs do
|
16
16
|
tdd_deploy_configs = './tdd_deploy_configs'
|
17
|
-
|
17
|
+
FileUtils.rm_r tdd_deploy_configs if File.exists? tdd_deploy_configs
|
18
18
|
end
|
19
19
|
|
20
20
|
desc "copies tests & config templates to lib/tdd_deploy/"
|
@@ -131,7 +131,7 @@ module TddDeploy
|
|
131
131
|
def remove_failed_tests
|
132
132
|
tmp = {}
|
133
133
|
Stats.test_results.each do |host, results|
|
134
|
-
tmp[host] = results.select { |tmp| tmp[0] }
|
134
|
+
tmp[host] = results.select { |tmp| tmp[0] }.uniq.sort
|
135
135
|
end
|
136
136
|
Stats.test_results = tmp
|
137
137
|
end
|
@@ -39,7 +39,7 @@ module TddDeploy
|
|
39
39
|
tdd_deploy_configs = File.join Dir.pwd, 'tdd_deploy_configs'
|
40
40
|
Dir.mkdir(tdd_deploy_configs) unless File.exists? tdd_deploy_configs
|
41
41
|
|
42
|
-
['balance_hosts', 'db_hosts', 'web_hosts'].each do |host_dir|
|
42
|
+
['app_hosts', 'balance_hosts', 'db_hosts', 'web_hosts'].each do |host_dir|
|
43
43
|
host_path = File.join(tdd_deploy_configs, host_dir)
|
44
44
|
Dir.mkdir(host_path) unless File.exists? host_path
|
45
45
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'net/ssh'
|
2
2
|
require 'net/sftp'
|
3
|
+
require 'fileutils'
|
3
4
|
|
4
5
|
module TddDeploy
|
5
6
|
module CopyMethods
|
@@ -21,13 +22,79 @@ module TddDeploy
|
|
21
22
|
result
|
22
23
|
end
|
23
24
|
|
25
|
+
def copy_dir_to_remote_on_hosts_as(userid, host_list, src_dir, dest_dir)
|
26
|
+
raise ::ArgumentError.new("copy_dir_to_remote_on_hosts_as: src_dir does not exist: #{src_dir}") \
|
27
|
+
unless File.directory? src_dir
|
28
|
+
host_list = [host_list] if host_list.is_a? String
|
29
|
+
result = true
|
30
|
+
host_list.uniq.each do |host|
|
31
|
+
result &= mkdir_on_remote_as userid, host, dest_dir
|
32
|
+
end
|
33
|
+
Dir.open(src_dir).each do |fname|
|
34
|
+
next if fname[0] == '.'
|
35
|
+
path = File.join(src_dir, fname)
|
36
|
+
result &= copy_file_to_remote_on_hosts_as userid, host_list, path, File.join(dest_dir, fname)
|
37
|
+
end
|
38
|
+
result
|
39
|
+
end
|
40
|
+
|
41
|
+
def append_string_to_remote_file_on_hosts_as userid, host_list, str, dst
|
42
|
+
result = true
|
43
|
+
host_list = [host_list] if host_list.is_a? String
|
44
|
+
host_list.uniq.each do |host|
|
45
|
+
result &= append_string_to_remote_file_as userid, host, str, dst
|
46
|
+
end
|
47
|
+
result
|
48
|
+
end
|
49
|
+
|
50
|
+
def append_file_to_remote_on_hosts_as userid, host_list, src, dst
|
51
|
+
result = true
|
52
|
+
host_list = [host_list] if host_list.is_a? String
|
53
|
+
host_list.uniq.each do |host|
|
54
|
+
result &= append_file_to_remote_file_as userid, host, src, dst
|
55
|
+
end
|
56
|
+
result
|
57
|
+
end
|
58
|
+
|
59
|
+
def append_dir_to_remote_on_hosts_as(userid, host_list, src_dir, dest_dir)
|
60
|
+
raise ::ArgumentError.new("append_dir_to_remote_on_hosts_as: src_dir does not exist: #{src_dir}") \
|
61
|
+
unless File.directory? src_dir
|
62
|
+
host_list = [host_list] if host_list.is_a? String
|
63
|
+
result = true
|
64
|
+
host_list.uniq.each do |host|
|
65
|
+
result &= mkdir_on_remote_as userid, host, dest_dir
|
66
|
+
end
|
67
|
+
Dir.open(src_dir).each do |fname|
|
68
|
+
next if fname[0] == '.'
|
69
|
+
path = File.join(src_dir, fname)
|
70
|
+
result &= append_file_to_remote_on_hosts_as userid, host_list, path, File.join(dest_dir, fname)
|
71
|
+
end
|
72
|
+
result
|
73
|
+
end
|
74
|
+
|
24
75
|
#single host methods
|
25
76
|
|
26
77
|
def mkdir_on_remote_as userid, host, dir, options = {}
|
27
78
|
result = nil
|
28
79
|
options[:permissions] = 0755 unless options.include? :permissions
|
29
80
|
Net::SFTP.start(host, userid) do |sftp|
|
30
|
-
|
81
|
+
begin
|
82
|
+
result = sftp.opendir! dir
|
83
|
+
rescue ::Net::SFTP::StatusException
|
84
|
+
result = sftp.mkdir dir, options
|
85
|
+
end
|
86
|
+
end
|
87
|
+
result
|
88
|
+
end
|
89
|
+
|
90
|
+
def append_string_to_remote_file_as userid, host, str, dst
|
91
|
+
result = nil
|
92
|
+
Net::SFTP.start(host, userid) do |sftp|
|
93
|
+
if handle = sftp.open!(dst, 'a+')
|
94
|
+
stat_buf = sftp.fstat! handle
|
95
|
+
result = sftp.write handle, stat_buf.size, str
|
96
|
+
sftp.close! handle
|
97
|
+
end
|
31
98
|
end
|
32
99
|
result
|
33
100
|
end
|
@@ -35,17 +102,23 @@ module TddDeploy
|
|
35
102
|
def copy_string_to_remote_file_as userid, host, str, dst
|
36
103
|
result = nil
|
37
104
|
Net::SFTP.start(host, userid) do |sftp|
|
38
|
-
result = sftp.file.open(dst,
|
105
|
+
result = sftp.file.open(dst, 'w') do |f|
|
39
106
|
f.write str
|
40
107
|
end
|
41
108
|
end
|
42
109
|
result
|
43
110
|
end
|
44
111
|
|
112
|
+
def append_file_to_remote_file_as(userid, host, src, dst)
|
113
|
+
raise ::ArgumentError.new("file name cannot be empty") if src.empty?
|
114
|
+
raise ::RuntimeError.new("unable to copy #{src} to #{userid}@#{host}: #{src} not found") unless File.exists? src
|
115
|
+
|
116
|
+
append_string_to_remote_file_as userid, host, File.new(src).read, dst
|
117
|
+
end
|
118
|
+
|
45
119
|
def copy_file_to_remote_as(userid, host, src, dst)
|
46
|
-
|
47
|
-
raise
|
48
|
-
raise RuntimeError.new("unable to copy #{src} to #{userid}@#{host}: #{src} not found") unless File.exists? src
|
120
|
+
raise ::ArgumentError.new("file name cannot be empty") if src.empty?
|
121
|
+
raise ::RuntimeError.new("unable to copy #{src} to #{userid}@#{host}: #{src} not found") unless File.exists? src
|
49
122
|
|
50
123
|
copy_string_to_remote_file_as userid, host, File.new(src).read, dst
|
51
124
|
end
|
data/lib/tdd_deploy/environ.rb
CHANGED
@@ -31,7 +31,8 @@ module TddDeploy
|
|
31
31
|
# * 'local_admin' - user name of on local hosts which can ssh into remote hosts via public key authentication
|
32
32
|
# * 'local_admin_email' - email of local admin who should receive monitoring emails
|
33
33
|
# * 'site' - name of site This should satisfy /[a-z][a-z0-9_]*.
|
34
|
-
# * '
|
34
|
+
# * 'site_doc_root' - the absolute path to DocumentRoot for the site
|
35
|
+
# * 'site_special_dir' - absolute path to site special directory - for system configuration fragments, commands, etc
|
35
36
|
# * 'site_url' - the url for the site (w/o scheme - as in 'www.foo.com')
|
36
37
|
# * 'site_aliases' - aliases for the site. The delimiters will depend on your web server
|
37
38
|
# * 'site_user' - name of site user. TddDeploy assumes that each site will have a unique user on the remote host.
|
@@ -65,7 +66,7 @@ module TddDeploy
|
|
65
66
|
# include TddDeploy::Environ
|
66
67
|
class DataCache
|
67
68
|
class << self
|
68
|
-
attr_accessor :env_hash, :env_types, :env_defaults, :capfile
|
69
|
+
attr_accessor :env_hash, :env_types, :env_desc, :env_defaults, :capfile
|
69
70
|
end
|
70
71
|
end
|
71
72
|
|
@@ -79,18 +80,18 @@ module TddDeploy
|
|
79
80
|
end
|
80
81
|
|
81
82
|
def env_hash=(hash)
|
82
|
-
raise ArgumentError.new("env_hash=(): arg must be a hash") unless hash.is_a? Hash
|
83
|
+
raise ::ArgumentError.new("env_hash=(): arg must be a hash") unless hash.is_a? Hash
|
83
84
|
if !(tmp = hash.keys - DataCache.env_types.keys).empty?
|
84
|
-
raise ArgumentError.new("env_hash=(): Illegal Keys in value: #{tmp.join(',')}")
|
85
|
+
raise ::ArgumentError.new("env_hash=(): Illegal Keys in value: #{tmp.join(',')}")
|
85
86
|
elsif !(tmp = DataCache.env_types.keys - hash.keys).empty?
|
86
|
-
raise ArgumentError.new("env_hash=(): Missing Keys in value: #{tmp.join(',')}")
|
87
|
+
raise ::ArgumentError.new("env_hash=(): Missing Keys in value: #{tmp.join(',')}")
|
87
88
|
else
|
88
89
|
DataCache.env_hash = hash
|
89
90
|
end
|
90
91
|
end
|
91
92
|
|
92
93
|
def capfile
|
93
|
-
raise RuntimeError.new('Attempt to access capfile data w/o capfile_paths defined') unless DataCache.env_hash['capfile_paths']
|
94
|
+
raise ::RuntimeError.new('Attempt to access capfile data w/o capfile_paths defined') unless DataCache.env_hash['capfile_paths']
|
94
95
|
unless DataCache.capfile
|
95
96
|
DataCache.capfile = TddDeploy::Capfile.new
|
96
97
|
DataCache.env_hash['capfile_paths'].each do |path|
|
@@ -112,7 +113,8 @@ module TddDeploy
|
|
112
113
|
'site' => :string,
|
113
114
|
'site_url' => :string,
|
114
115
|
'site_aliases' => :string,
|
115
|
-
'
|
116
|
+
'site_doc_root' => :string,
|
117
|
+
'site_special_dir' => :string,
|
116
118
|
'site_user' => :string,
|
117
119
|
|
118
120
|
'app_hosts' => :list,
|
@@ -127,6 +129,35 @@ module TddDeploy
|
|
127
129
|
'migration_hosts' => :pseudo,
|
128
130
|
'web' => :pseudo,
|
129
131
|
}
|
132
|
+
|
133
|
+
DataCache.env_desc = {
|
134
|
+
'ssh_timeout' => "ssh activity timeout in seconds",
|
135
|
+
'site_base_port' => "the lowest port number used by your mongrel or thin cluster",
|
136
|
+
'site_num_servers' => "number of mongrel or thin servers in your cluster",
|
137
|
+
|
138
|
+
'host_admin' => "userid of the non-root administrator on all your remote hosts",
|
139
|
+
'local_admin' => "userid on your local host which can ssh into all hosts as host_admin, root, and site_user",
|
140
|
+
'local_admin_email' => "email address of the recipient of montoring email - currently put in monitrc fragments",
|
141
|
+
|
142
|
+
'site' => 'name of site - will be the name of the deployment directory - as in /home/user/site/',
|
143
|
+
'site_url' => 'the site url - www.foo.com',
|
144
|
+
'site_aliases' => 'all the site aliases we need to put in nginx/apache configuration fragments',
|
145
|
+
'site_doc_root' => 'this is DocumentRoot for the site. probably /home/site_user/site/current',
|
146
|
+
'site_special_dir' => 'directory for monitrc, nginx config fragments, monit commands, etc',
|
147
|
+
'site_user' => 'userid that the app lives in. This need not be host_admin. It\' separate so multiple sites can live on the same host',
|
148
|
+
|
149
|
+
'app_hosts' => 'list of hosts the app will be installed on. Must have app stuff, like rvm, ruby, bundler, etc',
|
150
|
+
'balance_hosts' => 'list of hosts running load balancers',
|
151
|
+
'capfile_paths' => 'list of paths to Capistrano Capfile or ./config/deploy.rb or wherever you recipes are. Only used to get definitions of Capistrano roles.',
|
152
|
+
'db_hosts' => 'list of hosts running database servers',
|
153
|
+
'web_hosts' => 'list of hosts running real web servers - Apache or Nginx or ...',
|
154
|
+
|
155
|
+
'hosts' => 'uniquified sum of app_hosts, balance_hosts, db_hosts, and web_hosts',
|
156
|
+
'app' => 'list of servers in the Capistrano :app role',
|
157
|
+
'db' => 'list of servers in the Capistrano :db role',
|
158
|
+
'migration_hosts' => 'list of servers in the Capistrano :db role with :primary => truen',
|
159
|
+
'web' => 'list of servers in the Capistrano :web role',
|
160
|
+
}
|
130
161
|
|
131
162
|
DataCache.env_defaults ||= {
|
132
163
|
'ssh_timeout' => 5,
|
@@ -140,7 +171,8 @@ module TddDeploy
|
|
140
171
|
'site' => "site",
|
141
172
|
'site_url' => 'www.site.com', # don't include the scheme
|
142
173
|
'site_aliases' => '',
|
143
|
-
'
|
174
|
+
'site_doc_root' => '/home/site_user/site/current', # default for Capistrano
|
175
|
+
'site_special_dir' => '/home/site_user/site_special',
|
144
176
|
'site_user' => "site_user",
|
145
177
|
|
146
178
|
'capfile_paths' => './config/deploy.rb',
|
@@ -161,6 +193,10 @@ module TddDeploy
|
|
161
193
|
def env_defaults
|
162
194
|
DataCache.env_defaults
|
163
195
|
end
|
196
|
+
|
197
|
+
def env_desc
|
198
|
+
DataCache.env_desc
|
199
|
+
end
|
164
200
|
|
165
201
|
# set_env(value_hash {}) - convenience method which sets values of the environment
|
166
202
|
# hash using a hash rather than one-at-a-time
|
@@ -182,14 +218,14 @@ module TddDeploy
|
|
182
218
|
DataCache.env_hash['balance_hosts'] =
|
183
219
|
DataCache.env_hash['app_hosts'] = self.str_to_list(v)
|
184
220
|
else
|
185
|
-
raise RuntimeError.new("#{self}#reset_env(): Cannot assign value to 'hosts' if web_hosts &/or db_hosts already set.\n web_hosts: #{DataCache.env_hash['web_hosts']}\n db_hosts: #{DataCache.env_hash['db_hosts']}")
|
221
|
+
raise ::RuntimeError.new("#{self}#reset_env(): Cannot assign value to 'hosts' if web_hosts &/or db_hosts already set.\n web_hosts: #{DataCache.env_hash['web_hosts']}\n db_hosts: #{DataCache.env_hash['db_hosts']}")
|
186
222
|
# raise RuntimeError.new("Cannot change hosts key if web_hosts != db_hosts")
|
187
223
|
end
|
188
224
|
else
|
189
225
|
next
|
190
226
|
end
|
191
227
|
else
|
192
|
-
raise ArgumentError.new("#{self}#reset_env(): Illegal environment key: #{k}")
|
228
|
+
raise ::ArgumentError.new("#{self}#reset_env(): Illegal environment key: #{k}")
|
193
229
|
end
|
194
230
|
end
|
195
231
|
end
|
@@ -224,10 +260,10 @@ module TddDeploy
|
|
224
260
|
self.send "#{key}=".to_sym, $2
|
225
261
|
# self.env_hash[key] = self.env_types[key] == :list ? self.str_to_list($2) : $2.to_s
|
226
262
|
else
|
227
|
-
raise ArugmentError.new("TddDeploy::Environ#read_env: Error in #{TddDeploy::Error::ENV_FNAME}: #{line_no}: Illegal Key: #{key}")
|
263
|
+
raise ::ArugmentError.new("TddDeploy::Environ#read_env: Error in #{TddDeploy::Error::ENV_FNAME}: #{line_no}: Illegal Key: #{key}")
|
228
264
|
end
|
229
265
|
else
|
230
|
-
raise ArugmentError.new("TddDeploy::Environ#read_env: Error in #{TddDeploy::Error::ENV_FNAME}: #{line_no}: Unmatched Line: #{line}}")
|
266
|
+
raise ::ArugmentError.new("TddDeploy::Environ#read_env: Error in #{TddDeploy::Error::ENV_FNAME}: #{line_no}: Unmatched Line: #{line}}")
|
231
267
|
end
|
232
268
|
end
|
233
269
|
ensure
|
@@ -245,7 +281,7 @@ module TddDeploy
|
|
245
281
|
end
|
246
282
|
return self.env_hash
|
247
283
|
else
|
248
|
-
raise RuntimeError.new("Unable to open #{path} for reading")
|
284
|
+
raise ::RuntimeError.new("Unable to open #{path} for reading")
|
249
285
|
end
|
250
286
|
elsif dir_path.length <= 1
|
251
287
|
# reached root level, so initialize to defaults and exit
|
@@ -264,7 +300,7 @@ module TddDeploy
|
|
264
300
|
when str.is_a?(String) then str.split(/[\s,]+/).uniq.sort
|
265
301
|
when str.is_a?(Array) then str.uniq.sort
|
266
302
|
else
|
267
|
-
raise ArgumentError.new("str_to_list: #{str}")
|
303
|
+
raise ::ArgumentError.new("str_to_list: #{str}")
|
268
304
|
end
|
269
305
|
end
|
270
306
|
|
@@ -279,7 +315,7 @@ module TddDeploy
|
|
279
315
|
# 'site_host_setup.env' [aka TddDeploy::Environ::ENV_FNAME]
|
280
316
|
def save_env
|
281
317
|
f = File.new(TddDeploy::Environ::ENV_FNAME, "w")
|
282
|
-
self.env_types.keys.each do |k|
|
318
|
+
self.env_types.keys.sort.each do |k|
|
283
319
|
v = self.env_hash[k] || ''
|
284
320
|
case self.env_types[k]
|
285
321
|
when :int then f.write "#{k}=#{v}\n"
|
@@ -288,7 +324,7 @@ module TddDeploy
|
|
288
324
|
f.write "#{k}=#{self.list_to_str(k)}\n" unless k == 'hosts'
|
289
325
|
when :pseudo then next
|
290
326
|
else
|
291
|
-
raise RuntimeError("unknown key: #{k}")
|
327
|
+
raise ::RuntimeError.new("unknown key: #{k}")
|
292
328
|
end
|
293
329
|
end
|
294
330
|
f.close
|
@@ -349,7 +385,7 @@ module TddDeploy
|
|
349
385
|
self.balance_hosts =
|
350
386
|
self.app_hosts = self.str_to_list(list)
|
351
387
|
else
|
352
|
-
raise RuntimeError.new("Cannot assign value to 'hosts' if web_hosts &/or db_hosts already set.\n web_hosts: #{self.web_hosts}\n db_hosts: #{self.db_hosts}")
|
388
|
+
raise ::RuntimeError.new("Cannot assign value to 'hosts' if web_hosts &/or db_hosts already set.\n web_hosts: #{self.web_hosts}\n db_hosts: #{self.db_hosts}")
|
353
389
|
end
|
354
390
|
end
|
355
391
|
|
@@ -20,6 +20,7 @@ end
|
|
20
20
|
}
|
21
21
|
h1 { font-size: 1.4em;}
|
22
22
|
h2 { font-size: 1.2em;}
|
23
|
+
th, td { text-align: left;}
|
23
24
|
|
24
25
|
#test-summary {
|
25
26
|
padding: 10px;
|
@@ -69,6 +70,9 @@ end
|
|
69
70
|
}
|
70
71
|
.odd { background: #eee;}
|
71
72
|
.even { background: #ccc;}
|
73
|
+
.red { color: #800;}
|
74
|
+
.green { color: #080;}
|
75
|
+
.warn { color: #f80;}
|
72
76
|
</style>
|
73
77
|
<!-- Date: 2011-08-20 -->
|
74
78
|
</head>
|
@@ -81,17 +85,51 @@ end
|
|
81
85
|
<% else %>
|
82
86
|
<p id="test-summary-failed"><%= failures %> of <%= total_tests %> Tests Failed</p>
|
83
87
|
<% end %>
|
84
|
-
<
|
85
|
-
<
|
88
|
+
<h3>Actions:</h3>
|
89
|
+
<table>
|
90
|
+
<% reset_even_odd %>
|
91
|
+
<tr class="<%= even_odd %>">
|
92
|
+
<th>Tests</th>
|
93
|
+
<td><a href="/">All Tests</a></td>
|
94
|
+
<td><a href="/?failed-tests=<%= failed_tests.join(',') %>">Failed Tests</a></td>
|
95
|
+
</tr>
|
96
|
+
<tr class="<%= even_odd %>">
|
97
|
+
<th>Configurator</th>
|
98
|
+
<td><a href="/?run_configurator">Run Configurator</a></td>
|
99
|
+
<td></td>
|
100
|
+
</tr>
|
101
|
+
<!-- <tr class="<%= even_odd %>">
|
102
|
+
<th>Installation</th>
|
103
|
+
<td>Site Specials</td>
|
104
|
+
<td>Site Config</td>
|
105
|
+
</tr> -->
|
106
|
+
</table>
|
86
107
|
</div> <!-- test summary -->
|
87
108
|
|
88
109
|
|
89
110
|
<div class="env-summary">
|
90
111
|
<h2>Host / Site environment</h2>
|
112
|
+
<h3>TddDeploy Variables</h3>
|
91
113
|
<table>
|
114
|
+
<tr><th>Env Var (hover for info)</th><th>Current Value</th></tr>
|
92
115
|
<% reset_even_odd %>
|
93
116
|
<% env_hash.keys.sort.each do |k| %>
|
94
|
-
<tr class="<%= even_odd %>"><th class="env-key"><%= k %></th> <td class="env-value"><%= env_hash[k] %></td></tr>
|
117
|
+
<tr class="<%= even_odd %>"><th class="env-key" title="<%= server_obj.env_desc[k] %>"><%= k %></th> <td class="env-value"><%= env_hash[k] %></td></tr>
|
118
|
+
<% end %>
|
119
|
+
</table>
|
120
|
+
|
121
|
+
<h3>Capistrano Variables</h3>
|
122
|
+
<% if server_obj.app_hosts.sort != (server_obj.app + server_obj.migration_hosts).uniq.sort %>
|
123
|
+
<p class="warn">'app_hosts' does not match Capistrano 'app' and 'migration_hosts'</p>
|
124
|
+
<% end %>
|
125
|
+
<% if server_obj.db_hosts.uniq.sort != server_obj.db.uniq.sort %>
|
126
|
+
<p class="warn">'db_hosts' does not match Capistrano 'db'</p>
|
127
|
+
<% end %>
|
128
|
+
<table>
|
129
|
+
<% reset_even_odd %>
|
130
|
+
<tr><th>Cap Var (hover for info)</th><th>Current Value</th></tr>
|
131
|
+
<% ['app', 'db', 'migration_hosts', 'web'].each do |k| %>
|
132
|
+
<tr class="<%= even_odd %>"><th class="env-key" title="<%= server_obj.env_desc[k] %>"><%= k %></th><td class="env-value"><%= server_obj.send(k.to_sym) %></td></tr>
|
95
133
|
<% end %>
|
96
134
|
</table>
|
97
135
|
</div>
|
@@ -104,7 +142,7 @@ end
|
|
104
142
|
<% if File.exists? tdd_deploy_configs %>
|
105
143
|
<table>
|
106
144
|
<tr class="<%= even_odd %>"><td><%= tdd_deploy_configs %></td></tr>
|
107
|
-
<% ['balance_hosts', 'db_hosts', 'web_hosts'].each do |host_dir| %>
|
145
|
+
<% ['app_hosts', 'balance_hosts', 'db_hosts', 'web_hosts'].each do |host_dir| %>
|
108
146
|
<% host_path = File.join(tdd_deploy_configs, host_dir) %>
|
109
147
|
<% unless File.exists? host_path %>
|
110
148
|
<tr class="<%= even_odd %>"><td></td><td><%= host_dir %> does not exist</td></tr>
|
data/lib/tdd_deploy/server.rb
CHANGED
@@ -9,6 +9,9 @@ module TddDeploy
|
|
9
9
|
#
|
10
10
|
# implements a simple 'rack' server. Methods are either used internally or called
|
11
11
|
# from the web page during page reloads.
|
12
|
+
#
|
13
|
+
# It only displays one page - which is defined in the gem in
|
14
|
+
# lib/tdd_deploy/server-templates/test_results.html.erb.
|
12
15
|
class Server < TddDeploy::Base
|
13
16
|
LIB_DIR = File.expand_path('../..', __FILE__)
|
14
17
|
HOST_TESTS_DIR = File.join(Dir.pwd, 'lib', 'tdd_deploy', 'host_tests')
|
@@ -52,7 +55,7 @@ module TddDeploy
|
|
52
55
|
def call(env)
|
53
56
|
self.query_hash = parse_query_string(env['QUERY_STRING'])
|
54
57
|
|
55
|
-
if query_hash['run_configurator']
|
58
|
+
if self.query_hash['run_configurator']
|
56
59
|
require 'tdd_deploy/configurator'
|
57
60
|
configurator = TddDeploy::Configurator.new
|
58
61
|
configurator.make_configuration_files
|
@@ -162,7 +165,9 @@ module TddDeploy
|
|
162
165
|
f = File.new(TEMPLATE_PATH)
|
163
166
|
template = ERB.new f.read, nil, '<>'
|
164
167
|
f.close
|
165
|
-
|
168
|
+
|
169
|
+
# add 'server_obj' so accessors are accessible from erb template
|
170
|
+
server_obj = self
|
166
171
|
template.result(binding)
|
167
172
|
end
|
168
173
|
|
@@ -1,10 +1,10 @@
|
|
1
1
|
---
|
2
|
-
chdir: <%=
|
2
|
+
chdir: <%= site_doc_root %>
|
3
3
|
environment: production
|
4
4
|
address: 127.0.0.1
|
5
5
|
timeout: 30
|
6
6
|
log: log/thin.log
|
7
|
-
pid: <%=
|
7
|
+
pid: <%= site_doc_root %>/tmp/pids/thin.pid
|
8
8
|
max_conns: 1024
|
9
9
|
max_persistent_conns: 512
|
10
10
|
require: []
|
@@ -1,10 +1,10 @@
|
|
1
|
-
chdir: <%=
|
1
|
+
chdir: <%= site_doc_root %>
|
2
2
|
environment: production
|
3
3
|
address: 127.0.0.1
|
4
4
|
port: <%= site_base_port %>
|
5
5
|
timeout: 30
|
6
6
|
log: log/thin.log
|
7
|
-
pid: <%=
|
7
|
+
pid: <%= site_doc_root %>/tmp/pids/thin.pid
|
8
8
|
max_conns: 1024
|
9
9
|
max_persistent_conns: 512
|
10
10
|
require: []
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<% ((site_base_port)...(site_base_port+site_num_servers)).each do |port| %>
|
2
|
-
check process <%= site %>_server_<%= port %> with pidfile <%= "#{
|
3
|
-
start process = "<%= "#{
|
4
|
-
stop process = "<%= "#{
|
2
|
+
check process <%= site %>_server_<%= port %> with pidfile <%= "#{site_doc_root}/tmp/pids/thin.#{port}.pid" %>
|
3
|
+
start process = "<%= "#{site_doc_root}/site/thin_one_server start #{port}" %>" with timeout 60 seconds
|
4
|
+
stop process = "<%= "#{site_doc_root}/site/thin_one_server stop #{port}" %>"
|
5
5
|
if failed host localhost port <%= port %> protocol http
|
6
6
|
and request "/"
|
7
7
|
then restart
|
@@ -1,10 +1,10 @@
|
|
1
1
|
---
|
2
|
-
chdir: <%=
|
2
|
+
chdir: <%= site_doc_root %>
|
3
3
|
environment: production
|
4
4
|
address: 127.0.0.1
|
5
5
|
timeout: 30
|
6
6
|
log: log/thin.log
|
7
|
-
pid: <%=
|
7
|
+
pid: <%= site_doc_root %>/tmp/pids/thin.pid
|
8
8
|
max_conns: 1024
|
9
9
|
max_persistent_conns: 512
|
10
10
|
require: []
|
@@ -1,10 +1,10 @@
|
|
1
|
-
chdir: <%=
|
1
|
+
chdir: <%= site_doc_root %>
|
2
2
|
environment: production
|
3
3
|
address: 127.0.0.1
|
4
4
|
port: <%= site_base_port %>
|
5
5
|
timeout: 30
|
6
6
|
log: log/thin.log
|
7
|
-
pid: <%=
|
7
|
+
pid: <%= site_doc_root %>/tmp/pids/thin.pid
|
8
8
|
max_conns: 1024
|
9
9
|
max_persistent_conns: 512
|
10
10
|
require: []
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<% ((site_base_port)...(site_base_port+site_num_servers)).each do |port| %>
|
2
|
-
check process <%= site %>_server_<%= port %> with pidfile <%= "#{
|
3
|
-
start process = "<%= "#{
|
4
|
-
stop process = "<%= "#{
|
2
|
+
check process <%= site %>_server_<%= port %> with pidfile <%= "#{site_doc_root}/tmp/pids/thin.#{port}.pid" %>
|
3
|
+
start process = "<%= "#{site_doc_root}/site/thin_one_server start #{port}" %>" with timeout 60 seconds
|
4
|
+
stop process = "<%= "#{site_doc_root}/site/thin_one_server stop #{port}" %>"
|
5
5
|
if failed host localhost port <%= port %> protocol http
|
6
6
|
and request "/"
|
7
7
|
then restart
|
@@ -9,7 +9,7 @@ upstream <%= site %> {
|
|
9
9
|
server {
|
10
10
|
listen 80;
|
11
11
|
server_name <%= site_url %>;
|
12
|
-
root <%=
|
12
|
+
root <%= site_doc_root %>/current;
|
13
13
|
location / {
|
14
14
|
proxy_set_header X-Real-IP $remote_addr;
|
15
15
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<% ((site_base_port)...(site_base_port+site_num_servers)).each do |port| %>
|
2
|
-
check process <%= site %>_server_<%= port %> with pidfile <%= "#{
|
3
|
-
start process = "<%= "#{
|
4
|
-
stop process = "<%= "#{
|
2
|
+
check process <%= site %>_server_<%= port %> with pidfile <%= "#{site_doc_root}/tmp/pids/thin.#{port}.pid" %>
|
3
|
+
start process = "<%= "#{site_doc_root}/site/thin_one_server start #{port}" %>" with timeout 60 seconds
|
4
|
+
stop process = "<%= "#{site_doc_root}/site/thin_one_server stop #{port}" %>"
|
5
5
|
if failed host localhost port <%= port %> protocol http
|
6
6
|
and request "/"
|
7
7
|
then restart
|
@@ -9,7 +9,7 @@ upstream <%= site %> {
|
|
9
9
|
server {
|
10
10
|
listen 80;
|
11
11
|
server_name <%= site_url %>;
|
12
|
-
root <%=
|
12
|
+
root <%= site_doc_root %>/current;
|
13
13
|
location / {
|
14
14
|
proxy_set_header X-Real-IP $remote_addr;
|
15
15
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
@@ -8,44 +8,44 @@ module TddDeploy
|
|
8
8
|
#
|
9
9
|
# The sub directories tested for are:
|
10
10
|
#
|
11
|
-
# * '
|
12
|
-
# * '
|
13
|
-
# * '
|
14
|
-
# * '
|
15
|
-
# * '
|
16
|
-
# *
|
17
|
-
# *
|
11
|
+
# * 'site_doc_root' - DocumentRoot
|
12
|
+
# * 'site_doc_root'/../releases - a standard directory used by Capistrano
|
13
|
+
# * 'site_doc_root'/config/thin.conf - config file for 'thin' server
|
14
|
+
# * 'site_doc_root'/config/one_thin_server.conf - config file for monit to use to restart a single server instance
|
15
|
+
# * '~/site/nginx.conf - an nginx configuratino fragment which tells nginx to proxy the site's *thin* servers
|
16
|
+
# * ~/site/monitrc - a monit configuration fragment which tells monit how to monitor the site's *thin* servers.
|
17
|
+
# * ~/site/one_thin_server - shell script to start a single server instance
|
18
18
|
class SiteLayout < TddDeploy::Base
|
19
19
|
def test_site_subdir
|
20
|
-
deploy_test_file_exists_on_hosts_as self.site_user, self.web_hosts, "#{self.
|
20
|
+
deploy_test_file_exists_on_hosts_as self.site_user, self.web_hosts, "#{self.site_doc_root}"
|
21
21
|
end
|
22
22
|
|
23
23
|
def test_releases_subdir
|
24
|
-
deploy_test_file_exists_on_hosts_as self.site_user, self.web_hosts, "#{self.
|
24
|
+
deploy_test_file_exists_on_hosts_as self.site_user, self.web_hosts, "#{self.site_doc_root}/../releases"
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
deploy_test_file_exists_on_hosts_as self.site_user, self.web_hosts, "#{
|
27
|
+
def test_thin_conf
|
28
|
+
deploy_test_file_exists_on_hosts_as self.site_user, self.web_hosts, "#{site_doc_root}/config/thin.conf"
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
32
|
-
deploy_test_file_exists_on_hosts_as self.site_user, self.web_hosts, "#{
|
31
|
+
def test_one_thin_server_conf
|
32
|
+
deploy_test_file_exists_on_hosts_as self.site_user, self.web_hosts, "#{site_doc_root}/config/one_thin_server.conf"
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
deploy_test_file_exists_on_hosts_as self.site_user, self.web_hosts, "#{
|
35
|
+
def test_site_dir_exists
|
36
|
+
deploy_test_file_exists_on_hosts_as self.site_user, self.web_hosts, "#{site_special_dir}"
|
37
37
|
end
|
38
38
|
|
39
|
-
def
|
40
|
-
deploy_test_file_exists_on_hosts_as self.site_user, self.web_hosts, "#{
|
39
|
+
def test_monitrc
|
40
|
+
deploy_test_file_exists_on_hosts_as self.site_user, self.web_hosts, "#{site_special_dir}/monitrc"
|
41
41
|
end
|
42
42
|
|
43
|
-
def
|
44
|
-
deploy_test_file_exists_on_hosts_as self.site_user, self.web_hosts, "#{
|
43
|
+
def test_nginx_conf
|
44
|
+
deploy_test_file_exists_on_hosts_as self.site_user, self.web_hosts, "#{site_special_dir}/nginx.conf"
|
45
45
|
end
|
46
46
|
|
47
47
|
def test_one_thin_server
|
48
|
-
deploy_test_file_exists_on_hosts_as self.site_user, self.web_hosts, "#{
|
48
|
+
deploy_test_file_exists_on_hosts_as self.site_user, self.web_hosts, "#{site_special_dir}/one_thin_server"
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'tdd_deploy/base'
|
2
|
+
|
3
|
+
module TddDeploy
|
4
|
+
# = TddDeploy::SiteUser
|
5
|
+
#
|
6
|
+
# tests all hosts to make sure that the local user can log on as *site_user*
|
7
|
+
class SiteRvm < TddDeploy::Base
|
8
|
+
def test_rvm
|
9
|
+
deploy_test_on_hosts_as self.site_user, self.app_hosts, /RVM is the Ruby/, "rvm should be installed" do
|
10
|
+
'source ~/.rvm/scripts/rvm ; rvm'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_rvm_current
|
15
|
+
deploy_test_on_hosts_as self.site_user, self.app_hosts, /(ruby|jruby|rbx|ree)-\d\.\d\.\d/, "rvm current should display a ruby" do
|
16
|
+
'source ~/.rvm/scripts/rvm ; rvm current'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_bundle_prescence
|
21
|
+
deploy_test_on_hosts_as self.site_user, self.app_hosts, /Bundler version/, "bundler should run" do
|
22
|
+
'source ~/.rvm/scripts/rvm ; bundle --version'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/tdd_deploy/version.rb
CHANGED
data/tests/test_configurator.rb
CHANGED
@@ -21,13 +21,13 @@ class TestTddDeployConfiguratorTestCase < Test::Unit::TestCase
|
|
21
21
|
FileUtils.rm_rf 'tdd_deploy_configs'
|
22
22
|
@configurator.make_configuration_files
|
23
23
|
assert File.exists?('tdd_deploy_configs'), "tdd_deploy_configs/ exists"
|
24
|
-
[ 'balance_hosts', 'db_hosts', 'web_hosts'].each do |host_dir|
|
24
|
+
['app_hosts', 'balance_hosts', 'db_hosts', 'web_hosts'].each do |host_dir|
|
25
25
|
host_path = File.join('tdd_deploy_configs', host_dir)
|
26
26
|
assert File.exists?(host_path), "#{host_path} exists"
|
27
27
|
['config', 'site'].each do |subdir|
|
28
28
|
subdir_path = File.join(host_path, subdir)
|
29
29
|
assert File.exists?(subdir_path), "#{subdir_path} exists"
|
30
|
-
assert Dir.new(subdir_path).entries.length
|
30
|
+
assert Dir.new(subdir_path).entries.length >= 2, "#{subdir_path} has 3 or more entries"
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
data/tests/test_copy_methods.rb
CHANGED
@@ -18,7 +18,8 @@ class RunMethodsTestCase < Test::Unit::TestCase
|
|
18
18
|
|
19
19
|
def teardown
|
20
20
|
run_on_hosts_as 'site_user', 'arch', 'rm -f test-file'
|
21
|
-
run_on_hosts_as 'site_user', 'arch', '
|
21
|
+
run_on_hosts_as 'site_user', 'arch', 'rm -r test-dir'
|
22
|
+
FileUtils.rm_r 'test-dir' if File.exists? 'test-dir'
|
22
23
|
end
|
23
24
|
|
24
25
|
def test_mkdir_on_remote_as
|
@@ -31,6 +32,24 @@ class RunMethodsTestCase < Test::Unit::TestCase
|
|
31
32
|
assert_equal "success\n", stdout, "deploy_test_file_exists_on_hosts_as says 'test-dir' removed"
|
32
33
|
end
|
33
34
|
|
35
|
+
def test_append_string_to_remote_file_as
|
36
|
+
str = "line 1\nline 2\nline 3\n"
|
37
|
+
result = append_string_to_remote_file_as 'site_user', 'arch', str, 'test-file'
|
38
|
+
assert result, "append_string_to_remote_file_as returns true on success"
|
39
|
+
|
40
|
+
stdout, stderr, cmd = run_in_ssh_session_on_host_as('site_user', 'arch', 'cat test-file')
|
41
|
+
assert_equal str, stdout, "test-file should exist on arch"
|
42
|
+
assert_nil stderr, "stderr should be nil"
|
43
|
+
|
44
|
+
result = append_string_to_remote_file_as 'site_user', 'arch', "another line\n", 'test-file'
|
45
|
+
assert result, "append_string_to_remote_file_as returns true on success"
|
46
|
+
|
47
|
+
stdout, stderr, cmd = run_in_ssh_session_on_host_as('site_user', 'arch', 'cat test-file')
|
48
|
+
assert_match /line 1/, stdout, "output should contain 'line 1'"
|
49
|
+
assert_match /another line/, stdout, "output should contain 'another line'"
|
50
|
+
assert_equal 4, stdout.split("\n").length, "output should contain 4 lines"
|
51
|
+
end
|
52
|
+
|
34
53
|
def test_copy_string_to_remote_file_as
|
35
54
|
str = "line 1\nline 2\nline 3\n"
|
36
55
|
result = copy_string_to_remote_file_as 'site_user', 'arch', str, 'test-file'
|
@@ -58,6 +77,31 @@ class RunMethodsTestCase < Test::Unit::TestCase
|
|
58
77
|
tmp_file.unlink
|
59
78
|
end
|
60
79
|
end
|
80
|
+
|
81
|
+
def test_append_file_to_remote_file_as
|
82
|
+
require 'tempfile'
|
83
|
+
tmp_file = Tempfile.new('foo')
|
84
|
+
tmp2_file = Tempfile.new('bar')
|
85
|
+
begin
|
86
|
+
input_text = "line one\nline two\nline 3\n"
|
87
|
+
tmp_file.write input_text
|
88
|
+
tmp_file.close
|
89
|
+
|
90
|
+
input2_text = "line from file 2\n"
|
91
|
+
tmp2_file.write input2_text
|
92
|
+
tmp2_file.close
|
93
|
+
assert append_file_to_remote_file_as('site_user', 'arch', tmp_file.path, 'test-file'), 'copy file should work'
|
94
|
+
stdout, stderr, cmd = run_in_ssh_session_on_host_as 'site_user', 'arch', 'cat test-file'
|
95
|
+
assert_equal input_text, stdout, "remote file should contain input_text"
|
96
|
+
|
97
|
+
assert append_file_to_remote_file_as('site_user', 'arch', tmp2_file.path, 'test-file'), 'append should return true'
|
98
|
+
stdout, stderr, cmd = run_in_ssh_session_on_host_as 'site_user', 'arch', 'cat test-file'
|
99
|
+
assert_equal input_text + input2_text, stdout, "remote file should contain input_text + input2_text"
|
100
|
+
ensure
|
101
|
+
tmp_file.unlink
|
102
|
+
tmp2_file.unlink
|
103
|
+
end
|
104
|
+
end
|
61
105
|
|
62
106
|
def test_copy_string_to_remote_on_hosts_as
|
63
107
|
host_list = ['arch']
|
@@ -104,4 +148,98 @@ class RunMethodsTestCase < Test::Unit::TestCase
|
|
104
148
|
end
|
105
149
|
end
|
106
150
|
|
151
|
+
def test_copy_dir_to_remote_on_hosts_as
|
152
|
+
host_list = ['arch']
|
153
|
+
dir_name = 'test-dir'
|
154
|
+
Dir.mkdir dir_name unless File.exists? dir_name
|
155
|
+
['foo', 'bar', 'baz'].each do |fname|
|
156
|
+
path = File.join(dir_name, fname)
|
157
|
+
f = File.new(path, 'w')
|
158
|
+
f.write "This is a file named #{fname}\n"
|
159
|
+
f.close
|
160
|
+
end
|
161
|
+
|
162
|
+
assert copy_dir_to_remote_on_hosts_as('site_user', host_list, dir_name, dir_name), 'copy directory should work'
|
163
|
+
|
164
|
+
result_hash = run_on_hosts_as 'site_user', host_list, "ls"
|
165
|
+
assert_match Regexp.new(dir_name), result_hash['arch'][0], "ls of home should contain directory name"
|
166
|
+
|
167
|
+
result_hash = run_on_hosts_as 'site_user', host_list, "ls #{dir_name}"
|
168
|
+
listing = result_hash['arch'][0].split(/\n/)
|
169
|
+
['foo', 'bar', 'baz'].each do |fname|
|
170
|
+
assert listing.include?(fname), "listing of remote directory contains '#{fname}'"
|
171
|
+
end
|
172
|
+
['foo', 'bar', 'baz'].each do |fname|
|
173
|
+
path = File.join dir_name, fname
|
174
|
+
stdout, stderr, cmd = run_in_ssh_session_on_host_as 'site_user', 'arch', "cat #{path}"
|
175
|
+
assert_equal "This is a file named #{fname}\n", stdout, "copy_dir... should copy file contents of #{fname}"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_append_string_to_remote_on_hosts_as_with_host_list_as_str
|
180
|
+
host_list = 'arch'
|
181
|
+
str = "line 1\nline 2\nline 3\n"
|
182
|
+
result = append_string_to_remote_file_on_hosts_as 'site_user', host_list, str, 'test-file'
|
183
|
+
assert result, "append_string_to_remote_file_as returns true on success"
|
184
|
+
|
185
|
+
result = run_on_hosts_as('site_user', host_list, 'cat test-file')
|
186
|
+
refute_nil result, "run_on_hosts_as ran on #{host_list.inspect}"
|
187
|
+
assert_equal str, result['arch'][0], "test-file should exist on arch"
|
188
|
+
assert_nil result['arch'][1], "stderr should be nil"
|
189
|
+
|
190
|
+
str2 = "another string\n"
|
191
|
+
assert append_string_to_remote_file_on_hosts_as 'site_user', host_list, str2, 'test-file'
|
192
|
+
|
193
|
+
result = run_on_hosts_as('site_user', host_list, 'cat test-file')
|
194
|
+
assert_equal str + str2, result['arch'][0], "test-file should exist on arch"
|
195
|
+
end
|
196
|
+
|
197
|
+
|
198
|
+
def test_append_file_to_remote_on_hosts_as
|
199
|
+
host_list = ['arch']
|
200
|
+
require 'tempfile'
|
201
|
+
tmp_file = Tempfile.new('foo')
|
202
|
+
begin
|
203
|
+
input_text = "line one\nline two\nline 3\n"
|
204
|
+
tmp_file.write input_text
|
205
|
+
tmp_file.close
|
206
|
+
assert append_file_to_remote_on_hosts_as('site_user', host_list, tmp_file.path, 'test-file'), 'should work'
|
207
|
+
assert append_file_to_remote_on_hosts_as('site_user', host_list, tmp_file.path, 'test-file'), 'should work'
|
208
|
+
|
209
|
+
results = run_on_hosts_as 'site_user', host_list, 'cat test-file'
|
210
|
+
assert_equal input_text * 2, results['arch'][0], "remote file should contain input_text"
|
211
|
+
ensure
|
212
|
+
tmp_file.unlink
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_append_dir_to_remote_on_hosts_as
|
217
|
+
host_list = ['arch']
|
218
|
+
dir_name = 'test-dir'
|
219
|
+
Dir.mkdir dir_name unless File.exists? dir_name
|
220
|
+
['foo', 'bar', 'baz'].each do |fname|
|
221
|
+
path = File.join(dir_name, fname)
|
222
|
+
f = File.new(path, 'w')
|
223
|
+
f.write "This is a file named #{fname}\n"
|
224
|
+
f.close
|
225
|
+
end
|
226
|
+
|
227
|
+
assert append_dir_to_remote_on_hosts_as('site_user', host_list, dir_name, dir_name), 'append directory should work'
|
228
|
+
assert append_dir_to_remote_on_hosts_as('site_user', host_list, dir_name, dir_name), 'append directory should work'
|
229
|
+
|
230
|
+
result_hash = run_on_hosts_as 'site_user', host_list, "ls"
|
231
|
+
assert_match Regexp.new(dir_name), result_hash['arch'][0], "ls of home should contain directory name"
|
232
|
+
|
233
|
+
result_hash = run_on_hosts_as 'site_user', host_list, "ls #{dir_name}"
|
234
|
+
listing = result_hash['arch'][0].split(/\n/)
|
235
|
+
['foo', 'bar', 'baz'].each do |fname|
|
236
|
+
assert listing.include?(fname), "listing of remote directory contains '#{fname}'"
|
237
|
+
end
|
238
|
+
['foo', 'bar', 'baz'].each do |fname|
|
239
|
+
path = File.join dir_name, fname
|
240
|
+
stdout, stderr, cmd = run_in_ssh_session_on_host_as 'site_user', 'arch', "cat #{path}"
|
241
|
+
assert_equal "This is a file named #{fname}\nThis is a file named #{fname}\n", stdout, "append_dir... should append file contents of #{fname}"
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
107
245
|
end
|
data/tests/test_environ.rb
CHANGED
@@ -61,7 +61,7 @@ class TestEnvironTestCase < Test::Unit::TestCase
|
|
61
61
|
def test_resonse_to_instance_assessors
|
62
62
|
[:env_hash, :ssh_timeout, :site_base_port, :site_num_servers,
|
63
63
|
:host_admin, :local_admin, :local_admin_email,
|
64
|
-
:site, :site_user, :
|
64
|
+
:site, :site_user, :site_doc_root, :site_special_dir, :site_url,
|
65
65
|
:capfile_paths, :app, :db, :migration_hosts, :web,
|
66
66
|
:hosts, :app_hosts, :balance_hosts, :db_hosts, :web_hosts].each do |meth|
|
67
67
|
assert @foo.respond_to?(meth), "@foo should respond to #{meth}"
|
@@ -71,13 +71,13 @@ class TestEnvironTestCase < Test::Unit::TestCase
|
|
71
71
|
|
72
72
|
def test_env_type
|
73
73
|
["ssh_timeout", "site_base_port", "site_num_servers", "host_admin", "local_admin", "local_admin_email",
|
74
|
-
"site", "site_user", "
|
74
|
+
"site", "site_user", "site_doc_root", "site_special_dir", "site_url", 'app_hosts', "balance_hosts", "db_hosts", "web_hosts"].each do |sym|
|
75
75
|
assert @foo.env_types.keys.include?(sym.to_s), "@foo.env_types.keys includes #{sym}"
|
76
76
|
end
|
77
77
|
["ssh_timeout", "site_base_port", "site_num_servers"].each do |key|
|
78
78
|
assert_equal :int, @foo.env_types[key], "@foo.env_types[#{key}] should be :int"
|
79
79
|
end
|
80
|
-
["host_admin", "local_admin", "local_admin_email", "site", "site_user", "
|
80
|
+
["host_admin", "local_admin", "local_admin_email", "site", "site_user", "site_doc_root", "site_special_dir", "site_special_dir", "site_url"].each do |key|
|
81
81
|
assert_equal :string, @foo.env_types[key], "@foo.env_types[#{key}] should be :string"
|
82
82
|
end
|
83
83
|
['app_hosts', "balance_hosts", "capfile_paths", "db_hosts", "web_hosts"].each do |key|
|
@@ -100,14 +100,14 @@ class TestEnvironTestCase < Test::Unit::TestCase
|
|
100
100
|
|
101
101
|
def test_env_hash
|
102
102
|
["ssh_timeout", "site_base_port", "site_num_servers", "host_admin", "local_admin", "local_admin_email",
|
103
|
-
"site", "site_user", "
|
103
|
+
"site", "site_user", "site_doc_root", "site_special_dir", "site_url", 'app_hosts', "balance_hosts", "db_hosts", "web_hosts"].each do |key|
|
104
104
|
assert_not_nil @foo.env_hash[key], "@foo.env_hash[#{key}] should not be nil"
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
108
|
def test_env_defaults
|
109
109
|
["ssh_timeout", "site_base_port", "site_num_servers", "host_admin", "local_admin", "local_admin_email",
|
110
|
-
"site", "site_user", "
|
110
|
+
"site", "site_user", "site_doc_root", "site_special_dir", "site_url", 'app_hosts', "balance_hosts", "db_hosts", "web_hosts"].each do |key|
|
111
111
|
assert_not_nil @foo.env_defaults[key], "@foo.env_defaults[#{key}] should not be nil"
|
112
112
|
end
|
113
113
|
end
|
@@ -122,7 +122,7 @@ class TestEnvironTestCase < Test::Unit::TestCase
|
|
122
122
|
@foo.send "#{key}=", tmp
|
123
123
|
assert_equal tmp, @foo.send(key.to_sym), "@foo.#{key} should now be #{tmp}"
|
124
124
|
end
|
125
|
-
["host_admin", "local_admin", "local_admin_email", "site", "site_user", "
|
125
|
+
["host_admin", "local_admin", "local_admin_email", "site", "site_user", "site_doc_root", "site_special_dir", "site_url"].each do |key|
|
126
126
|
tmp = "#{key}-changed"
|
127
127
|
@foo.send "#{key}=", tmp
|
128
128
|
assert_equal tmp, @foo.send(key.to_sym), "@foo.#{key} should now be #{tmp}"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tdd_deploy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2011-08-16 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: capistrano
|
16
|
-
requirement: &
|
16
|
+
requirement: &2160122860 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2160122860
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: net-ping
|
27
|
-
requirement: &
|
27
|
+
requirement: &2160122180 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2160122180
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: net-ssh
|
38
|
-
requirement: &
|
38
|
+
requirement: &2160121720 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,21 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2160121720
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rack
|
49
|
+
requirement: &2160121060 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2160121060
|
47
58
|
- !ruby/object:Gem::Dependency
|
48
59
|
name: ZenTest
|
49
|
-
requirement: &
|
60
|
+
requirement: &2160120340 !ruby/object:Gem::Requirement
|
50
61
|
none: false
|
51
62
|
requirements:
|
52
63
|
- - ~>
|
@@ -54,10 +65,10 @@ dependencies:
|
|
54
65
|
version: 4.5.0
|
55
66
|
type: :development
|
56
67
|
prerelease: false
|
57
|
-
version_requirements: *
|
68
|
+
version_requirements: *2160120340
|
58
69
|
- !ruby/object:Gem::Dependency
|
59
70
|
name: autotest-growl
|
60
|
-
requirement: &
|
71
|
+
requirement: &2160119700 !ruby/object:Gem::Requirement
|
61
72
|
none: false
|
62
73
|
requirements:
|
63
74
|
- - ! '>='
|
@@ -65,7 +76,7 @@ dependencies:
|
|
65
76
|
version: '0'
|
66
77
|
type: :development
|
67
78
|
prerelease: false
|
68
|
-
version_requirements: *
|
79
|
+
version_requirements: *2160119700
|
69
80
|
description: Test driven support for host provisioning & Capistrano deployment - for
|
70
81
|
those who don't want to bother learning too much
|
71
82
|
email: ! ' mike@clove.com '
|
@@ -99,6 +110,7 @@ files:
|
|
99
110
|
- lib/tdd_deploy/server.rb
|
100
111
|
- lib/tdd_deploy/site_tests/site_database.rb
|
101
112
|
- lib/tdd_deploy/site_tests/site_layout.rb
|
113
|
+
- lib/tdd_deploy/site_tests/site_rvm.rb
|
102
114
|
- lib/tdd_deploy/site_tests/site_user.rb
|
103
115
|
- lib/tdd_deploy/version.rb
|
104
116
|
- lib/tdd_deploy.rb
|
@@ -126,21 +138,17 @@ files:
|
|
126
138
|
- tests/test_tdd_deploy_server.rb
|
127
139
|
- lib/tasks/tdd_deploy.rake
|
128
140
|
- lib/tdd_deploy/server-templates/test_results.html.erb
|
141
|
+
- lib/tdd_deploy/site-erb/app_hosts/config/one_thin_server.conf.erb
|
142
|
+
- lib/tdd_deploy/site-erb/app_hosts/config/thin.conf.erb
|
143
|
+
- lib/tdd_deploy/site-erb/app_hosts/site/monitrc.erb
|
144
|
+
- lib/tdd_deploy/site-erb/app_hosts/site/one_thin_server.erb
|
129
145
|
- lib/tdd_deploy/site-erb/balance_hosts/config/one_thin_server.conf.erb
|
130
146
|
- lib/tdd_deploy/site-erb/balance_hosts/config/thin.conf.erb
|
131
147
|
- lib/tdd_deploy/site-erb/balance_hosts/site/monitrc.erb
|
132
148
|
- lib/tdd_deploy/site-erb/balance_hosts/site/nginx.conf.erb
|
133
149
|
- lib/tdd_deploy/site-erb/balance_hosts/site/one_thin_server.erb
|
134
|
-
- lib/tdd_deploy/site-erb/db_hosts/config/one_thin_server.conf.erb
|
135
|
-
- lib/tdd_deploy/site-erb/db_hosts/config/thin.conf.erb
|
136
|
-
- lib/tdd_deploy/site-erb/db_hosts/site/monitrc.erb
|
137
|
-
- lib/tdd_deploy/site-erb/db_hosts/site/nginx.conf.erb
|
138
|
-
- lib/tdd_deploy/site-erb/db_hosts/site/one_thin_server.erb
|
139
|
-
- lib/tdd_deploy/site-erb/web_hosts/config/one_thin_server.conf.erb
|
140
|
-
- lib/tdd_deploy/site-erb/web_hosts/config/thin.conf.erb
|
141
150
|
- lib/tdd_deploy/site-erb/web_hosts/site/monitrc.erb
|
142
151
|
- lib/tdd_deploy/site-erb/web_hosts/site/nginx.conf.erb
|
143
|
-
- lib/tdd_deploy/site-erb/web_hosts/site/one_thin_server.erb
|
144
152
|
homepage: https://github.com/mikehoward/tdd_deploy
|
145
153
|
licenses:
|
146
154
|
- GPL3
|
@@ -1,29 +0,0 @@
|
|
1
|
-
host {
|
2
|
-
|
3
|
-
}
|
4
|
-
upstream <%= site %> {
|
5
|
-
<% ((site_base_port)...(site_base_port+site_num_servers)).each do |port| %>
|
6
|
-
server 127.0.0.1:<%= port %>;
|
7
|
-
<% end %>
|
8
|
-
}
|
9
|
-
server {
|
10
|
-
listen 80;
|
11
|
-
server_name <%= site_url %>;
|
12
|
-
root <%= site_path %>/current;
|
13
|
-
location / {
|
14
|
-
proxy_set_header X-Real-IP $remote_addr;
|
15
|
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
16
|
-
proxy_set_header Host $http_host;
|
17
|
-
proxy_redirect false;
|
18
|
-
try_files $uri $uri/index.html $uri.html @thin;
|
19
|
-
location / {
|
20
|
-
include proxy.conf;
|
21
|
-
proxy_pass http://<%= site %>;
|
22
|
-
}
|
23
|
-
}
|
24
|
-
|
25
|
-
error_page 500 502 503 504 /500.html;
|
26
|
-
location = /500.html {
|
27
|
-
root html;
|
28
|
-
}
|
29
|
-
}
|
@@ -1,14 +0,0 @@
|
|
1
|
-
---
|
2
|
-
chdir: <%= site_path %>
|
3
|
-
environment: production
|
4
|
-
address: 127.0.0.1
|
5
|
-
timeout: 30
|
6
|
-
log: log/thin.log
|
7
|
-
pid: <%= site_path %>/tmp/pids/thin.pid
|
8
|
-
max_conns: 1024
|
9
|
-
max_persistent_conns: 512
|
10
|
-
require: []
|
11
|
-
|
12
|
-
wait: 30
|
13
|
-
server: 1
|
14
|
-
daemonize: true
|
@@ -1,14 +0,0 @@
|
|
1
|
-
chdir: <%= site_path %>
|
2
|
-
environment: production
|
3
|
-
address: 127.0.0.1
|
4
|
-
port: <%= site_base_port %>
|
5
|
-
timeout: 30
|
6
|
-
log: log/thin.log
|
7
|
-
pid: <%= site_path %>/tmp/pids/thin.pid
|
8
|
-
max_conns: 1024
|
9
|
-
max_persistent_conns: 512
|
10
|
-
require: []
|
11
|
-
|
12
|
-
wait: 30
|
13
|
-
servers: <%= site_num_servers %>
|
14
|
-
daemonize: true
|