terraspace 0.6.7 → 0.6.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 790cbc55c399a3130eaaaa9e1e3af636a2b182cb28c2ca008e14a48d75883e47
4
- data.tar.gz: 72d05ffb527f163d2b3be47542b77764ddbc599858e6dde6381058e992bc531c
3
+ metadata.gz: ac0b4566fae8a6be4cfb7907e60d1d0ec3cdf4f7426989a68e5a7c22c55b4cc5
4
+ data.tar.gz: 66bd6807da803a3891ba2d78b5e21e5dcf0af2e8a1ed303ceb8c9e70c6916ea7
5
5
  SHA512:
6
- metadata.gz: a598f6c5e693d42c113a5aac0f4d2e63c41821a2414095ed65415fa6b11ab1636ce48d6a98ada24557c6b685642f1ac420fc9850544bd1cbda80e3de91036d48
7
- data.tar.gz: f0a0955bbc1f7846e855141514a69b0aaffc81283081a5a90384fb85e4ec7946a65f19fa1dc3ff5df0e7c9f656ac5563fecca2c8a1a1959c83fa29d9daeae4bd
6
+ metadata.gz: d14b3c79add9cf2075c27682ad466f4afeb474a21943868d3dc1260afd129d127387e0089fa44e08e695bb5c28080b6dcbfdcd6774c3fff244782a50dd8a4f7c
7
+ data.tar.gz: c54ed8c38625bccd2ce424a18b70b4ca9198a4921bf10a57e452e0c6d7b1f2ae500f9565ba123cbaa071d7fec9767fa1d263e8a315dc1427ea5d983c8309c790
data/CHANGELOG.md CHANGED
@@ -3,6 +3,9 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *loosely tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [0.6.8] - 2021-05-07
7
+ - [#110](https://github.com/boltops-tools/terraspace/pull/110) fix popen deadlock with large amounts of output [#97](https://github.com/boltops-tools/terraspace/pull/97) Terraspace hangs when TF_LOG=TRACE environment variable exists #97
8
+
6
9
  ## [0.6.7] - 2021-05-05
7
10
  - [#108](https://github.com/boltops-tools/terraspace/pull/108) provide runner context to terraspace hook
8
11
 
@@ -30,16 +30,16 @@ module Terraspace::Hooks
30
30
  logger.warn "WARN: execute option not set for hook: #{@hook.inspect}"
31
31
  end
32
32
 
33
- if executor
34
- meth = executor.method(:call)
35
- case meth.arity
36
- when 0
37
- executor.call # backwards compatibility
38
- when 1
39
- executor.call(self)
40
- else
41
- raise "The #{executor} call method definition has been more than 1 arguments and is not supported"
42
- end
33
+ return unless executor
34
+
35
+ meth = executor.method(:call)
36
+ case meth.arity
37
+ when 0
38
+ executor.call # backwards compatibility
39
+ when 1
40
+ executor.call(self)
41
+ else
42
+ raise "The #{executor} call method definition has been more than 1 arguments and is not supported"
43
43
  end
44
44
  end
45
45
  end
@@ -29,70 +29,82 @@ module Terraspace
29
29
 
30
30
  def popen3(env)
31
31
  Open3.popen3(env, @command, chdir: @mod.cache_dir) do |stdin, stdout, stderr, wait_thread|
32
- mimic_terraform_input(stdin, stdout)
33
- while out = stdout.gets
34
- terraform_to_stdout(out)
35
- end
36
-
37
- while err = stderr.gets
38
- @error ||= Error.new
39
- @error.lines << err # aggregate all error lines
40
- unless @error.known?
41
- # Sometimes may print a "\e[31m\n" which like during dependencies fetcher init
42
- # suppress it so dont get a bunch of annoying "newlines"
43
- next if err == "\e[31m\n" && @options[:suppress_error_color]
44
- logger.error(err)
45
- end
46
- end
47
-
32
+ handle_streams(stdin, stdout, stderr)
48
33
  status = wait_thread.value.exitstatus
49
34
  exit_status(status)
50
35
  end
51
36
  end
52
37
 
53
- def exit_status(status)
54
- return if status == 0
38
+ BLOCK_SIZE = Integer(ENV['TS_BUFFER_BLOCK_SIZE'] || 102400)
39
+ BUFFER_TIMEOUT = Integer(ENV['TS_BUFFER_TIMEOUT'] || 3600) # 3600s = 1h
40
+ def handle_streams(stdin, stdout, stderr)
41
+ files = [stdout, stderr]
42
+ # note: t=0 and t=nil means no timeout. See: https://bit.ly/2PURlCX
43
+ t = BUFFER_TIMEOUT.to_i unless BUFFER_TIMEOUT.nil?
44
+ Timeout::timeout(t) do
45
+ until all_eof?(files) do
46
+ ready = IO.select(files, nil, nil, 0.1)
47
+ next unless ready
55
48
 
56
- exit_on_fail = @options[:exit_on_fail].nil? ? true : @options[:exit_on_fail]
57
- if @error && @error.known?
58
- raise @error.instance
59
- elsif exit_on_fail
60
- logger.error "Error running command: #{@command}".color(:red)
61
- exit status
49
+ readable = ready[0]
50
+ readable.each do |f|
51
+ buffer = f.read_nonblock(BLOCK_SIZE, exception: false)
52
+ next unless buffer
53
+
54
+ lines = buffer.split("\n")
55
+ lines.each do |line|
56
+ terraform_to_stdout(line)
57
+ handle_input(stdin, line)
58
+ end
59
+ end
60
+ end
62
61
  end
63
62
  end
64
63
 
64
+ def all_eof?(files)
65
+ files.find { |f| !f.eof }.nil?
66
+ end
67
+
65
68
  # Terraform doesnt seem to stream the line that prompts with "Enter a value:" when using Open3.popen3
66
69
  # Hack around it by mimicking the "Enter a value:" prompt
67
70
  #
68
71
  # Note: system does stream the prompt but using Open3.popen3 so we can capture output to save to logs.
69
- def mimic_terraform_input(stdin, stdout)
70
- shown = false
72
+ def handle_input(stdin, line)
73
+ # stdout doesnt seem to flush and show "Enter a value: " look for earlier output
71
74
  patterns = [
72
75
  "Only 'yes' will be accepted", # prompt for apply. can happen on apply
73
76
  "\e[0m\e[1mvar.", # prompts for variable input. can happen on plan or apply. looking for bold marker also in case "var." shows up somewhere else
74
77
  ]
75
- while out = stdout.gets
76
- terraform_to_stdout(out) unless shown && out.include?("Enter a value:")
77
- shown = false if out.include?("Enter a value:") # reset shown in case of multiple input prompts
78
+ if patterns.any? { |pattern| line.include?(pattern) }
79
+ print "\n Enter a value: ".bright
80
+ stdin.write_nonblock($stdin.gets)
81
+ end
82
+ end
78
83
 
79
- # Sometimes stdout doesnt flush and show "Enter a value: ", so mimic it
80
- if patterns.any? { |pattern| out.include?(pattern) }
81
- print " Enter a value: ".bright
82
- shown = true
83
- stdin.write_nonblock($stdin.gets)
84
- end
84
+ def exit_status(status)
85
+ return if status == 0
86
+
87
+ exit_on_fail = @options[:exit_on_fail].nil? ? true : @options[:exit_on_fail]
88
+ if @error && @error.known?
89
+ raise @error.instance
90
+ elsif exit_on_fail
91
+ logger.error "Error running command: #{@command}".color(:red)
92
+ exit status
85
93
  end
86
94
  end
87
95
 
88
- # Allows piping to jq. IE:
89
- # terraspace show demo --json | jq
90
- def terraform_to_stdout(out)
91
- # so terraform output goes stdout
96
+ def terraform_to_stdout(line)
97
+ prompted = line.include?('Enter a value')
98
+ @prompt_shown ||= prompted
99
+ return if @prompt_shown && prompted
100
+
101
+ # Terraspace logger has special stdout method so original terraform output
102
+ # can be piped to jq. IE:
103
+ # terraspace show demo --json | jq
92
104
  if logger.respond_to?(:stdout) && !@options[:log_to_stderr]
93
- logger.stdout(out)
105
+ logger.stdout(line)
94
106
  else
95
- logger.info(out)
107
+ logger.info(line)
96
108
  end
97
109
  end
98
110
  end
@@ -1,3 +1,3 @@
1
1
  module Terraspace
2
- VERSION = "0.6.7"
2
+ VERSION = "0.6.8"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terraspace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.7
4
+ version: 0.6.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-05 00:00:00.000000000 Z
11
+ date: 2021-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport