cem_acpt 0.10.7 → 0.10.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 +4 -4
- data/.github/workflows/spec.yml +1 -1
- data/Gemfile.lock +1 -1
- data/lib/cem_acpt/utils/shell.rb +168 -31
- data/lib/cem_acpt/version.rb +1 -1
- data/lib/terraform/gcp/linux/main.tf +3 -3
- data/lib/terraform/gcp/windows/main.tf +3 -3
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 93cbd3354b97e498b8eba13d18b40a0294147c2e5d499ee3ce3a8c3cd809637d
|
|
4
|
+
data.tar.gz: d5879ac35af8d5fa25f4207b9efea2bc51fda8718a65a49aa38a87e7cb74e766
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c02e967c85cc1b00840e2263f292af3a911d4675be2509228ad822d5014d586c7282cc81c6ea071d078970b7a7dcbdcf29755ea3c4befe56a1cb7209740d6fef
|
|
7
|
+
data.tar.gz: a0d1beae7b3ebe208a5310beccf5c8ba176f82a3840affad465cc7cf9ac47d76a1ae8b0eb8fc9f7d806302333bba3cd03b43b14ab9818212cefe57bc61330e92
|
data/.github/workflows/spec.yml
CHANGED
data/Gemfile.lock
CHANGED
data/lib/cem_acpt/utils/shell.rb
CHANGED
|
@@ -11,49 +11,186 @@ module CemAcpt
|
|
|
11
11
|
module Utils
|
|
12
12
|
# Generic utilities for running local shell commands
|
|
13
13
|
module Shell
|
|
14
|
-
#
|
|
15
|
-
#
|
|
14
|
+
# Class to represent a single piece of output data, along with the stream it came from (stdout or stderr).
|
|
15
|
+
# This class is used to buffer output data from shell commands before writing it to the output stream, allowing
|
|
16
|
+
# for real-time logging and processing of the output.
|
|
17
|
+
class OutputData
|
|
18
|
+
attr_reader :data, :stream
|
|
19
|
+
|
|
20
|
+
# Initializes a new OutputData instance.
|
|
21
|
+
# @param data [String] The output data captured from the shell command
|
|
22
|
+
# @param stream [Symbol] The stream the data came from, either :stdout or :stderr. Defaults to :stdout.
|
|
23
|
+
def initialize(data, stream = :stdout)
|
|
24
|
+
@data = data
|
|
25
|
+
@stream = stream
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @return [String] The string representation of the output data, which is just the data itself.
|
|
29
|
+
def to_s
|
|
30
|
+
data
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Class to handle output from shell commands, allowing for real-time logging and buffering of output data.
|
|
35
|
+
# The Output class captures both stdout and stderr, and can be configured to combine them or keep them separate.
|
|
36
|
+
# It also supports logging debug messages if the provided output object supports it.
|
|
37
|
+
class Output
|
|
38
|
+
attr_writer :log_title
|
|
39
|
+
|
|
40
|
+
# Initializes a new Output instance.
|
|
41
|
+
# @param output [IO] An IO object that implements `:<<` to write the output of the command to in real time.
|
|
42
|
+
# Typically this is a Logger object. Defaults to $stdout.
|
|
43
|
+
# If the object responds to `:debug`, the command will be logged at the debug level.
|
|
44
|
+
# @param raise_on_fail [Boolean] Whether to raise an error if writing to the output fails. Defaults to true.
|
|
45
|
+
# @param combine_out_err [Boolean] Whether to combine the output and error streams into the output. If false,
|
|
46
|
+
# the stderr stream will not be written to the output stream or returned with the output string.
|
|
47
|
+
# Defaults to true.
|
|
48
|
+
def initialize(output: $stdout, raise_on_fail: true, combine_out_err: true)
|
|
49
|
+
@output = output
|
|
50
|
+
validate_output_object!
|
|
51
|
+
@buffer = []
|
|
52
|
+
@closed = false
|
|
53
|
+
@raise_on_fail = raise_on_fail
|
|
54
|
+
@combine_out_err = combine_out_err
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# @return [StringIO] The StringIO object capturing stdout
|
|
58
|
+
def stdout
|
|
59
|
+
@io_out ||= StringIO.new
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# @return [StringIO] The StringIO object capturing stderr
|
|
63
|
+
def stderr
|
|
64
|
+
@io_err ||= StringIO.new
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# @return [String] The log title used for logging, defaults to "Output"
|
|
68
|
+
def log_title
|
|
69
|
+
@log_title ||= "Output"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# @return [Boolean] Whether the output is closed
|
|
73
|
+
def closed?
|
|
74
|
+
@closed
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Logs a debug message to the output if it supports :debug, otherwise writes it to the output stream.
|
|
78
|
+
# @param msg [String] The message to log as debug
|
|
79
|
+
def debug(msg)
|
|
80
|
+
write("DEBUG: #{msg}\n", :stderr)
|
|
81
|
+
if @output.respond_to? :debug
|
|
82
|
+
@output.debug(log_title) { msg }
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Writes data to the output stream and captures it in the buffer. Handles both stdout and stderr based on the stream parameter.
|
|
87
|
+
# @param data [String] The data to write to the output
|
|
88
|
+
# @param stream [Symbol] The stream to write to, either :stdout or :stderr. Defaults to :stdout.
|
|
89
|
+
def write(data, stream = :stdout)
|
|
90
|
+
raise IOError, "Cannot write to closed output" if closed?
|
|
91
|
+
begin
|
|
92
|
+
validate_stream!(stream)
|
|
93
|
+
newlines = data.count("\n")
|
|
94
|
+
if newlines == 1 && data.end_with?("\n")
|
|
95
|
+
data_obj = OutputData.new(data, stream)
|
|
96
|
+
@buffer << data_obj
|
|
97
|
+
flush
|
|
98
|
+
elsif newlines > 0
|
|
99
|
+
data.split("\n").each do |part|
|
|
100
|
+
data_obj = OutputData.new("#{part}\n", stream)
|
|
101
|
+
@buffer << data_obj
|
|
102
|
+
flush
|
|
103
|
+
end
|
|
104
|
+
else
|
|
105
|
+
@buffer << OutputData.new(data, stream)
|
|
106
|
+
end
|
|
107
|
+
rescue StandardError => e
|
|
108
|
+
raise e if @raise_on_fail
|
|
109
|
+
|
|
110
|
+
# If there's an error writing to the output, we still want to capture the output in the buffer and not lose it.
|
|
111
|
+
msg = "Error writing to output: #{e.message}. Captured output: #{data}"
|
|
112
|
+
@buffer << OutputData.new(msg, :stderr)
|
|
113
|
+
flush
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
alias << write
|
|
117
|
+
|
|
118
|
+
# Flushes the buffer to the output stream in order. If combine_out_err is true, stderr data will be written to the same stream as stdout.
|
|
119
|
+
def flush
|
|
120
|
+
return if @buffer.empty?
|
|
121
|
+
|
|
122
|
+
@buffer.each do |data_obj|
|
|
123
|
+
data = data_obj.to_s
|
|
124
|
+
stream = @combine_out_err ? :stdout : data_obj.stream
|
|
125
|
+
@output << data if @output
|
|
126
|
+
send(stream).write(data)
|
|
127
|
+
end
|
|
128
|
+
@buffer.clear
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Closes the output, flushing any remaining buffered data. If raise_on_fail is true, any errors during flushing will be raised.
|
|
132
|
+
def close
|
|
133
|
+
flush unless @buffer.empty?
|
|
134
|
+
@closed = true
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
private
|
|
138
|
+
|
|
139
|
+
def validate_output_object!
|
|
140
|
+
raise ArgumentError, "Output object must support :<< method" unless @output.respond_to?(:<<)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def validate_stream!(stream)
|
|
144
|
+
raise ArgumentError, "Stream must be :stdout or :stderr" unless [:stdout, :stderr].include?(stream)
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Runs a command in a subshell and returns the the string output of the command.
|
|
16
149
|
# @param cmd [String] The command to run
|
|
17
150
|
# @param env [Hash] A hash of environment variables to set
|
|
18
|
-
# @param output [IO] An IO object that implements
|
|
151
|
+
# @param output [IO] An IO object that implements `:<<` to write the output of the
|
|
19
152
|
# command to in real time. Typically this is a Logger object. Defaults to $stdout.
|
|
20
|
-
# If the object responds to
|
|
153
|
+
# If the object responds to `:debug`, the command will be logged at the debug level.
|
|
21
154
|
# @param raise_on_fail [Boolean] Whether to raise an error if the command fails
|
|
22
155
|
# @param combine_out_err [Boolean] Whether to combine the output and error streams into the output.
|
|
23
156
|
# If false, the stderr stream will not be written to the output stream or returned with
|
|
24
157
|
# the output string.
|
|
25
|
-
# @return [String] The string output of the command
|
|
158
|
+
# @return [String] The string output of the command
|
|
26
159
|
def self.run_cmd(cmd, env = {}, output: $stdout, raise_on_fail: true, combine_out_err: true)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
160
|
+
env.transform_keys!(&:to_s)
|
|
161
|
+
output = Output.new(output: output, raise_on_fail: raise_on_fail, combine_out_err: combine_out_err)
|
|
162
|
+
output.log_title = 'CemAcpt::Utils::Shell'
|
|
163
|
+
output.debug("Running command:\n\t#{cmd}\nWith environment:\n\t#{env}")
|
|
164
|
+
begin
|
|
165
|
+
val = Open3.popen3(env, cmd) do |i, o, e, t|
|
|
166
|
+
i.close
|
|
167
|
+
o.sync = true
|
|
168
|
+
e.sync = true
|
|
169
|
+
files = [o, e]
|
|
170
|
+
until files.all?(&:eof?)
|
|
171
|
+
ready = IO.select(files)
|
|
172
|
+
if ready
|
|
173
|
+
ready[0].each do |f|
|
|
174
|
+
data = f.read_nonblock(4096)
|
|
175
|
+
if f == o
|
|
176
|
+
output.write(data, :stdout)
|
|
177
|
+
elsif f == e
|
|
178
|
+
output.write(data, :stderr)
|
|
179
|
+
end
|
|
180
|
+
rescue IO::WaitReadable, EOFError
|
|
181
|
+
next
|
|
182
|
+
end
|
|
46
183
|
end
|
|
47
184
|
end
|
|
185
|
+
t.value
|
|
48
186
|
end
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
t.value
|
|
187
|
+
ensure
|
|
188
|
+
output.close unless output.closed?
|
|
52
189
|
end
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
190
|
+
if raise_on_fail && !val.success?
|
|
191
|
+
raise CemAcpt::ShellCommandError, "Error running command: #{cmd}\n#{output.stdout.string}\n#{output.stderr.string}"
|
|
192
|
+
end
|
|
193
|
+
output.stdout.string
|
|
57
194
|
end
|
|
58
195
|
|
|
59
196
|
# Mimics the behavior of the `which` command.
|
data/lib/cem_acpt/version.rb
CHANGED
|
@@ -81,9 +81,9 @@ resource "google_compute_instance" "acpt-test-node" {
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
scheduling {
|
|
84
|
-
preemptible =
|
|
85
|
-
automatic_restart =
|
|
86
|
-
provisioning_model = "
|
|
84
|
+
preemptible = false
|
|
85
|
+
automatic_restart = true
|
|
86
|
+
provisioning_model = "STANDARD"
|
|
87
87
|
instance_termination_action = "DELETE"
|
|
88
88
|
max_run_duration {
|
|
89
89
|
seconds = each.value.max_run_duration
|
|
@@ -80,9 +80,9 @@ resource "google_compute_instance" "acpt-test-node" {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
scheduling {
|
|
83
|
-
preemptible =
|
|
84
|
-
automatic_restart =
|
|
85
|
-
provisioning_model = "
|
|
83
|
+
preemptible = false
|
|
84
|
+
automatic_restart = true
|
|
85
|
+
provisioning_model = "STANDARD"
|
|
86
86
|
instance_termination_action = "DELETE"
|
|
87
87
|
max_run_duration {
|
|
88
88
|
seconds = each.value.max_run_duration
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cem_acpt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.10.
|
|
4
|
+
version: 0.10.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- puppetlabs
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-02-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: async-http
|
|
@@ -314,7 +314,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
314
314
|
- !ruby/object:Gem::Version
|
|
315
315
|
version: '0'
|
|
316
316
|
requirements: []
|
|
317
|
-
rubygems_version: 3.5.
|
|
317
|
+
rubygems_version: 3.5.18
|
|
318
318
|
signing_key:
|
|
319
319
|
specification_version: 4
|
|
320
320
|
summary: CEM Acceptance Tests
|