kumogata 0.3.13 → 0.3.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZDVkOTFjYWZhMzc2OTdhYjlkM2RlYWY3ZDI4MjcyYzNjYmZlN2NhYQ==
4
+ NWY1ZGU1ZTExOTU3MWMyMmYwNGViNGVkNTc0ZGI3OTkxMzI2NTRkNA==
5
5
  data.tar.gz: !binary |-
6
- MmYyNjA2YjZkZTZjNzJkZDljOWQzNjU2NzNkMDgwYjQ3MzBiN2Q5Nw==
6
+ NjE4MjUwNWQ5ZjQ0Njg5YzUzNDYxZDQwOTIzNTdjZmFlZGViM2RjNQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NDBjZDk1YTY2YTZkMDM1YjkzMDE1ZDU3ZDdiOTZlNTFhYWY4NGQ3YmY1OGNk
10
- YmMwZDc5Yzc3MmI0MTExNzU0ZTNhYTQ0MTI2ZTFlZWJhYTg5MzcyZjY2ZjJm
11
- NmZhYjQ2ZWMyMjU3OGUxMTA3MThlNzdmNjk4ODhlYjQ2YmE5NmQ=
9
+ YjE1YzNkYWJmMTcwZTNiMjdmMjZhMWUwNDc2ZDJkOWQzYjgwOTRlMDY3NTM4
10
+ NWQzZTYxM2U5OTY1NjgwMGE3MWI5YjRmYmRmZjI3OGM4MTJlMzdhOTJkZmFm
11
+ OGIzNTc3NTliMjYzMjVlNzYxOWE5Y2Y2YTJlMDZlYjNjMDVjMDc=
12
12
  data.tar.gz: !binary |-
13
- MTRiY2EzMDIyYjBkZDdhNmYyOTgwZTM1ZDg3ZWEzMjc3MGViMmY0NjhlMzE1
14
- NTExMjFmNmI4ZmUzM2M2MWFkZmNlY2MyODI3ODY1MjI0Yzk4Y2JiZDZiMDFm
15
- NWM0MmVkMjljMGNjYTNmNDViNWRhYjIyNDYwNDgzMzAxNDNmNTI=
13
+ Y2ZiMzE5MmM3ZDU0MGJlZjJjNGVlYjRhOWI3MGNlZmU2YTFlOTc3NTU5YzM2
14
+ N2JiMzk1ZTJmNzllNDM5NzMyOWIzZmQ3NWU2NWQ1Mzk3NDMzMWY3YTQxZjMz
15
+ ZGJiNDNmNDE1OWMyNDU2MDU1Yzg5Y2Q4NDUxMTYxZjM4MGNhYzY=
data/README.md CHANGED
@@ -5,8 +5,8 @@
5
5
 
6
6
  Kumogata is a tool for [AWS CloudFormation](https://aws.amazon.com/cloudformation/).
7
7
 
8
- [![Gem Version](https://badge.fury.io/rb/kumogata.png?201403111456)](http://badge.fury.io/rb/kumogata)
9
- [![Build Status](https://drone.io/github.com/winebarrel/kumogata/status.png?201403111456)](https://drone.io/github.com/winebarrel/kumogata/latest)
8
+ [![Gem Version](https://badge.fury.io/rb/kumogata.png?201403121243)](http://badge.fury.io/rb/kumogata)
9
+ [![Build Status](https://drone.io/github.com/winebarrel/kumogata/status.png?201403121243)](https://drone.io/github.com/winebarrel/kumogata/latest)
10
10
 
11
11
  It can define a template in Ruby DSL, such as:
12
12
 
data/lib/kumogata.rb CHANGED
@@ -19,6 +19,7 @@ require 'set'
19
19
  require 'singleton'
20
20
  require 'strscan'
21
21
  require 'term/ansicolor'
22
+ require 'thread'
22
23
  require 'uuidtools'
23
24
 
24
25
  require 'kumogata/argument_parser'
@@ -29,4 +30,5 @@ require 'kumogata/ext/json_ext'
29
30
  require 'kumogata/ext/string_ext'
30
31
  require 'kumogata/logger'
31
32
  require 'kumogata/post_processing'
33
+ require 'kumogata/string_stream'
32
34
  require 'kumogata/utils'
@@ -135,13 +135,22 @@ class Kumogata::PostProcessing
135
135
  connect_tries = (ssh['connect_tries'] || 36).to_i
136
136
  retry_interval = (ssh['retry_interval'] || 5).to_i
137
137
 
138
+ stderr_orig = nil
139
+
138
140
  begin
139
- retryable(:tries => connect_tries, :on => Net::SSH::Disconnect, :sleep => retry_interval) do
140
- Net::SSH.start(*args) {|ssh| ssh_exec!(ssh, command) }
141
+ stderr_orig = STDERR.dup
142
+ STDERR.reopen('/dev/null', 'w')
143
+
144
+ begin
145
+ retryable(:tries => connect_tries, :on => Net::SSH::Disconnect, :sleep => retry_interval) do
146
+ Net::SSH.start(*args) {|ssh| ssh_exec!(ssh, command) }
147
+ end
148
+ rescue Net::SSH::HostKeyMismatch => e
149
+ e.remember_host!
150
+ retry
141
151
  end
142
- rescue Net::SSH::HostKeyMismatch => e
143
- e.remember_host!
144
- retry
152
+ ensure
153
+ STDERR.reopen(stderr_orig)
145
154
  end
146
155
  end
147
156
 
@@ -151,6 +160,9 @@ class Kumogata::PostProcessing
151
160
  exit_code = nil
152
161
  #exit_signal = nil
153
162
 
163
+ stdout_stream = create_stdout_stream
164
+ stderr_stream = create_stderr_stream
165
+
154
166
  ssh.open_channel do |channel|
155
167
  channel.exec(command) do |ch, success|
156
168
  unless success
@@ -158,10 +170,12 @@ class Kumogata::PostProcessing
158
170
  end
159
171
 
160
172
  channel.on_data do |ch, data|
173
+ stdout_stream.push data
161
174
  stdout_data << data
162
175
  end
163
176
 
164
177
  channel.on_extended_data do |ch, type, data|
178
+ stderr_stream.push data
165
179
  stderr_data << data
166
180
  end
167
181
 
@@ -177,13 +191,57 @@ class Kumogata::PostProcessing
177
191
 
178
192
  ssh.loop
179
193
 
194
+ stdout_stream.close
195
+ stderr_stream.close
196
+
180
197
  #[stdout_data, stderr_data, exit_code, exit_signal]
181
198
  [stdout_data, stderr_data, exit_code]
182
199
  end
183
200
 
184
201
  def run_shell_command(command, outputs)
185
202
  command = evaluate_command_template(command, outputs)
186
- Open3.capture3(command)
203
+
204
+ stdout_data = ''
205
+ stderr_data = ''
206
+ exit_code = nil
207
+
208
+ Open3.popen3(command) do |stdin, stdout, stderr, wait_thr|
209
+ mutex = Mutex.new
210
+
211
+ th_out = Thread.start do
212
+ stdout_stream = create_stdout_stream
213
+
214
+ stdout.each_line do |line|
215
+ mutex.synchronize do
216
+ stdout_stream.push line
217
+ end
218
+
219
+ stdout_data << line
220
+ end
221
+
222
+ stdout_stream.close
223
+ end
224
+
225
+ th_err = Thread.start do
226
+ stderr_stream = create_stderr_stream
227
+
228
+ stderr.each_line do |line|
229
+ mutex.synchronize do
230
+ stderr_stream.push line
231
+ end
232
+ stderr_data << line
233
+ end
234
+
235
+ stderr_stream.close
236
+ end
237
+
238
+ th_out.join
239
+ th_err.join
240
+ exit_code = wait_thr.value
241
+ end
242
+
243
+ #[stdout_data, stderr_data, exit_code, exit_signal]
244
+ [stdout_data, stderr_data, exit_code]
187
245
  end
188
246
 
189
247
  def validate_command_template(name, command, outputs)
@@ -232,17 +290,25 @@ Command: #{name.intense_blue}
232
290
  EOS
233
291
  end
234
292
 
235
- def print_command_result(out, err, status)
293
+ def create_stdout_stream
294
+ Kumogata::StringStream.new do |line|
295
+ puts '1> '.intense_green + line
296
+ $stdout.flush
297
+ end
298
+ end
299
+
300
+ def create_stderr_stream
301
+ Kumogata::StringStream.new do |line|
302
+ puts '2> '.intense_red + line
303
+ $stdout.flush
304
+ end
305
+ end
306
+
307
+ def print_command_result(out, err, status) # XXX:
236
308
  status = status.to_i
237
- dspout = (out || '').lines.map {|i| "1> ".intense_green + i }.join.chomp
238
- dsperr = (err || '').lines.map {|i| "2> ".intense_red + i }.join.chomp
239
309
 
240
310
  puts <<-EOS
241
- Status: #{status.zero? ? status : status.to_s.red}#{
242
- dspout.empty? ? '' : ("\n---\n" + dspout)
243
- }#{
244
- dsperr.empty? ? '' : ("\n---\n" + dsperr)
245
- }
311
+ Status: #{status.zero? ? status : status.to_s.red}
246
312
  EOS
247
313
  end
248
314
 
@@ -0,0 +1,39 @@
1
+ class Kumogata::StringStream
2
+ def initialize(&block)
3
+ @buf = StringScanner.new('')
4
+ @block = block
5
+
6
+ @fiber = Fiber.new do
7
+ self.run
8
+ end
9
+
10
+ # Step to `yield`
11
+ @fiber.resume
12
+ end
13
+
14
+ def run
15
+ loop do
16
+ chunk = Fiber.yield
17
+ break unless chunk
18
+
19
+ @buf << chunk.to_s
20
+ self.each_line
21
+ end
22
+ end
23
+
24
+ def each_line
25
+ while (line = @buf.scan_until(/(\r\n|\r|\n)/))
26
+ @block.call(line.chomp)
27
+ end
28
+ end
29
+
30
+ def push(chunk)
31
+ @fiber.resume(chunk)
32
+ end
33
+
34
+ def close
35
+ self.each_line
36
+ @block.call(@buf.rest) if @buf.rest?
37
+ @fiber.resume
38
+ end
39
+ end
@@ -1,3 +1,3 @@
1
1
  module Kumogata
2
- VERSION = '0.3.13'
2
+ VERSION = '0.3.14'
3
3
  end
@@ -146,9 +146,13 @@ end
146
146
  process_status1 = make_double('process_status1') {|obj| obj.should_receive(:to_i).and_return(0) }
147
147
  process_status2 = make_double('process_status2') {|obj| obj.should_receive(:to_i).and_return(0) }
148
148
 
149
- Open3.should_receive(:capture3).with("echo ap-northeast-1b\necho ap-northeast-1\n")
149
+ client.instance_variable_get(:@post_processing)
150
+ .should_receive(:run_shell_command)
151
+ .with(" echo <%= Key \"AZ\" %>\n echo <%= Key \"Region\" %>\n", {"AZ"=>"ap-northeast-1b", "Region"=>"ap-northeast-1"})
150
152
  .and_return(["ap-northeast-1b\nap-northeast-1\n", "", process_status1])
151
- Open3.should_receive(:capture3).with("echo ap-northeast-1\necho ap-northeast-1b\n")
153
+ client.instance_variable_get(:@post_processing)
154
+ .should_receive(:run_shell_command)
155
+ .with(" echo <%= Key \"Region\" %>\n echo <%= Key \"AZ\" %>\n", {"AZ"=>"ap-northeast-1b", "Region"=>"ap-northeast-1"})
152
156
  .and_return(["ap-northeast-1\nap-northeast-1b\n", "", process_status2])
153
157
 
154
158
  client.instance_variable_get(:@post_processing)
@@ -240,7 +244,9 @@ end
240
244
 
241
245
  cf.should_receive(:stacks).twice { stacks }
242
246
 
243
- Net::SSH.should_receive(:start).with("127.0.0.1", "ec2-user")
247
+ client.instance_variable_get(:@post_processing)
248
+ .should_receive(:run_ssh_command)
249
+ .with({"host"=>"<%= Key \"PublicIp\" %>", "user"=>"ec2-user"}, " ls\n", {"PublicIp"=>"127.0.0.1"})
244
250
  .and_return(["file1\nfile2\n", "", 0])
245
251
 
246
252
  client.instance_variable_get(:@post_processing)
@@ -345,9 +351,13 @@ end
345
351
  process_status1 = make_double('process_status1') {|obj| obj.should_receive(:to_i).and_return(0) }
346
352
  process_status2 = make_double('process_status2') {|obj| obj.should_receive(:to_i).and_return(0) }
347
353
 
348
- Open3.should_receive(:capture3).with("echo ap-northeast-1b\necho ap-northeast-1\n")
354
+ client.instance_variable_get(:@post_processing)
355
+ .should_receive(:run_shell_command)
356
+ .with(" echo <%= Key \"AZ\" %>\n echo <%= Key \"Region\" %>\n", {"AZ"=>"ap-northeast-1b", "Region"=>"ap-northeast-1"})
349
357
  .and_return(["ap-northeast-1b\nap-northeast-1\n", "", process_status1])
350
- Open3.should_receive(:capture3).with("echo ap-northeast-1\necho ap-northeast-1b\n")
358
+ client.instance_variable_get(:@post_processing)
359
+ .should_receive(:run_shell_command)
360
+ .with(" echo <%= Key \"Region\" %>\n echo <%= Key \"AZ\" %>\n", {"AZ"=>"ap-northeast-1b", "Region"=>"ap-northeast-1"})
351
361
  .and_return(["ap-northeast-1\nap-northeast-1b\n", "", process_status2])
352
362
 
353
363
  client.instance_variable_get(:@post_processing)
@@ -141,9 +141,13 @@ end
141
141
  process_status1 = make_double('process_status1') {|obj| obj.should_receive(:to_i).and_return(0) }
142
142
  process_status2 = make_double('process_status2') {|obj| obj.should_receive(:to_i).and_return(0) }
143
143
 
144
- Open3.should_receive(:capture3).with("echo ap-northeast-1b\necho ap-northeast-1\n")
144
+ client.instance_variable_get(:@post_processing)
145
+ .should_receive(:run_shell_command)
146
+ .with(" echo <%= Key \"AZ\" %>\n echo <%= Key \"Region\" %>\n", {"AZ"=>"ap-northeast-1b", "Region"=>"ap-northeast-1"})
145
147
  .and_return(["ap-northeast-1b\nap-northeast-1\n", "", process_status1])
146
- Open3.should_receive(:capture3).with("echo ap-northeast-1\necho ap-northeast-1b\n")
148
+ client.instance_variable_get(:@post_processing)
149
+ .should_receive(:run_shell_command)
150
+ .with(" echo <%= Key \"Region\" %>\n echo <%= Key \"AZ\" %>\n", {"AZ"=>"ap-northeast-1b", "Region"=>"ap-northeast-1"})
147
151
  .and_return(["ap-northeast-1\nap-northeast-1b\n", "", process_status2])
148
152
 
149
153
  client.instance_variable_get(:@post_processing)
@@ -232,7 +236,9 @@ end
232
236
 
233
237
  cf.should_receive(:stacks) { stacks }
234
238
 
235
- Net::SSH.should_receive(:start).with("127.0.0.1", "ec2-user")
239
+ client.instance_variable_get(:@post_processing)
240
+ .should_receive(:run_ssh_command)
241
+ .with({"host"=>"<%= Key \"PublicIp\" %>", "user"=>"ec2-user"}, " ls\n", {"PublicIp"=>"127.0.0.1"})
236
242
  .and_return(["file1\nfile2\n", "", 0])
237
243
 
238
244
  client.instance_variable_get(:@post_processing)
@@ -336,9 +342,13 @@ end
336
342
  process_status1 = make_double('process_status1') {|obj| obj.should_receive(:to_i).and_return(0) }
337
343
  process_status2 = make_double('process_status2') {|obj| obj.should_receive(:to_i).and_return(0) }
338
344
 
339
- Open3.should_receive(:capture3).with("echo ap-northeast-1b\necho ap-northeast-1\n")
345
+ client.instance_variable_get(:@post_processing)
346
+ .should_receive(:run_shell_command)
347
+ .with(" echo <%= Key \"AZ\" %>\n echo <%= Key \"Region\" %>\n", {"AZ"=>"ap-northeast-1b", "Region"=>"ap-northeast-1"})
340
348
  .and_return(["ap-northeast-1b\nap-northeast-1\n", "", process_status1])
341
- Open3.should_receive(:capture3).with("echo ap-northeast-1\necho ap-northeast-1b\n")
349
+ client.instance_variable_get(:@post_processing)
350
+ .should_receive(:run_shell_command)
351
+ .with(" echo <%= Key \"Region\" %>\n echo <%= Key \"AZ\" %>\n", {"AZ"=>"ap-northeast-1b", "Region"=>"ap-northeast-1"})
342
352
  .and_return(["ap-northeast-1\nap-northeast-1b\n", "", process_status2])
343
353
 
344
354
  client.instance_variable_get(:@post_processing)
@@ -0,0 +1,123 @@
1
+ describe Kumogata::StringStream do
2
+ it 'pass the line ("\n")' do
3
+ lines = []
4
+
5
+ sstream = Kumogata::StringStream.new do |line|
6
+ lines << line
7
+ end
8
+
9
+ sstream.push("chunk1")
10
+ sstream.push("chunk2\n")
11
+ sstream.push("chunk3")
12
+ sstream.push("chunk4")
13
+ sstream.push("chunk5\n")
14
+ sstream.push("\n")
15
+ sstream.push("\n")
16
+ sstream.push("chunk6")
17
+ sstream.push("chunk7")
18
+ sstream.close
19
+
20
+ expect(lines).to eq([
21
+ "chunk1chunk2",
22
+ "chunk3chunk4chunk5",
23
+ "",
24
+ "",
25
+ "chunk6chunk7",
26
+ ])
27
+ end
28
+
29
+ it 'pass the line ("\r")' do
30
+ lines = []
31
+
32
+ sstream = Kumogata::StringStream.new do |line|
33
+ lines << line
34
+ end
35
+
36
+ sstream.push("chunk1")
37
+ sstream.push("chunk2\r")
38
+ sstream.push("chunk3")
39
+ sstream.push("chunk4")
40
+ sstream.push("chunk5\r")
41
+ sstream.push("\r")
42
+ sstream.push("\r")
43
+ sstream.push("chunk6")
44
+ sstream.push("chunk7")
45
+ sstream.close
46
+
47
+ expect(lines).to eq([
48
+ "chunk1chunk2",
49
+ "chunk3chunk4chunk5",
50
+ "",
51
+ "",
52
+ "chunk6chunk7",
53
+ ])
54
+ end
55
+
56
+ it 'pass the line ("\r\n")' do
57
+ lines = []
58
+
59
+ sstream = Kumogata::StringStream.new do |line|
60
+ lines << line
61
+ end
62
+
63
+ sstream.push("chunk1")
64
+ sstream.push("chunk2\r\n")
65
+ sstream.push("chunk3")
66
+ sstream.push("chunk4")
67
+ sstream.push("chunk5\r\n")
68
+ sstream.push("\r\n")
69
+ sstream.push("\r\n")
70
+ sstream.push("chunk6")
71
+ sstream.push("chunk7")
72
+ sstream.close
73
+
74
+ expect(lines).to eq([
75
+ "chunk1chunk2",
76
+ "chunk3chunk4chunk5",
77
+ "",
78
+ "",
79
+ "chunk6chunk7",
80
+ ])
81
+ end
82
+
83
+ it 'pass the line ("\n" / "\r" / "\r\n")' do
84
+ lines = []
85
+
86
+ sstream = Kumogata::StringStream.new do |line|
87
+ lines << line
88
+ end
89
+
90
+ sstream.push("chunk1")
91
+ sstream.push("chunk2\n")
92
+ sstream.push("chunk3")
93
+ sstream.push("chunk4")
94
+ sstream.push("chunk5\r")
95
+ sstream.push("\r\n")
96
+ sstream.push("\n")
97
+ sstream.push("chunk6")
98
+ sstream.push("chunk7")
99
+ sstream.push("chunk1")
100
+ sstream.push("chunk2\r")
101
+ sstream.push("chunk3")
102
+ sstream.push("chunk4")
103
+ sstream.push("chunk5\n\r")
104
+ sstream.push("\n")
105
+ sstream.push("\r")
106
+ sstream.push("chunk6")
107
+ sstream.push("chunk7")
108
+ sstream.close
109
+
110
+ expect(lines).to eq([
111
+ "chunk1chunk2",
112
+ "chunk3chunk4chunk5",
113
+ "",
114
+ "",
115
+ "chunk6chunk7chunk1chunk2",
116
+ "chunk3chunk4chunk5",
117
+ "",
118
+ "",
119
+ "",
120
+ "chunk6chunk7",
121
+ ])
122
+ end
123
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kumogata
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.13
4
+ version: 0.3.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Genki Sugawara
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-11 00:00:00.000000000 Z
11
+ date: 2014-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -231,6 +231,7 @@ files:
231
231
  - lib/kumogata/ext/string_ext.rb
232
232
  - lib/kumogata/logger.rb
233
233
  - lib/kumogata/post_processing.rb
234
+ - lib/kumogata/string_stream.rb
234
235
  - lib/kumogata/utils.rb
235
236
  - lib/kumogata/version.rb
236
237
  - packer/CentOS-6.4-x86_64-with_Updates-Asia_Pacific.json
@@ -250,6 +251,7 @@ files:
250
251
  - spec/kumogata_update_spec.rb
251
252
  - spec/kumogata_validate_spec.rb
252
253
  - spec/spec_helper.rb
254
+ - spec/string_stream_spec.rb
253
255
  homepage: https://github.com/winebarrel/kumogata
254
256
  licenses:
255
257
  - MIT
@@ -290,3 +292,4 @@ test_files:
290
292
  - spec/kumogata_update_spec.rb
291
293
  - spec/kumogata_validate_spec.rb
292
294
  - spec/spec_helper.rb
295
+ - spec/string_stream_spec.rb