engineyard-serverside 1.5.33 → 1.5.35.pre.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/engineyard-serverside.rb +1 -1
- data/lib/engineyard-serverside/deploy.rb +7 -12
- data/lib/engineyard-serverside/logged_output.rb +5 -4
- data/lib/engineyard-serverside/server.rb +2 -2
- data/lib/engineyard-serverside/task.rb +2 -2
- data/lib/engineyard-serverside/version.rb +1 -1
- data/lib/vendor/systemu/LICENSE +3 -0
- data/lib/vendor/systemu/lib/systemu.rb +363 -0
- data/lib/vendor/systemu/systemu.gemspec +45 -0
- data/spec/spec_helper.rb +0 -13
- metadata +6 -9
- data/lib/vendor/open4/lib/open4.rb +0 -403
- data/spec/fixtures/gitrepo/bar +0 -0
|
@@ -8,7 +8,7 @@ else
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
$LOAD_PATH.unshift File.expand_path('vendor/thor/lib', File.dirname(__FILE__))
|
|
11
|
-
$LOAD_PATH.unshift File.expand_path('vendor/
|
|
11
|
+
$LOAD_PATH.unshift File.expand_path('vendor/systemu/lib', File.dirname(__FILE__))
|
|
12
12
|
$LOAD_PATH.unshift File.expand_path('vendor/escape/lib', File.dirname(__FILE__))
|
|
13
13
|
$LOAD_PATH.unshift File.expand_path('vendor/json_pure/lib', File.dirname(__FILE__))
|
|
14
14
|
|
|
@@ -193,11 +193,10 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
|
|
|
193
193
|
# create it on all the servers that will need it.
|
|
194
194
|
# TODO - This logic likely fails when people change deploy keys.
|
|
195
195
|
def ssh_executable
|
|
196
|
-
path = ssh_wrapper_path
|
|
197
196
|
roles :app_master, :app, :solo, :util do
|
|
198
197
|
run(generate_ssh_wrapper)
|
|
199
198
|
end
|
|
200
|
-
|
|
199
|
+
ssh_wrapper_path
|
|
201
200
|
end
|
|
202
201
|
|
|
203
202
|
# We specify 'IdentitiesOnly' to avoid failures on systems with > 5 private keys available.
|
|
@@ -206,16 +205,12 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
|
|
|
206
205
|
# Learned this at http://lists.mindrot.org/pipermail/openssh-unix-dev/2009-February/027271.html
|
|
207
206
|
# (Thanks Jim L.)
|
|
208
207
|
def generate_ssh_wrapper
|
|
209
|
-
path = ssh_wrapper_path
|
|
210
208
|
identity_file = "~/.ssh/#{c.app}-deploy-key"
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
ssh -o
|
|
216
|
-
SSH
|
|
217
|
-
chmod 0700 #{path}
|
|
218
|
-
WRAP
|
|
209
|
+
%{ echo "#{wrapper_for(identity_file)}" > #{ssh_wrapper_path} && chmod 0700 #{ssh_wrapper_path} }
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def wrapper_for(identity)
|
|
213
|
+
"#!/bin/sh\nunset SSH_AUTH_SOCK; ssh -o CheckHostIP=no -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o LogLevel=DEBUG -o IdentityFile=#{identity} -o IdentitiesOnly=yes -o UserKnownHostsFile=/dev/null $*"
|
|
219
214
|
end
|
|
220
215
|
|
|
221
216
|
def ssh_wrapper_path
|
|
@@ -387,7 +382,7 @@ WRAP
|
|
|
387
382
|
end
|
|
388
383
|
|
|
389
384
|
def callback(what)
|
|
390
|
-
@callbacks_reached
|
|
385
|
+
@callbacks_reached = true
|
|
391
386
|
if File.exist?("#{c.release_path}/deploy/#{what}.rb")
|
|
392
387
|
run Escape.shell_command(base_callback_command_for(what)) do |server, cmd|
|
|
393
388
|
per_instance_args = [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'systemu'
|
|
2
2
|
|
|
3
3
|
module EY
|
|
4
4
|
module Serverside
|
|
@@ -62,10 +62,11 @@ module EY
|
|
|
62
62
|
out = verbose? ? Tee.new($stdout, log) : log
|
|
63
63
|
err = Tee.new($stderr, log) # we always want to see errors
|
|
64
64
|
|
|
65
|
+
cmd = "sh -c #{Escape.shell_command([cmd])}"
|
|
66
|
+
puts "running #{cmd}" if ENV['DEBUG']
|
|
65
67
|
out << with_timestamp(":: running #{cmd}\n")
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
status = Open4.spawn cmd, :stdin => '', :stdout => out, :quiet => true # leaving :stderr out for now
|
|
68
|
+
status = systemu cmd, 'stdout' => out, 'stderr' => err
|
|
69
|
+
puts "exit status= #{status.exitstatus}" if ENV['DEBUG']
|
|
69
70
|
status.exitstatus == 0
|
|
70
71
|
end
|
|
71
72
|
end
|
|
@@ -83,12 +83,12 @@ module EY
|
|
|
83
83
|
if local?
|
|
84
84
|
logged_system(command)
|
|
85
85
|
else
|
|
86
|
-
logged_system(ssh_command
|
|
86
|
+
logged_system("#{ssh_command} #{user}@#{hostname} #{command}")
|
|
87
87
|
end
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
def ssh_command
|
|
91
|
-
"ssh -i #{ENV['HOME']}/.ssh/internal -o StrictHostKeyChecking=no -o PasswordAuthentication=no"
|
|
91
|
+
"ssh -i #{ENV['HOME']}/.ssh/internal -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PasswordAuthentication=no"
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
end
|
|
@@ -50,11 +50,11 @@ module EY
|
|
|
50
50
|
|
|
51
51
|
private
|
|
52
52
|
|
|
53
|
-
def run_on_roles(cmd,
|
|
53
|
+
def run_on_roles(cmd, &block)
|
|
54
54
|
servers = EY::Serverside::Server.from_roles(@roles)
|
|
55
55
|
futures = EY::Serverside::Future.call(servers, block_given?) do |server, exec_block|
|
|
56
56
|
to_run = exec_block ? block.call(server, cmd.dup) : cmd
|
|
57
|
-
server.run(
|
|
57
|
+
server.run(to_run)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
unless EY::Serverside::Future.success?(futures)
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'tmpdir'
|
|
4
|
+
require 'socket'
|
|
5
|
+
require 'fileutils'
|
|
6
|
+
require 'rbconfig'
|
|
7
|
+
require 'thread'
|
|
8
|
+
|
|
9
|
+
class Object
|
|
10
|
+
def systemu(*a, &b) SystemUniversal.new(*a, &b).systemu end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class SystemUniversal
|
|
14
|
+
#
|
|
15
|
+
# constants
|
|
16
|
+
#
|
|
17
|
+
SystemUniversal::VERSION = '2.5.0' unless SystemUniversal.send(:const_defined?, :VERSION)
|
|
18
|
+
def SystemUniversal.version() SystemUniversal::VERSION end
|
|
19
|
+
def version() SystemUniversal::VERSION end
|
|
20
|
+
#
|
|
21
|
+
# class methods
|
|
22
|
+
#
|
|
23
|
+
|
|
24
|
+
@host = Socket.gethostname
|
|
25
|
+
@ppid = Process.ppid
|
|
26
|
+
@pid = Process.pid
|
|
27
|
+
@turd = ENV['SYSTEMU_TURD']
|
|
28
|
+
|
|
29
|
+
c = begin; ::RbConfig::CONFIG; rescue NameError; ::Config::CONFIG; end
|
|
30
|
+
ruby = File.join(c['bindir'], c['ruby_install_name']) << c['EXEEXT']
|
|
31
|
+
@ruby = if system('%s -e 42' % ruby)
|
|
32
|
+
ruby
|
|
33
|
+
else
|
|
34
|
+
system('%s -e 42' % 'ruby') ? 'ruby' : warn('no ruby in PATH/CONFIG')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class << SystemUniversal
|
|
38
|
+
%w( host ppid pid ruby turd ).each{|a| attr_accessor a}
|
|
39
|
+
|
|
40
|
+
def quote(*words)
|
|
41
|
+
words.map{|word| word.inspect}.join(' ')
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
#
|
|
46
|
+
# instance methods
|
|
47
|
+
#
|
|
48
|
+
|
|
49
|
+
def initialize argv, opts = {}, &block
|
|
50
|
+
getopt = getopts opts
|
|
51
|
+
|
|
52
|
+
@argv = argv
|
|
53
|
+
@block = block
|
|
54
|
+
|
|
55
|
+
@stdin = getopt[ ['stdin', 'in', '0', 0] ]
|
|
56
|
+
@stdout = getopt[ ['stdout', 'out', '1', 1] ]
|
|
57
|
+
@stderr = getopt[ ['stderr', 'err', '2', 2] ]
|
|
58
|
+
@env = getopt[ 'env' ]
|
|
59
|
+
@cwd = getopt[ 'cwd' ]
|
|
60
|
+
|
|
61
|
+
@host = getopt[ 'host', self.class.host ]
|
|
62
|
+
@ppid = getopt[ 'ppid', self.class.ppid ]
|
|
63
|
+
@pid = getopt[ 'pid', self.class.pid ]
|
|
64
|
+
@ruby = getopt[ 'ruby', self.class.ruby ]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def systemu
|
|
68
|
+
tmpdir do |tmp|
|
|
69
|
+
c = child_setup tmp
|
|
70
|
+
status = nil
|
|
71
|
+
|
|
72
|
+
begin
|
|
73
|
+
thread = nil
|
|
74
|
+
|
|
75
|
+
quietly{
|
|
76
|
+
IO.popen "#{ quote(@ruby) } #{ quote(c['program']) }", 'r+' do |pipe|
|
|
77
|
+
line = pipe.gets
|
|
78
|
+
case line
|
|
79
|
+
when %r/^pid: \d+$/
|
|
80
|
+
cid = Integer line[%r/\d+/]
|
|
81
|
+
else
|
|
82
|
+
begin
|
|
83
|
+
buf = pipe.read
|
|
84
|
+
buf = "#{ line }#{ buf }"
|
|
85
|
+
e = Marshal.load buf
|
|
86
|
+
raise unless Exception === e
|
|
87
|
+
raise e
|
|
88
|
+
rescue
|
|
89
|
+
raise "wtf?\n#{ buf }\n"
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
thread = new_thread cid, @block if @block
|
|
93
|
+
pipe.read rescue nil
|
|
94
|
+
end
|
|
95
|
+
}
|
|
96
|
+
status = $?
|
|
97
|
+
ensure
|
|
98
|
+
if thread
|
|
99
|
+
begin
|
|
100
|
+
class << status
|
|
101
|
+
attr 'thread'
|
|
102
|
+
end
|
|
103
|
+
status.instance_eval{ @thread = thread }
|
|
104
|
+
rescue
|
|
105
|
+
42
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
if @stdout or @stderr
|
|
111
|
+
open(c['stdout']){|f| relay f => @stdout} if @stdout
|
|
112
|
+
open(c['stderr']){|f| relay f => @stderr} if @stderr
|
|
113
|
+
status
|
|
114
|
+
else
|
|
115
|
+
[status, IO.read(c['stdout']), IO.read(c['stderr'])]
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def quote *args, &block
|
|
121
|
+
SystemUniversal.quote(*args, &block)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def new_thread cid, block
|
|
125
|
+
q = Queue.new
|
|
126
|
+
Thread.new(cid) do |cid|
|
|
127
|
+
current = Thread.current
|
|
128
|
+
current.abort_on_exception = true
|
|
129
|
+
q.push current
|
|
130
|
+
block.call cid
|
|
131
|
+
end
|
|
132
|
+
q.pop
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def child_setup tmp
|
|
136
|
+
stdin = File.expand_path(File.join(tmp, 'stdin'))
|
|
137
|
+
stdout = File.expand_path(File.join(tmp, 'stdout'))
|
|
138
|
+
stderr = File.expand_path(File.join(tmp, 'stderr'))
|
|
139
|
+
program = File.expand_path(File.join(tmp, 'program'))
|
|
140
|
+
config = File.expand_path(File.join(tmp, 'config'))
|
|
141
|
+
|
|
142
|
+
if @stdin
|
|
143
|
+
open(stdin, 'w'){|f| relay @stdin => f}
|
|
144
|
+
else
|
|
145
|
+
FileUtils.touch stdin
|
|
146
|
+
end
|
|
147
|
+
FileUtils.touch stdout
|
|
148
|
+
FileUtils.touch stderr
|
|
149
|
+
|
|
150
|
+
c = {}
|
|
151
|
+
c['argv'] = @argv
|
|
152
|
+
c['env'] = @env
|
|
153
|
+
c['cwd'] = @cwd
|
|
154
|
+
c['stdin'] = stdin
|
|
155
|
+
c['stdout'] = stdout
|
|
156
|
+
c['stderr'] = stderr
|
|
157
|
+
c['program'] = program
|
|
158
|
+
open(config, 'w'){|f| Marshal.dump(c, f)}
|
|
159
|
+
|
|
160
|
+
open(program, 'w'){|f| f.write child_program(config)}
|
|
161
|
+
|
|
162
|
+
c
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def quietly
|
|
166
|
+
v = $VERBOSE
|
|
167
|
+
$VERBOSE = nil
|
|
168
|
+
yield
|
|
169
|
+
ensure
|
|
170
|
+
$VERBOSE = v
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def child_program config
|
|
174
|
+
<<-program
|
|
175
|
+
# encoding: utf-8
|
|
176
|
+
|
|
177
|
+
PIPE = STDOUT.dup
|
|
178
|
+
begin
|
|
179
|
+
config = Marshal.load(IO.read('#{ config }'))
|
|
180
|
+
|
|
181
|
+
argv = config['argv']
|
|
182
|
+
env = config['env']
|
|
183
|
+
cwd = config['cwd']
|
|
184
|
+
stdin = config['stdin']
|
|
185
|
+
stdout = config['stdout']
|
|
186
|
+
stderr = config['stderr']
|
|
187
|
+
|
|
188
|
+
Dir.chdir cwd if cwd
|
|
189
|
+
env.each{|k,v| ENV[k.to_s] = v.to_s} if env
|
|
190
|
+
|
|
191
|
+
STDIN.reopen stdin
|
|
192
|
+
STDOUT.reopen stdout
|
|
193
|
+
STDERR.reopen stderr
|
|
194
|
+
|
|
195
|
+
PIPE.puts "pid: \#{ Process.pid }"
|
|
196
|
+
PIPE.flush ### the process is ready yo!
|
|
197
|
+
PIPE.close
|
|
198
|
+
if RUBY_VERSION >= "1.9"
|
|
199
|
+
exec *argv
|
|
200
|
+
else
|
|
201
|
+
exec argv
|
|
202
|
+
end
|
|
203
|
+
rescue Exception => e
|
|
204
|
+
PIPE.write Marshal.dump(e) rescue nil
|
|
205
|
+
exit 42
|
|
206
|
+
end
|
|
207
|
+
program
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def relay srcdst
|
|
211
|
+
src, dst, ignored = srcdst.to_a.first
|
|
212
|
+
if src.respond_to? 'read'
|
|
213
|
+
while((buf = src.read(8192))); dst << buf; end
|
|
214
|
+
else
|
|
215
|
+
if src.respond_to?(:each_line)
|
|
216
|
+
src.each_line{|buf| dst << buf}
|
|
217
|
+
else
|
|
218
|
+
src.each{|buf| dst << buf}
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def tmpdir d = Dir.tmpdir, max = 42, &b
|
|
224
|
+
i = -1 and loop{
|
|
225
|
+
i += 1
|
|
226
|
+
|
|
227
|
+
tmp = File.join d, "systemu_#{ @host }_#{ @ppid }_#{ @pid }_#{ rand }_#{ i += 1 }"
|
|
228
|
+
|
|
229
|
+
begin
|
|
230
|
+
Dir.mkdir tmp
|
|
231
|
+
rescue Errno::EEXIST
|
|
232
|
+
raise if i >= max
|
|
233
|
+
next
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
break(
|
|
237
|
+
if b
|
|
238
|
+
begin
|
|
239
|
+
b.call tmp
|
|
240
|
+
ensure
|
|
241
|
+
FileUtils.rm_rf tmp unless SystemU.turd
|
|
242
|
+
end
|
|
243
|
+
else
|
|
244
|
+
tmp
|
|
245
|
+
end
|
|
246
|
+
)
|
|
247
|
+
}
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def getopts opts = {}
|
|
251
|
+
lambda do |*args|
|
|
252
|
+
keys, default, ignored = args
|
|
253
|
+
catch(:opt) do
|
|
254
|
+
[keys].flatten.each do |key|
|
|
255
|
+
[key, key.to_s, key.to_s.intern].each do |key|
|
|
256
|
+
throw :opt, opts[key] if opts.has_key?(key)
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
default
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
# some monkeypatching for JRuby
|
|
266
|
+
if defined? JRUBY_VERSION
|
|
267
|
+
require 'jruby'
|
|
268
|
+
java_import org.jruby.RubyProcess
|
|
269
|
+
|
|
270
|
+
class SystemUniversal
|
|
271
|
+
def systemu
|
|
272
|
+
split_argv = JRuby::PathHelper.smart_split_command @argv
|
|
273
|
+
process = java.lang.Runtime.runtime.exec split_argv.to_java(:string)
|
|
274
|
+
|
|
275
|
+
stdout, stderr = [process.input_stream, process.error_stream].map do |stream|
|
|
276
|
+
StreamReader.new(stream)
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
exit_code = process.wait_for
|
|
280
|
+
field = process.get_class.get_declared_field("pid")
|
|
281
|
+
field.set_accessible(true)
|
|
282
|
+
pid = field.get(process)
|
|
283
|
+
[
|
|
284
|
+
RubyProcess::RubyStatus.new_process_status(JRuby.runtime, exit_code, pid),
|
|
285
|
+
stdout.join,
|
|
286
|
+
stderr.join
|
|
287
|
+
]
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
class StreamReader
|
|
291
|
+
def initialize(stream)
|
|
292
|
+
@data = ""
|
|
293
|
+
@thread = Thread.new do
|
|
294
|
+
reader = java.io.BufferedReader.new java.io.InputStreamReader.new(stream)
|
|
295
|
+
|
|
296
|
+
while line = reader.read_line
|
|
297
|
+
@data << line << "\n"
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def join
|
|
303
|
+
@thread.join
|
|
304
|
+
@data
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
SystemU = SystemUniversal unless defined? SystemU
|
|
313
|
+
Systemu = SystemUniversal unless defined? Systemu
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
if $0 == __FILE__
|
|
328
|
+
#
|
|
329
|
+
# date
|
|
330
|
+
#
|
|
331
|
+
date = %q( ruby -e" t = Time.now; STDOUT.puts t; STDERR.puts t " )
|
|
332
|
+
|
|
333
|
+
status, stdout, stderr = systemu date
|
|
334
|
+
p [status, stdout, stderr]
|
|
335
|
+
|
|
336
|
+
status = systemu date, 1=>(stdout = '')
|
|
337
|
+
p [status, stdout]
|
|
338
|
+
|
|
339
|
+
status = systemu date, 2=>(stderr = '')
|
|
340
|
+
p [status, stderr]
|
|
341
|
+
#
|
|
342
|
+
# sleep
|
|
343
|
+
#
|
|
344
|
+
sleep = %q( ruby -e" p(sleep(1)) " )
|
|
345
|
+
status, stdout, stderr = systemu sleep
|
|
346
|
+
p [status, stdout, stderr]
|
|
347
|
+
|
|
348
|
+
sleep = %q( ruby -e" p(sleep(42)) " )
|
|
349
|
+
status, stdout, stderr = systemu(sleep){|cid| Process.kill 9, cid}
|
|
350
|
+
p [status, stdout, stderr]
|
|
351
|
+
#
|
|
352
|
+
# env
|
|
353
|
+
#
|
|
354
|
+
env = %q( ruby -e" p ENV['A'] " )
|
|
355
|
+
status, stdout, stderr = systemu env, :env => {'A' => 42}
|
|
356
|
+
p [status, stdout, stderr]
|
|
357
|
+
#
|
|
358
|
+
# cwd
|
|
359
|
+
#
|
|
360
|
+
env = %q( ruby -e" p Dir.pwd " )
|
|
361
|
+
status, stdout, stderr = systemu env, :cwd => Dir.tmpdir
|
|
362
|
+
p [status, stdout, stderr]
|
|
363
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
## systemu.gemspec
|
|
2
|
+
#
|
|
3
|
+
|
|
4
|
+
Gem::Specification::new do |spec|
|
|
5
|
+
spec.name = "systemu"
|
|
6
|
+
spec.version = "2.5.0"
|
|
7
|
+
spec.platform = Gem::Platform::RUBY
|
|
8
|
+
spec.summary = "systemu"
|
|
9
|
+
spec.description = "description: systemu kicks the ass"
|
|
10
|
+
|
|
11
|
+
spec.files =
|
|
12
|
+
["LICENSE",
|
|
13
|
+
"README",
|
|
14
|
+
"README.erb",
|
|
15
|
+
"Rakefile",
|
|
16
|
+
"lib",
|
|
17
|
+
"lib/systemu.rb",
|
|
18
|
+
"samples",
|
|
19
|
+
"samples/a.rb",
|
|
20
|
+
"samples/b.rb",
|
|
21
|
+
"samples/c.rb",
|
|
22
|
+
"samples/d.rb",
|
|
23
|
+
"samples/e.rb",
|
|
24
|
+
"samples/f.rb",
|
|
25
|
+
"systemu.gemspec",
|
|
26
|
+
"test",
|
|
27
|
+
"test/systemu_test.rb",
|
|
28
|
+
"test/testing.rb"]
|
|
29
|
+
|
|
30
|
+
spec.executables = []
|
|
31
|
+
|
|
32
|
+
spec.require_path = "lib"
|
|
33
|
+
|
|
34
|
+
spec.test_files = nil
|
|
35
|
+
|
|
36
|
+
### spec.add_dependency 'lib', '>= version'
|
|
37
|
+
#### spec.add_dependency 'map'
|
|
38
|
+
|
|
39
|
+
spec.extensions.push(*[])
|
|
40
|
+
|
|
41
|
+
spec.rubyforge_project = "codeforpeople"
|
|
42
|
+
spec.author = "Ara T. Howard"
|
|
43
|
+
spec.email = "ara.t.howard@gmail.com"
|
|
44
|
+
spec.homepage = "https://github.com/ahoward/systemu"
|
|
45
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -36,19 +36,6 @@ module EY
|
|
|
36
36
|
old_info(*args)
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
|
-
|
|
40
|
-
def logged_system(cmd)
|
|
41
|
-
output = `#{cmd} 2>&1`
|
|
42
|
-
successful = ($? == 0)
|
|
43
|
-
if ENV['VERBOSE']
|
|
44
|
-
if successful
|
|
45
|
-
$stdout.puts "#{cmd}\n#{output.strip}".chomp
|
|
46
|
-
else
|
|
47
|
-
$stderr.puts "\nCommand `#{cmd}` exited with status #{$?.exitstatus}: '#{output.strip}'"
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
successful
|
|
51
|
-
end
|
|
52
39
|
end
|
|
53
40
|
|
|
54
41
|
class Strategies::Git
|
metadata
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: engineyard-serverside
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.5.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 1.5.35.pre.1
|
|
5
|
+
prerelease: 7
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- EY Cloud Team
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-03-
|
|
12
|
+
date: 2012-03-23 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rspec
|
|
@@ -279,7 +279,9 @@ files:
|
|
|
279
279
|
- lib/vendor/json_pure/tools/fuzz.rb
|
|
280
280
|
- lib/vendor/json_pure/tools/server.rb
|
|
281
281
|
- lib/vendor/json_pure/VERSION
|
|
282
|
-
- lib/vendor/
|
|
282
|
+
- lib/vendor/systemu/lib/systemu.rb
|
|
283
|
+
- lib/vendor/systemu/LICENSE
|
|
284
|
+
- lib/vendor/systemu/systemu.gemspec
|
|
283
285
|
- lib/vendor/thor/bin/rake2thor
|
|
284
286
|
- lib/vendor/thor/bin/thor
|
|
285
287
|
- lib/vendor/thor/CHANGELOG.rdoc
|
|
@@ -321,7 +323,6 @@ files:
|
|
|
321
323
|
- spec/deploy_hook_spec.rb
|
|
322
324
|
- spec/deprecation_spec.rb
|
|
323
325
|
- spec/fixtures/gemfiles/1.0.21-rails-31-with-sqlite
|
|
324
|
-
- spec/fixtures/gitrepo/bar
|
|
325
326
|
- spec/fixtures/gitrepo/foo
|
|
326
327
|
- spec/fixtures/gitrepo.tar.gz
|
|
327
328
|
- spec/fixtures/invalid_hook.rb
|
|
@@ -363,9 +364,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
363
364
|
- - ! '>='
|
|
364
365
|
- !ruby/object:Gem::Version
|
|
365
366
|
version: '0'
|
|
366
|
-
segments:
|
|
367
|
-
- 0
|
|
368
|
-
hash: -3202821505931209678
|
|
369
367
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
370
368
|
none: false
|
|
371
369
|
requirements:
|
|
@@ -385,7 +383,6 @@ test_files:
|
|
|
385
383
|
- spec/deploy_hook_spec.rb
|
|
386
384
|
- spec/deprecation_spec.rb
|
|
387
385
|
- spec/fixtures/gemfiles/1.0.21-rails-31-with-sqlite
|
|
388
|
-
- spec/fixtures/gitrepo/bar
|
|
389
386
|
- spec/fixtures/gitrepo/foo
|
|
390
387
|
- spec/fixtures/gitrepo.tar.gz
|
|
391
388
|
- spec/fixtures/invalid_hook.rb
|
|
@@ -1,403 +0,0 @@
|
|
|
1
|
-
# vim: ts=2:sw=2:sts=2:et:fdm=marker
|
|
2
|
-
require 'fcntl'
|
|
3
|
-
require 'timeout'
|
|
4
|
-
require 'thread'
|
|
5
|
-
|
|
6
|
-
module Open4
|
|
7
|
-
#--{{{
|
|
8
|
-
VERSION = '1.1.0'
|
|
9
|
-
def self.version() VERSION end
|
|
10
|
-
|
|
11
|
-
class Error < ::StandardError; end
|
|
12
|
-
|
|
13
|
-
def popen4(*cmd, &b)
|
|
14
|
-
#--{{{
|
|
15
|
-
pw, pr, pe, ps = IO.pipe, IO.pipe, IO.pipe, IO.pipe
|
|
16
|
-
|
|
17
|
-
verbose = $VERBOSE
|
|
18
|
-
begin
|
|
19
|
-
$VERBOSE = nil
|
|
20
|
-
ps.first.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
|
21
|
-
ps.last.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
|
22
|
-
|
|
23
|
-
cid = fork {
|
|
24
|
-
pw.last.close
|
|
25
|
-
STDIN.reopen pw.first
|
|
26
|
-
pw.first.close
|
|
27
|
-
|
|
28
|
-
pr.first.close
|
|
29
|
-
STDOUT.reopen pr.last
|
|
30
|
-
pr.last.close
|
|
31
|
-
|
|
32
|
-
pe.first.close
|
|
33
|
-
STDERR.reopen pe.last
|
|
34
|
-
pe.last.close
|
|
35
|
-
|
|
36
|
-
STDOUT.sync = STDERR.sync = true
|
|
37
|
-
|
|
38
|
-
begin
|
|
39
|
-
exec(*cmd)
|
|
40
|
-
raise 'forty-two'
|
|
41
|
-
rescue Exception => e
|
|
42
|
-
Marshal.dump(e, ps.last)
|
|
43
|
-
ps.last.flush
|
|
44
|
-
end
|
|
45
|
-
ps.last.close unless (ps.last.closed?)
|
|
46
|
-
exit!
|
|
47
|
-
}
|
|
48
|
-
ensure
|
|
49
|
-
$VERBOSE = verbose
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
[pw.first, pr.last, pe.last, ps.last].each{|fd| fd.close}
|
|
53
|
-
|
|
54
|
-
begin
|
|
55
|
-
e = Marshal.load ps.first
|
|
56
|
-
raise(Exception === e ? e : "unknown failure!")
|
|
57
|
-
rescue EOFError # If we get an EOF error, then the exec was successful
|
|
58
|
-
42
|
|
59
|
-
ensure
|
|
60
|
-
ps.first.close
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
pw.last.sync = true
|
|
64
|
-
|
|
65
|
-
pi = [pw.last, pr.first, pe.first]
|
|
66
|
-
|
|
67
|
-
if b
|
|
68
|
-
begin
|
|
69
|
-
b[cid, *pi]
|
|
70
|
-
Process.waitpid2(cid).last
|
|
71
|
-
ensure
|
|
72
|
-
pi.each{|fd| fd.close unless fd.closed?}
|
|
73
|
-
end
|
|
74
|
-
else
|
|
75
|
-
[cid, pw.last, pr.first, pe.first]
|
|
76
|
-
end
|
|
77
|
-
#--}}}
|
|
78
|
-
end
|
|
79
|
-
alias open4 popen4
|
|
80
|
-
module_function :popen4
|
|
81
|
-
module_function :open4
|
|
82
|
-
|
|
83
|
-
class SpawnError < Error
|
|
84
|
-
#--{{{
|
|
85
|
-
attr 'cmd'
|
|
86
|
-
attr 'status'
|
|
87
|
-
attr 'signals'
|
|
88
|
-
def exitstatus
|
|
89
|
-
@status.exitstatus
|
|
90
|
-
end
|
|
91
|
-
def initialize cmd, status
|
|
92
|
-
@cmd, @status = cmd, status
|
|
93
|
-
@signals = {}
|
|
94
|
-
if status.signaled?
|
|
95
|
-
@signals['termsig'] = status.termsig
|
|
96
|
-
@signals['stopsig'] = status.stopsig
|
|
97
|
-
end
|
|
98
|
-
sigs = @signals.map{|k,v| "#{ k }:#{ v.inspect }"}.join(' ')
|
|
99
|
-
super "cmd <#{ cmd }> failed with status <#{ exitstatus.inspect }> signals <#{ sigs }>"
|
|
100
|
-
end
|
|
101
|
-
#--}}}
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
class ThreadEnsemble
|
|
105
|
-
#--{{{
|
|
106
|
-
attr 'threads'
|
|
107
|
-
|
|
108
|
-
def initialize cid
|
|
109
|
-
@cid, @threads, @argv, @done, @running = cid, [], [], Queue.new, false
|
|
110
|
-
@killed = false
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def add_thread *a, &b
|
|
114
|
-
@running ? raise : (@argv << [a, b])
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
#
|
|
118
|
-
# take down process more nicely
|
|
119
|
-
#
|
|
120
|
-
def killall
|
|
121
|
-
c = Thread.critical
|
|
122
|
-
return nil if @killed
|
|
123
|
-
Thread.critical = true
|
|
124
|
-
(@threads - [Thread.current]).each{|t| t.kill rescue nil}
|
|
125
|
-
@killed = true
|
|
126
|
-
ensure
|
|
127
|
-
Thread.critical = c
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def run
|
|
131
|
-
@running = true
|
|
132
|
-
|
|
133
|
-
begin
|
|
134
|
-
@argv.each do |a, b|
|
|
135
|
-
@threads << Thread.new(*a) do |*a|
|
|
136
|
-
begin
|
|
137
|
-
b[*a]
|
|
138
|
-
ensure
|
|
139
|
-
killall rescue nil if $!
|
|
140
|
-
@done.push Thread.current
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
rescue
|
|
145
|
-
killall
|
|
146
|
-
raise
|
|
147
|
-
ensure
|
|
148
|
-
all_done
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
@threads.map{|t| t.value}
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
def all_done
|
|
155
|
-
@threads.size.times{ @done.pop }
|
|
156
|
-
end
|
|
157
|
-
#--}}}
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
def to timeout = nil
|
|
161
|
-
#--{{{
|
|
162
|
-
Timeout.timeout(timeout){ yield }
|
|
163
|
-
#--}}}
|
|
164
|
-
end
|
|
165
|
-
module_function :to
|
|
166
|
-
|
|
167
|
-
def new_thread *a, &b
|
|
168
|
-
#--{{{
|
|
169
|
-
cur = Thread.current
|
|
170
|
-
Thread.new(*a) do |*a|
|
|
171
|
-
begin
|
|
172
|
-
b[*a]
|
|
173
|
-
rescue Exception => e
|
|
174
|
-
cur.raise e
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
#--}}}
|
|
178
|
-
end
|
|
179
|
-
module_function :new_thread
|
|
180
|
-
|
|
181
|
-
def getopts opts = {}
|
|
182
|
-
#--{{{
|
|
183
|
-
lambda do |*args|
|
|
184
|
-
keys, default, ignored = args
|
|
185
|
-
catch('opt') do
|
|
186
|
-
[keys].flatten.each do |key|
|
|
187
|
-
[key, key.to_s, key.to_s.intern].each do |key|
|
|
188
|
-
throw 'opt', opts[key] if opts.has_key?(key)
|
|
189
|
-
end
|
|
190
|
-
end
|
|
191
|
-
default
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
#--}}}
|
|
195
|
-
end
|
|
196
|
-
module_function :getopts
|
|
197
|
-
|
|
198
|
-
def relay src, dst = nil, t = nil
|
|
199
|
-
#--{{{
|
|
200
|
-
send_dst =
|
|
201
|
-
if dst.respond_to?(:call)
|
|
202
|
-
lambda{|buf| dst.call(buf)}
|
|
203
|
-
elsif dst.respond_to?(:<<)
|
|
204
|
-
lambda{|buf| dst << buf }
|
|
205
|
-
else
|
|
206
|
-
lambda{|buf| buf }
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
unless src.nil?
|
|
210
|
-
if src.respond_to? :gets
|
|
211
|
-
while buf = to(t){ src.gets }
|
|
212
|
-
send_dst[buf]
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
elsif src.respond_to? :each
|
|
216
|
-
q = Queue.new
|
|
217
|
-
th = nil
|
|
218
|
-
|
|
219
|
-
timer_set = lambda do |t|
|
|
220
|
-
th = new_thread{ to(t){ q.pop } }
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
timer_cancel = lambda do |t|
|
|
224
|
-
th.kill if th rescue nil
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
timer_set[t]
|
|
228
|
-
begin
|
|
229
|
-
src.each do |buf|
|
|
230
|
-
timer_cancel[t]
|
|
231
|
-
send_dst[buf]
|
|
232
|
-
timer_set[t]
|
|
233
|
-
end
|
|
234
|
-
ensure
|
|
235
|
-
timer_cancel[t]
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
elsif src.respond_to? :read
|
|
239
|
-
buf = to(t){ src.read }
|
|
240
|
-
send_dst[buf]
|
|
241
|
-
|
|
242
|
-
else
|
|
243
|
-
buf = to(t){ src.to_s }
|
|
244
|
-
send_dst[buf]
|
|
245
|
-
end
|
|
246
|
-
end
|
|
247
|
-
#--}}}
|
|
248
|
-
end
|
|
249
|
-
module_function :relay
|
|
250
|
-
|
|
251
|
-
def spawn arg, *argv
|
|
252
|
-
#--{{{
|
|
253
|
-
argv.unshift(arg)
|
|
254
|
-
opts = ((argv.size > 1 and Hash === argv.last) ? argv.pop : {})
|
|
255
|
-
argv.flatten!
|
|
256
|
-
cmd = argv.join(' ')
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
getopt = getopts opts
|
|
260
|
-
|
|
261
|
-
ignore_exit_failure = getopt[ 'ignore_exit_failure', getopt['quiet', false] ]
|
|
262
|
-
ignore_exec_failure = getopt[ 'ignore_exec_failure', !getopt['raise', true] ]
|
|
263
|
-
exitstatus = getopt[ %w( exitstatus exit_status status ) ]
|
|
264
|
-
stdin = getopt[ %w( stdin in i 0 ) << 0 ]
|
|
265
|
-
stdout = getopt[ %w( stdout out o 1 ) << 1 ]
|
|
266
|
-
stderr = getopt[ %w( stderr err e 2 ) << 2 ]
|
|
267
|
-
pid = getopt[ 'pid' ]
|
|
268
|
-
timeout = getopt[ %w( timeout spawn_timeout ) ]
|
|
269
|
-
stdin_timeout = getopt[ %w( stdin_timeout ) ]
|
|
270
|
-
stdout_timeout = getopt[ %w( stdout_timeout io_timeout ) ]
|
|
271
|
-
stderr_timeout = getopt[ %w( stderr_timeout ) ]
|
|
272
|
-
status = getopt[ %w( status ) ]
|
|
273
|
-
cwd = getopt[ %w( cwd dir ) ]
|
|
274
|
-
|
|
275
|
-
exitstatus =
|
|
276
|
-
case exitstatus
|
|
277
|
-
when TrueClass, FalseClass
|
|
278
|
-
ignore_exit_failure = true if exitstatus
|
|
279
|
-
[0]
|
|
280
|
-
else
|
|
281
|
-
[*(exitstatus || 0)].map{|i| Integer i}
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
stdin ||= '' if stdin_timeout
|
|
285
|
-
stdout ||= '' if stdout_timeout
|
|
286
|
-
stderr ||= '' if stderr_timeout
|
|
287
|
-
|
|
288
|
-
started = false
|
|
289
|
-
|
|
290
|
-
status =
|
|
291
|
-
begin
|
|
292
|
-
chdir(cwd) do
|
|
293
|
-
Timeout::timeout(timeout) do
|
|
294
|
-
popen4(*argv) do |c, i, o, e|
|
|
295
|
-
started = true
|
|
296
|
-
|
|
297
|
-
%w( replace pid= << push update ).each do |msg|
|
|
298
|
-
break(pid.send(msg, c)) if pid.respond_to? msg
|
|
299
|
-
end
|
|
300
|
-
|
|
301
|
-
te = ThreadEnsemble.new c
|
|
302
|
-
|
|
303
|
-
te.add_thread(i, stdin) do |i, stdin|
|
|
304
|
-
relay stdin, i, stdin_timeout
|
|
305
|
-
i.close rescue nil
|
|
306
|
-
end
|
|
307
|
-
|
|
308
|
-
te.add_thread(o, stdout) do |o, stdout|
|
|
309
|
-
relay o, stdout, stdout_timeout
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
te.add_thread(e, stderr) do |o, stderr|
|
|
313
|
-
relay e, stderr, stderr_timeout
|
|
314
|
-
end
|
|
315
|
-
|
|
316
|
-
te.run
|
|
317
|
-
end
|
|
318
|
-
end
|
|
319
|
-
end
|
|
320
|
-
rescue
|
|
321
|
-
raise unless(not started and ignore_exec_failure)
|
|
322
|
-
end
|
|
323
|
-
|
|
324
|
-
raise SpawnError.new(cmd, status) unless
|
|
325
|
-
(ignore_exit_failure or (status.nil? and ignore_exec_failure) or exitstatus.include?(status.exitstatus))
|
|
326
|
-
|
|
327
|
-
status
|
|
328
|
-
#--}}}
|
|
329
|
-
end
|
|
330
|
-
module_function :spawn
|
|
331
|
-
|
|
332
|
-
def chdir cwd, &block
|
|
333
|
-
return(block.call Dir.pwd) unless cwd
|
|
334
|
-
Dir.chdir cwd, &block
|
|
335
|
-
end
|
|
336
|
-
module_function :chdir
|
|
337
|
-
|
|
338
|
-
def background arg, *argv
|
|
339
|
-
#--{{{
|
|
340
|
-
require 'thread'
|
|
341
|
-
q = Queue.new
|
|
342
|
-
opts = { 'pid' => q, :pid => q }
|
|
343
|
-
case argv.last
|
|
344
|
-
when Hash
|
|
345
|
-
argv.last.update opts
|
|
346
|
-
else
|
|
347
|
-
argv.push opts
|
|
348
|
-
end
|
|
349
|
-
thread = Thread.new(arg, argv){|arg, argv| spawn arg, *argv}
|
|
350
|
-
sc = class << thread; self; end
|
|
351
|
-
sc.module_eval {
|
|
352
|
-
define_method(:pid){ @pid ||= q.pop }
|
|
353
|
-
define_method(:spawn_status){ @spawn_status ||= value }
|
|
354
|
-
define_method(:exitstatus){ @exitstatus ||= spawn_status.exitstatus }
|
|
355
|
-
}
|
|
356
|
-
thread
|
|
357
|
-
#--}}}
|
|
358
|
-
end
|
|
359
|
-
alias bg background
|
|
360
|
-
module_function :background
|
|
361
|
-
module_function :bg
|
|
362
|
-
|
|
363
|
-
def maim pid, opts = {}
|
|
364
|
-
#--{{{
|
|
365
|
-
getopt = getopts opts
|
|
366
|
-
sigs = getopt[ 'signals', %w(SIGTERM SIGQUIT SIGKILL) ]
|
|
367
|
-
suspend = getopt[ 'suspend', 4 ]
|
|
368
|
-
pid = Integer pid
|
|
369
|
-
existed = false
|
|
370
|
-
sigs.each do |sig|
|
|
371
|
-
begin
|
|
372
|
-
Process.kill sig, pid
|
|
373
|
-
existed = true
|
|
374
|
-
rescue Errno::ESRCH
|
|
375
|
-
return(existed ? nil : true)
|
|
376
|
-
end
|
|
377
|
-
return true unless alive? pid
|
|
378
|
-
sleep suspend
|
|
379
|
-
return true unless alive? pid
|
|
380
|
-
end
|
|
381
|
-
return(not alive?(pid))
|
|
382
|
-
#--}}}
|
|
383
|
-
end
|
|
384
|
-
module_function :maim
|
|
385
|
-
|
|
386
|
-
def alive pid
|
|
387
|
-
#--{{{
|
|
388
|
-
pid = Integer pid
|
|
389
|
-
begin
|
|
390
|
-
Process.kill 0, pid
|
|
391
|
-
true
|
|
392
|
-
rescue Errno::ESRCH
|
|
393
|
-
false
|
|
394
|
-
end
|
|
395
|
-
#--}}}
|
|
396
|
-
end
|
|
397
|
-
alias alive? alive
|
|
398
|
-
module_function :alive
|
|
399
|
-
module_function :'alive?'
|
|
400
|
-
#--}}}
|
|
401
|
-
end
|
|
402
|
-
|
|
403
|
-
def open4(*cmd, &b) cmd.size == 0 ? Open4 : Open4::popen4(*cmd, &b) end
|
data/spec/fixtures/gitrepo/bar
DELETED
|
File without changes
|