cem_acpt 0.7.2 → 0.8.0
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/.rubocop.yml +3 -1
- data/Gemfile.lock +42 -14
- data/README.md +8 -0
- data/cem_acpt.gemspec +3 -1
- data/exe/cem_acpt_image +0 -0
- data/lib/cem_acpt/action_result.rb +85 -0
- data/lib/cem_acpt/cli.rb +46 -22
- data/lib/cem_acpt/config/base.rb +27 -4
- data/lib/cem_acpt/config/cem_acpt.rb +0 -17
- data/lib/cem_acpt/config/cem_acpt_image.rb +2 -17
- data/lib/cem_acpt/goss/api.rb +8 -2
- data/lib/cem_acpt/image_builder.rb +82 -64
- data/lib/cem_acpt/logging.rb +41 -30
- data/lib/cem_acpt/platform.rb +4 -5
- data/lib/cem_acpt/provision/terraform/linux.rb +17 -1
- data/lib/cem_acpt/provision/terraform/terraform_cmd.rb +181 -0
- data/lib/cem_acpt/provision/terraform/windows.rb +9 -0
- data/lib/cem_acpt/provision/terraform.rb +34 -47
- data/lib/cem_acpt/provision.rb +1 -1
- data/lib/cem_acpt/puppet_helpers.rb +1 -1
- data/lib/cem_acpt/test_data.rb +3 -3
- data/lib/cem_acpt/test_runner/log_formatter/error_formatter.rb +33 -0
- data/lib/cem_acpt/test_runner/log_formatter.rb +10 -1
- data/lib/cem_acpt/test_runner.rb +151 -52
- data/lib/cem_acpt/utils/ssh.rb +2 -2
- data/lib/cem_acpt/utils/terminal.rb +1 -5
- data/lib/cem_acpt/utils/winrm_runner.rb +160 -0
- data/lib/cem_acpt/utils.rb +41 -1
- data/lib/cem_acpt/version.rb +1 -1
- data/lib/cem_acpt.rb +51 -21
- data/lib/terraform/gcp/linux/goss/puppet_idempotent.yaml +2 -2
- data/lib/terraform/gcp/linux/goss/puppet_noop.yaml +1 -1
- data/lib/terraform/gcp/windows/goss/puppet_idempotent.yaml +9 -0
- data/lib/terraform/gcp/windows/goss/puppet_noop.yaml +12 -0
- data/lib/terraform/gcp/windows/main.tf +115 -0
- metadata +49 -8
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
4
|
require 'json'
|
5
|
-
require 'ruby-terraform'
|
6
5
|
require_relative 'logging'
|
7
6
|
require_relative 'platform'
|
8
7
|
require_relative 'utils'
|
9
8
|
require_relative 'version'
|
9
|
+
require_relative 'provision/terraform/terraform_cmd'
|
10
10
|
require_relative 'image_builder/exec'
|
11
11
|
require_relative 'image_builder/provision_commands'
|
12
12
|
|
@@ -14,7 +14,17 @@ module CemAcpt
|
|
14
14
|
# This module contains the classes and methods for building test node images
|
15
15
|
module ImageBuilder
|
16
16
|
def self.build_images(config)
|
17
|
-
|
17
|
+
include CemAcpt::Logging
|
18
|
+
|
19
|
+
builder = TerraformBuilder.new(config)
|
20
|
+
builder.run
|
21
|
+
logger.info('CemAcpt::ImageBuilder') { "Image builder finished after #{builder.duration} seconds" }
|
22
|
+
if builder.exit_code.zero?
|
23
|
+
logger.info('CemAcpt::ImageBuilder') { 'Image builder finished successfully' }
|
24
|
+
else
|
25
|
+
logger.error('CemAcpt::ImageBuilder') { "Image builder finished with exit code #{builder.exit_code}" }
|
26
|
+
end
|
27
|
+
exit builder.exit_code
|
18
28
|
end
|
19
29
|
|
20
30
|
# This class builds test node images using Terraform
|
@@ -27,6 +37,8 @@ module CemAcpt
|
|
27
37
|
DEFAULT_VARS_FILE = 'imagevars.json'
|
28
38
|
include CemAcpt::Logging
|
29
39
|
|
40
|
+
attr_reader :exit_code, :duration
|
41
|
+
|
30
42
|
def initialize(config)
|
31
43
|
@config = config
|
32
44
|
@image_terraform_dir = File.join(config.get('terraform.dir'), 'image', config.get('platform.name'))
|
@@ -36,43 +48,56 @@ module CemAcpt
|
|
36
48
|
@linux_tfvars = { node_data: {} }
|
37
49
|
@windows_tfvars = { node_data: {} }
|
38
50
|
@duration = 0
|
39
|
-
@exit_code =
|
51
|
+
@exit_code = 1
|
40
52
|
@private_key = nil
|
41
53
|
@public_key = nil
|
42
54
|
end
|
43
55
|
|
44
56
|
def run
|
45
57
|
@start_time = Time.now
|
46
|
-
logger.
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
58
|
+
logger.start_ci_group("CemAcptImage v#{CemAcpt::VERSION} run started at #{@start_time}")
|
59
|
+
@all_tfvars = new_tfvars(@config)
|
60
|
+
@linux_tfvars, @windows_tfvars = divide_tfvars_by_os(@all_tfvars)
|
61
|
+
image_types = []
|
62
|
+
image_types << [@linux_tfvars, 'linux'] unless no_linux?
|
63
|
+
image_types << [@windows_tfvars, 'windows'] unless no_windows?
|
64
|
+
return dry_run(image_types) if @config.get('dry_run')
|
65
|
+
|
66
|
+
@working_dir = new_working_dir
|
67
|
+
logger.info('CemAcpt::ImageBuilder') { "Using working directory: #{@working_dir}..." }
|
68
|
+
keep_terminal_alive
|
69
|
+
save_vars_to_file!('linux', @linux_tfvars)
|
70
|
+
save_vars_to_file!('windows', @windows_tfvars)
|
71
|
+
terraform_init
|
72
|
+
image_types.each do |tfvars, os_str|
|
73
|
+
terraform_plan(os_str, tfvars, DEFAULT_PLAN_NAME)
|
74
|
+
begin
|
75
|
+
terraform_apply(os_str, DEFAULT_PLAN_NAME)
|
76
|
+
output = JSON.parse(terraform_output(os_str, 'node-data', json: true))
|
77
|
+
output.each do |instance_name, data|
|
78
|
+
logger.info('CemAcpt::ImageBuilder') { "Stopping instance #{instance_name}..." }
|
79
|
+
@exec.run('compute', 'instances', 'stop', instance_name)
|
80
|
+
unless @config.get('no_build_images')
|
68
81
|
deprecate_old_images_in_family(data['image_family'])
|
69
82
|
create_image_from_disk(data['disk_link'], image_name_from_image_family(data['image_family']), data['image_family'])
|
70
83
|
end
|
71
|
-
|
72
|
-
terraform_destroy(os_str, tfvars)
|
84
|
+
@exit_code = 0
|
73
85
|
end
|
86
|
+
ensure
|
87
|
+
terraform_destroy(os_str, tfvars) unless @config.get('no_destroy_nodes')
|
74
88
|
end
|
75
89
|
end
|
90
|
+
rescue StandardError => e
|
91
|
+
logger.error('CemAcpt::ImageBuilder') { "Image builder failed with error: #{e}" }
|
92
|
+
logger.verbose('CemAcpt::ImageBuilder') { e.backtrace.join("\n") }
|
93
|
+
@exit_code = 1
|
94
|
+
ensure
|
95
|
+
if @start_time
|
96
|
+
@duration = Time.now - @start_time
|
97
|
+
else
|
98
|
+
@duration = 0
|
99
|
+
end
|
100
|
+
logger.end_ci_group
|
76
101
|
end
|
77
102
|
|
78
103
|
private
|
@@ -84,21 +109,21 @@ module CemAcpt
|
|
84
109
|
end
|
85
110
|
|
86
111
|
def deprecate_old_images_in_family(image_family)
|
87
|
-
logger.info('
|
112
|
+
logger.info('CemAcpt::ImageBuilder') { "Deprecating old images in family #{image_family}..." }
|
88
113
|
images = @exec.run('compute', 'images', 'list', '--project', @config.get('platform.project'), '--filter', "family:#{image_family}")
|
89
114
|
images.each do |image|
|
90
115
|
next unless image['status'] == 'READY'
|
91
116
|
|
92
|
-
logger.info('
|
117
|
+
logger.info('CemAcpt::ImageBuilder') { "Deprecating image #{image['name']}..." }
|
93
118
|
@exec.run('compute', 'images', 'deprecate', image['name'], '--state', 'DEPRECATED', '--delete-in', '1d', '--project', @config.get('platform.project'))
|
94
119
|
end
|
95
120
|
end
|
96
121
|
|
97
122
|
def create_image_from_disk(disk_link, image_name, image_family)
|
98
|
-
logger.info('
|
123
|
+
logger.info('CemAcpt::ImageBuilder') { "Creating image from disk #{disk_link}..." }
|
99
124
|
@exec.run('compute', 'images', 'create', image_name, '--family', image_family,
|
100
125
|
'--source-disk', disk_link, '--project', @config.get('platform.project'))
|
101
|
-
logger.info('
|
126
|
+
logger.info('CemAcpt::ImageBuilder') { "Image #{image_name} created for family #{image_family}"}
|
102
127
|
end
|
103
128
|
|
104
129
|
def no_windows?
|
@@ -110,29 +135,22 @@ module CemAcpt
|
|
110
135
|
end
|
111
136
|
|
112
137
|
def dry_run(image_types)
|
113
|
-
logger.info('
|
138
|
+
logger.info('CemAcpt::ImageBuilder') { 'Dry run mode enabled. No images will be built.' }
|
114
139
|
image_types.each do |tfvars, os_str|
|
115
|
-
logger.info('
|
116
|
-
logger.info('
|
140
|
+
logger.info('CemAcpt::ImageBuilder') { "Dry run for #{os_str}..." }
|
141
|
+
logger.info('CemAcpt::ImageBuilder') { "Terraform vars:\n#{JSON.pretty_generate(tfvars)}" }
|
117
142
|
end
|
143
|
+
@exit_code = 0
|
118
144
|
end
|
119
145
|
|
120
146
|
def terraform
|
121
|
-
|
122
|
-
|
123
|
-
RubyTerraform.configure do |c|
|
124
|
-
c.logger = logger
|
125
|
-
c.stdout = logger
|
126
|
-
c.stderr = logger
|
127
|
-
end
|
128
|
-
@terraform = RubyTerraform
|
129
|
-
@terraform
|
147
|
+
@terraform ||= CemAcpt::Provision::TerraformCmd.new(@image_terraform_dir, @environment)
|
130
148
|
end
|
131
149
|
|
132
150
|
def new_environment(config)
|
133
151
|
env = (config.get('terraform.environment') || {})
|
134
152
|
env['CLOUDSDK_PYTHON_SITEPACKAGES'] = '1' # This is needed for gcloud to use numpy
|
135
|
-
logger.verbose('ImageBuilder') { "Using environment:\n#{JSON.pretty_generate(env)}" }
|
153
|
+
logger.verbose('CemAcpt::ImageBuilder') { "Using environment:\n#{JSON.pretty_generate(env)}" }
|
136
154
|
env
|
137
155
|
end
|
138
156
|
|
@@ -177,7 +195,7 @@ module CemAcpt
|
|
177
195
|
return unless block_given?
|
178
196
|
|
179
197
|
if no_os_str?(os_str)
|
180
|
-
logger.debug('ImageBuilder') { "Skipping #{os_str} because no_#{os_str} is true" }
|
198
|
+
logger.debug('CemAcpt::ImageBuilder') { "Skipping #{os_str} because no_#{os_str} is true" }
|
181
199
|
return
|
182
200
|
end
|
183
201
|
|
@@ -190,7 +208,7 @@ module CemAcpt
|
|
190
208
|
def terraform_init
|
191
209
|
raise 'Cannot initialize Terraform, both no_linux and no_windows are true' if no_linux? && no_windows?
|
192
210
|
|
193
|
-
logger.debug('ImageBuilder') { 'Initializing Terraform' }
|
211
|
+
logger.debug('CemAcpt::ImageBuilder') { 'Initializing Terraform' }
|
194
212
|
in_os_dir('linux') do
|
195
213
|
terraform.init({ input: false, no_color: true })
|
196
214
|
end
|
@@ -201,37 +219,37 @@ module CemAcpt
|
|
201
219
|
|
202
220
|
def terraform_plan(os_dir, tfvars, plan_name)
|
203
221
|
in_os_dir(os_dir) do
|
204
|
-
logger.debug('ImageBuilder') { "Creating Terraform plan #{plan_name} for #{os_dir}" }
|
205
|
-
logger.verbose('ImageBuilder') { "Using vars:\n#{JSON.pretty_generate(tfvars)}" }
|
222
|
+
logger.debug('CemAcpt::ImageBuilder') { "Creating Terraform plan #{plan_name} for #{os_dir}" }
|
223
|
+
logger.verbose('CemAcpt::ImageBuilder') { "Using vars:\n#{JSON.pretty_generate(tfvars)}" }
|
206
224
|
terraform.plan({ input: false, no_color: true, plan: plan_name, vars: tfvars }, { environment: environment })
|
207
225
|
end
|
208
226
|
end
|
209
227
|
|
210
228
|
def terraform_apply(os_dir, plan_name)
|
211
229
|
in_os_dir(os_dir) do
|
212
|
-
logger.debug('ImageBuilder') { "Applying Terraform plan #{plan_name} for #{os_dir}" }
|
230
|
+
logger.debug('CemAcpt::ImageBuilder') { "Applying Terraform plan #{plan_name} for #{os_dir}" }
|
213
231
|
terraform.apply({ input: false, no_color: true, plan: plan_name }, { environment: environment })
|
214
232
|
end
|
215
233
|
end
|
216
234
|
|
217
235
|
def terraform_output(os_dir, output_name, json: true)
|
218
236
|
in_os_dir(os_dir) do
|
219
|
-
logger.debug('ImageBuilder') { "Getting Terraform output #{output_name} for #{os_dir}" }
|
237
|
+
logger.debug('CemAcpt::ImageBuilder') { "Getting Terraform output #{output_name} for #{os_dir}" }
|
220
238
|
terraform.output({ no_color: true, json: json, name: output_name }, { environment: environment })
|
221
239
|
end
|
222
240
|
end
|
223
241
|
|
224
242
|
def terraform_destroy(os_dir, tfvars)
|
225
243
|
in_os_dir(os_dir) do
|
226
|
-
logger.debug('ImageBuilder') { "Destroying Terraform resources for #{os_dir}" }
|
227
|
-
logger.verbose('ImageBuilder') { "Using vars:\n#{JSON.pretty_generate(tfvars)}" }
|
244
|
+
logger.debug('CemAcpt::ImageBuilder') { "Destroying Terraform resources for #{os_dir}" }
|
245
|
+
logger.verbose('CemAcpt::ImageBuilder') { "Using vars:\n#{JSON.pretty_generate(tfvars)}" }
|
228
246
|
terraform.destroy({ auto_approve: true, input: false, no_color: true, vars: tfvars }, { environment: environment })
|
229
247
|
end
|
230
248
|
end
|
231
249
|
|
232
250
|
def terraform_show(os_dir)
|
233
251
|
in_os_dir(os_dir) do
|
234
|
-
logger.debug('ImageBuilder') { "Showing Terraform state for #{os_dir}" }
|
252
|
+
logger.debug('CemAcpt::ImageBuilder') { "Showing Terraform state for #{os_dir}" }
|
235
253
|
terraform.show({ no_color: true }, { environment: environment })
|
236
254
|
end
|
237
255
|
end
|
@@ -262,7 +280,7 @@ module CemAcpt
|
|
262
280
|
windows_image: windows_image?(image[:os]),
|
263
281
|
)
|
264
282
|
end
|
265
|
-
logger.verbose('ImageBuilder') { "All Terraform variables:\n#{JSON.pretty_generate(tfvars)}" }
|
283
|
+
logger.verbose('CemAcpt::ImageBuilder') { "All Terraform variables:\n#{JSON.pretty_generate(tfvars)}" }
|
266
284
|
tfvars
|
267
285
|
end
|
268
286
|
|
@@ -273,8 +291,8 @@ module CemAcpt
|
|
273
291
|
linux_tfvars[:node_data] = linux_node_data
|
274
292
|
windows_tfvars = tfvars.dup
|
275
293
|
windows_tfvars[:node_data] = windows_node_data
|
276
|
-
logger.verbose('ImageBuilder') { "Linux Terraform variables:\n#{JSON.pretty_generate(linux_tfvars)}" }
|
277
|
-
logger.verbose('ImageBuilder') { "Windows Terraform variables:\n#{JSON.pretty_generate(windows_tfvars)}" }
|
294
|
+
logger.verbose('CemAcpt::ImageBuilder') { "Linux Terraform variables:\n#{JSON.pretty_generate(linux_tfvars)}" }
|
295
|
+
logger.verbose('CemAcpt::ImageBuilder') { "Windows Terraform variables:\n#{JSON.pretty_generate(windows_tfvars)}" }
|
278
296
|
[linux_tfvars, windows_tfvars]
|
279
297
|
end
|
280
298
|
|
@@ -283,10 +301,10 @@ module CemAcpt
|
|
283
301
|
end
|
284
302
|
|
285
303
|
def save_vars_to_file!(prefix, vars)
|
286
|
-
logger.debug('ImageBuilder') { "Saving vars to file #{File.join(@working_dir, "#{prefix}_#{DEFAULT_VARS_FILE}")}" }
|
304
|
+
logger.debug('CemAcpt::ImageBuilder') { "Saving vars to file #{File.join(@working_dir, "#{prefix}_#{DEFAULT_VARS_FILE}")}" }
|
287
305
|
File.write(File.join(@working_dir, "#{prefix}_#{DEFAULT_VARS_FILE}"), vars.to_json)
|
288
306
|
rescue StandardError => e
|
289
|
-
logger.error('ImageBuilder') { 'Error saving vars to file' }
|
307
|
+
logger.error('CemAcpt::ImageBuilder') { 'Error saving vars to file' }
|
290
308
|
raise e
|
291
309
|
end
|
292
310
|
|
@@ -294,25 +312,25 @@ module CemAcpt
|
|
294
312
|
unless Dir.exist?(@image_terraform_dir)
|
295
313
|
raise "Image Terraform directory #{@image_terraform_dir} does not exist"
|
296
314
|
end
|
297
|
-
logger.debug('ImageBuilder') { "Creating new working directory in #{@image_terraform_dir}" }
|
315
|
+
logger.debug('CemAcpt::ImageBuilder') { "Creating new working directory in #{@image_terraform_dir}" }
|
298
316
|
working_dir = File.join(@image_terraform_dir, "image_builder_#{Time.now.to_i}")
|
299
317
|
FileUtils.mkdir_p(working_dir)
|
300
|
-
logger.verbose('ImageBuilder') { "Created working directory #{working_dir}" }
|
318
|
+
logger.verbose('CemAcpt::ImageBuilder') { "Created working directory #{working_dir}" }
|
301
319
|
FileUtils.cp_r(File.join(@image_terraform_dir, 'linux'), working_dir)
|
302
320
|
FileUtils.cp_r(File.join(@image_terraform_dir, 'windows'), working_dir)
|
303
|
-
logger.verbose('ImageBuilder') { "Copied Terraform files from #{@image_terraform_dir}/(linux|windows) to #{working_dir}" }
|
321
|
+
logger.verbose('CemAcpt::ImageBuilder') { "Copied Terraform files from #{@image_terraform_dir}/(linux|windows) to #{working_dir}" }
|
304
322
|
if File.exist?(@all_tfvars[:private_key])
|
305
323
|
FileUtils.cp(@all_tfvars[:private_key], working_dir)
|
306
324
|
@private_key = File.join(working_dir, File.basename(@all_tfvars[:private_key]))
|
307
|
-
logger.verbose('ImageBuilder') { "Copied private key #{@all_tfvars[:private_key]} to #{working_dir}" }
|
325
|
+
logger.verbose('CemAcpt::ImageBuilder') { "Copied private key #{@all_tfvars[:private_key]} to #{working_dir}" }
|
308
326
|
end
|
309
327
|
if File.exist?(@all_tfvars[:public_key])
|
310
328
|
FileUtils.cp(@all_tfvars[:public_key], working_dir)
|
311
329
|
@public_key = File.join(working_dir, File.basename(@all_tfvars[:public_key]))
|
312
|
-
logger.verbose('ImageBuilder') { "Copied public key #{@all_tfvars[:public_key]} to #{working_dir}" }
|
330
|
+
logger.verbose('CemAcpt::ImageBuilder') { "Copied public key #{@all_tfvars[:public_key]} to #{working_dir}" }
|
313
331
|
end
|
314
332
|
|
315
|
-
logger.verbose('ImageBuilder') { "Content of #{working_dir}:\n#{Dir.glob(File.join(working_dir, '*')).join("\n")}" }
|
333
|
+
logger.verbose('CemAcpt::ImageBuilder') { "Content of #{working_dir}:\n#{Dir.glob(File.join(working_dir, '*')).join("\n")}" }
|
316
334
|
working_dir
|
317
335
|
end
|
318
336
|
end
|
data/lib/cem_acpt/logging.rb
CHANGED
@@ -13,7 +13,7 @@ module CemAcpt
|
|
13
13
|
'error' => ::Logger::ERROR,
|
14
14
|
'fatal' => ::Logger::FATAL,
|
15
15
|
'unknown' => ::Logger::UNKNOWN,
|
16
|
-
}
|
16
|
+
}.freeze
|
17
17
|
|
18
18
|
# Delegator class for when you want to log to multiple devices
|
19
19
|
# at the same time, such as STDOUT and a file.
|
@@ -28,34 +28,39 @@ module CemAcpt
|
|
28
28
|
def self.from_logger_configs(configs)
|
29
29
|
return if configs.nil? || configs.empty?
|
30
30
|
|
31
|
-
|
31
|
+
logger_instances = configs.map do |config|
|
32
32
|
CemAcpt::Logging::Logger.new(config[:logdev],
|
33
33
|
config[:shift_age],
|
34
34
|
config[:shift_size],
|
35
35
|
**config.reject { |k, _| [:logdev, :shift_age, :shift_size].include?(k) })
|
36
36
|
end
|
37
|
-
new(*
|
37
|
+
new(*logger_instances)
|
38
38
|
end
|
39
39
|
|
40
|
-
def initialize(*
|
41
|
-
@loggers =
|
40
|
+
def initialize(*logger_instances)
|
41
|
+
@loggers = logger_instances
|
42
42
|
end
|
43
43
|
|
44
44
|
def logger_configs
|
45
|
-
|
45
|
+
loggers.map(&:config_hash)
|
46
46
|
end
|
47
47
|
|
48
48
|
def method_missing(m, *args, &block)
|
49
|
-
if
|
50
|
-
|
49
|
+
if loggers.all? { |l| l.respond_to?(m) }
|
50
|
+
loggers.map { |l| l.send(m, *args, &block) }
|
51
51
|
else
|
52
52
|
super
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
56
|
def respond_to_missing?(m, include_private = false)
|
57
|
-
|
57
|
+
loggers.all? { |l| l.respond_to?(m) } || super
|
58
58
|
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# Basically just for making testing easier
|
63
|
+
attr_reader :loggers
|
59
64
|
end
|
60
65
|
|
61
66
|
# Delagator class for the standard Ruby Logger class.
|
@@ -89,55 +94,63 @@ module CemAcpt
|
|
89
94
|
end
|
90
95
|
|
91
96
|
def debug(progname = nil, &block)
|
92
|
-
|
93
|
-
return
|
97
|
+
severity = 'debug'
|
98
|
+
return log_trap_context(severity, progname, &block) if log_trap_context?(severity)
|
99
|
+
return log_ci_mode(severity, progname, &block) if log_ci_mode?(severity)
|
94
100
|
|
95
101
|
super
|
96
102
|
end
|
97
103
|
|
98
104
|
def info(progname = nil, &block)
|
99
|
-
|
100
|
-
return
|
105
|
+
severity = 'info'
|
106
|
+
return log_trap_context(severity, progname, &block) if log_trap_context?(severity)
|
107
|
+
return log_ci_mode(severity, progname, &block) if log_ci_mode?(severity)
|
101
108
|
|
102
109
|
super
|
103
110
|
end
|
104
111
|
|
105
112
|
def warn(progname = nil, &block)
|
106
|
-
|
107
|
-
return
|
113
|
+
severity = 'warn'
|
114
|
+
return log_trap_context(severity, progname, &block) if log_trap_context?(severity)
|
115
|
+
return log_ci_mode(severity, progname, &block) if log_ci_mode?(severity)
|
108
116
|
|
109
117
|
super
|
110
118
|
end
|
111
119
|
|
112
120
|
def error(progname = nil, &block)
|
113
|
-
|
114
|
-
return
|
121
|
+
severity = 'error'
|
122
|
+
return log_trap_context(severity, progname, &block) if log_trap_context?(severity)
|
123
|
+
return log_ci_mode(severity, progname, &block) if log_ci_mode?(severity)
|
115
124
|
|
116
125
|
super
|
117
126
|
end
|
118
127
|
|
119
128
|
def fatal(progname = nil, &block)
|
120
|
-
|
121
|
-
return
|
129
|
+
severity = 'fatal'
|
130
|
+
return log_trap_context(severity, progname, &block) if log_trap_context?(severity)
|
131
|
+
return log_ci_mode(severity, progname, &block) if log_ci_mode?(severity)
|
122
132
|
|
123
133
|
super
|
124
134
|
end
|
125
135
|
|
126
|
-
|
127
|
-
# @param name [String] the name of the group
|
128
|
-
def with_ci_group(name)
|
136
|
+
def start_ci_group(name)
|
129
137
|
if @ci_mode
|
130
138
|
self.<< "::group::#{name}\n"
|
131
139
|
else
|
132
140
|
info(name)
|
133
141
|
end
|
134
|
-
|
135
|
-
|
142
|
+
end
|
143
|
+
|
144
|
+
def end_ci_group
|
136
145
|
self.<< "::endgroup::\n" if @ci_mode
|
137
146
|
end
|
138
147
|
|
139
148
|
private
|
140
149
|
|
150
|
+
def log_trap_context?(severity)
|
151
|
+
@trap_context && level <= LEVEL_MAP[severity]
|
152
|
+
end
|
153
|
+
|
141
154
|
# Can't use the standard Logger methods when in trap context
|
142
155
|
# because they don't work. So we have to write directly to the
|
143
156
|
# raw logdev. Unlike the standard Logger methods, there is no
|
@@ -145,8 +158,6 @@ module CemAcpt
|
|
145
158
|
# This is necessary in the trap context because using a Mutex
|
146
159
|
# lock in a trap context will cause a deadlock.
|
147
160
|
def log_trap_context(severity, progname = nil, &block)
|
148
|
-
return false unless @trap_context && level <= LEVEL_MAP[severity]
|
149
|
-
|
150
161
|
if @raw_logdev.respond_to?(:puts)
|
151
162
|
@raw_logdev.puts(ci_format(severity, false, progname, &block))
|
152
163
|
elsif @raw_logdev.respond_to?(:write)
|
@@ -155,7 +166,10 @@ module CemAcpt
|
|
155
166
|
# Default to logging to STDERR
|
156
167
|
$stderr.puts(ci_format(severity, false, progname, &block))
|
157
168
|
end
|
158
|
-
|
169
|
+
end
|
170
|
+
|
171
|
+
def log_ci_mode?(severity)
|
172
|
+
@ci_mode && level <= LEVEL_MAP[severity]
|
159
173
|
end
|
160
174
|
|
161
175
|
# CI mode uses << instead of the standard Logger methods
|
@@ -164,10 +178,7 @@ module CemAcpt
|
|
164
178
|
# with a standard Logger, the CI mode messages are still
|
165
179
|
# formatted correctly.
|
166
180
|
def log_ci_mode(severity, progname = nil, &block)
|
167
|
-
return false unless @ci_mode && level <= LEVEL_MAP[severity]
|
168
|
-
|
169
181
|
self.<<(ci_format(severity, true, progname, &block))
|
170
|
-
true
|
171
182
|
end
|
172
183
|
|
173
184
|
# Formats the log message for CI mode, translating the severity
|
data/lib/cem_acpt/platform.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'concurrent-ruby'
|
4
3
|
require_relative 'logging'
|
5
4
|
|
6
5
|
# CemAcpt::Platform manages creating and configring platform specific objects
|
@@ -25,7 +24,7 @@ module CemAcpt::Platform
|
|
25
24
|
raise Error, 'run_data must include a :test_data key' unless run_data.key?(:test_data)
|
26
25
|
raise Error, 'run_data[:test_data] must be an Array' unless run_data[:test_data].is_a?(Array)
|
27
26
|
|
28
|
-
logger.info "Using #{platform} for #{run_data[:test_data].length} tests..."
|
27
|
+
logger.info('CemAcpt::Platform') { "Using #{platform} for #{run_data[:test_data].length} tests..." }
|
29
28
|
run_data[:test_data].dup.each_with_object([]) do |single_test_data, ary|
|
30
29
|
ary << new_test_platform_object(platform, config, single_test_data, **run_data.reject { |k, _| k == :test_data })
|
31
30
|
end
|
@@ -53,7 +52,7 @@ module CemAcpt::Platform
|
|
53
52
|
File.basename(file, '.rb') unless file.end_with?('base.rb')
|
54
53
|
end
|
55
54
|
@platforms.compact!
|
56
|
-
logger.debug "Discovered platform(s): #{@platforms}"
|
55
|
+
logger.debug('CemAcpt::Platform') { "Discovered platform(s): #{@platforms}" }
|
57
56
|
@platforms
|
58
57
|
end
|
59
58
|
|
@@ -83,7 +82,7 @@ module CemAcpt::Platform
|
|
83
82
|
require_relative 'platform/base'
|
84
83
|
# If the class has already been defined, we can just use it.
|
85
84
|
if Object.const_defined?(class_name)
|
86
|
-
logger.debug "Using existing platform class #{class_name}"
|
85
|
+
logger.debug('CemAcpt::Platform') { "Using existing platform class #{class_name}" }
|
87
86
|
klass = Object.const_get(class_name)
|
88
87
|
else
|
89
88
|
# Otherwise, we need to create the class. We do this by setting
|
@@ -110,7 +109,7 @@ module CemAcpt::Platform
|
|
110
109
|
end,
|
111
110
|
)
|
112
111
|
end
|
113
|
-
logger.debug "Using platform class: #{klass.inspect}"
|
112
|
+
logger.debug('CemAcpt::Platform') { "Using platform class: #{klass.inspect}" }
|
114
113
|
klass
|
115
114
|
end
|
116
115
|
end
|
@@ -40,7 +40,23 @@ module CemAcpt
|
|
40
40
|
commands << "sudo systemctl start #{file} && sudo systemctl enable #{file}"
|
41
41
|
end
|
42
42
|
end
|
43
|
-
commands <<
|
43
|
+
commands << apply_command
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def apply_command
|
49
|
+
cmd = [
|
50
|
+
'sudo',
|
51
|
+
puppet_bin_path,
|
52
|
+
'apply',
|
53
|
+
'--logdest',
|
54
|
+
'console,/opt/cem_acpt/provision_apply.log',
|
55
|
+
]
|
56
|
+
cmd << '--debug' if @config.debug? && !@config.get('puppet.no_debug')
|
57
|
+
cmd << '--verbose' if @config.verbose? && !@config.get('puppet.no_verbose')
|
58
|
+
cmd << "#{destination_provision_directory}/#{puppet_manifest_file}"
|
59
|
+
cmd.join(' ')
|
44
60
|
end
|
45
61
|
end
|
46
62
|
end
|