cem_acpt 0.10.3 → 0.10.4
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/Gemfile.lock +1 -1
- data/lib/cem_acpt/actions.rb +7 -2
- data/lib/cem_acpt/goss/api/action_response.rb +5 -3
- data/lib/cem_acpt/goss/api.rb +22 -52
- data/lib/cem_acpt/logging.rb +2 -2
- data/lib/cem_acpt/provision/terraform/linux.rb +7 -0
- data/lib/cem_acpt/test_runner/test_results.rb +8 -8
- data/lib/cem_acpt/test_runner.rb +23 -27
- data/lib/cem_acpt/utils/puppet.rb +50 -16
- data/lib/cem_acpt/utils.rb +2 -1
- data/lib/cem_acpt/version.rb +1 -1
- data/lib/terraform/gcp/linux/log_service/log_service.rb +62 -0
- data/lib/terraform/gcp/linux/systemd/goss-acpt.service +1 -1
- data/lib/terraform/gcp/linux/systemd/goss-idempotent.service +1 -1
- data/lib/terraform/gcp/linux/systemd/goss-noop.service +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f6d280d4ac5c56cd722e9a2a906647996cc18a5db7babc1f950b74a44306fc3
|
4
|
+
data.tar.gz: f62af838277ee9e25b2af58093d1183460bc9022a175399c5830d38e49d01620
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d573fb143effd9425d6b38f6e764c8bafb44acb583bf95b9f2a600ca787e975875e2004edcaedc78876c303342663376334fde8fff37c5fef1bed3b131c9442
|
7
|
+
data.tar.gz: a4e164fd64921e3bdde69e664f846ebe3fc307e1d919fff61df40634ac34794124d5e15539c3c657f874c6e9403228e3dca2593c4fe54358b0c588ba92e5e698
|
data/Gemfile.lock
CHANGED
data/lib/cem_acpt/actions.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'async'
|
4
4
|
require 'async/barrier'
|
5
5
|
require 'async/http/internet'
|
6
|
+
require_relative 'logging'
|
6
7
|
|
7
8
|
module CemAcpt
|
8
9
|
# Provides a way to register actions to be executed if the registered
|
@@ -12,7 +13,7 @@ module CemAcpt
|
|
12
13
|
class Action
|
13
14
|
attr_reader :name, :order
|
14
15
|
|
15
|
-
def initialize(name, order
|
16
|
+
def initialize(name, order: 0, &block)
|
16
17
|
@name = name.to_sym
|
17
18
|
@order = order
|
18
19
|
@block = block
|
@@ -42,7 +43,7 @@ module CemAcpt
|
|
42
43
|
# order of the associated action groups' execution order. Defaults to 0.
|
43
44
|
# @param block [Proc] the block to be executed
|
44
45
|
def register_action(name, order: 0, &block)
|
45
|
-
new_action = Action.new(name, order, &block)
|
46
|
+
new_action = Action.new(name, order: order, &block)
|
46
47
|
@actions << new_action
|
47
48
|
sort!
|
48
49
|
self # return self to allow chaining
|
@@ -119,6 +120,8 @@ module CemAcpt
|
|
119
120
|
class << self
|
120
121
|
attr_reader :config
|
121
122
|
|
123
|
+
include CemAcpt::Logging
|
124
|
+
|
122
125
|
# Configures the Actions module.
|
123
126
|
# @param world_config [CemAcpt::Config::Base] the current config for the "world"
|
124
127
|
# @yield [CemAcpt::Actions::ActionConfig] the config object for the Actions module
|
@@ -134,12 +137,14 @@ module CemAcpt
|
|
134
137
|
# @option opts [Hash] :context the context to be passed to the actions
|
135
138
|
# @return [Array] the results of the actions
|
136
139
|
def execute(**opts)
|
140
|
+
logger.debug('CemAcpt::Actions') { "Executing registered actions with opts: #{opts}" }
|
137
141
|
context = opts[:context] || {}
|
138
142
|
ordered_groups = config.groups.values.sort_by(&:order)
|
139
143
|
ordered_groups.each_with_object([]) do |group, results|
|
140
144
|
actions = group.filter_actions
|
141
145
|
next if actions.empty?
|
142
146
|
|
147
|
+
logger.debug('CemAcpt::Actions') { "Executing action group: #{group.name}" }
|
143
148
|
context[:group] = group.name
|
144
149
|
context[:actions] = actions.map(&:name)
|
145
150
|
if group.async
|
@@ -4,13 +4,14 @@ module CemAcpt
|
|
4
4
|
module Goss
|
5
5
|
module Api
|
6
6
|
class ActionResponse
|
7
|
-
attr_reader :host, :action, :body
|
7
|
+
attr_reader :host, :action, :body, :metadata
|
8
8
|
|
9
9
|
def initialize(host, action, status, body)
|
10
10
|
@host = host
|
11
11
|
@action = action
|
12
12
|
@status = status
|
13
13
|
@body = body
|
14
|
+
@metadata = {}
|
14
15
|
end
|
15
16
|
|
16
17
|
def to_s
|
@@ -27,6 +28,7 @@ module CemAcpt
|
|
27
28
|
action: action,
|
28
29
|
status: @status,
|
29
30
|
body: @body,
|
31
|
+
metadata: @metadata,
|
30
32
|
}
|
31
33
|
end
|
32
34
|
|
@@ -40,11 +42,11 @@ module CemAcpt
|
|
40
42
|
end
|
41
43
|
|
42
44
|
def error
|
43
|
-
results.find(&:error)
|
45
|
+
results.find(&:error)
|
44
46
|
end
|
45
47
|
|
46
48
|
def error?
|
47
|
-
!success?
|
49
|
+
!success? && !error.nil?
|
48
50
|
end
|
49
51
|
|
50
52
|
def results
|
data/lib/cem_acpt/goss/api.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'async'
|
4
|
-
require 'async/barrier'
|
5
|
-
require 'async/http/internet'
|
6
3
|
require 'json'
|
7
4
|
require_relative 'api/action_response'
|
8
5
|
require_relative '../logging'
|
@@ -31,64 +28,37 @@ module CemAcpt
|
|
31
28
|
URI("http://#{host}:#{ACTIONS[action.to_sym]}")
|
32
29
|
end
|
33
30
|
|
34
|
-
#
|
35
|
-
# @param
|
36
|
-
# @
|
37
|
-
#
|
38
|
-
# @
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
raise ArgumentError, 'actions must be an Array' unless actions.is_a?(Array)
|
48
|
-
|
49
|
-
actions.map!(&:to_sym)
|
50
|
-
actions.select! { |action| ACTIONS.key?(action) }
|
51
|
-
logger.info('CemAcpt::Goss::Api') do
|
52
|
-
"Running test actions #{actions.join(', ')} against #{hosts.size} host(s)..."
|
53
|
-
end
|
54
|
-
task = Async do
|
55
|
-
internet = Async::HTTP::Internet.new
|
56
|
-
barrier = Async::Barrier.new
|
57
|
-
barrier.async do
|
58
|
-
hosts.each do |host|
|
59
|
-
actions.each do |action|
|
60
|
-
results << run_action(internet, host, action)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
barrier.wait
|
65
|
-
ensure
|
66
|
-
internet&.close
|
31
|
+
# Get the JSON response from the specified URI.
|
32
|
+
# @param uri [URI] The URI to get the JSON response from.
|
33
|
+
# @param internet [nil, Async::HTTP::Internet] The object to use for the request. If nil,
|
34
|
+
# Net::HTTP will be used.
|
35
|
+
# @return [Array] The status code and the parsed JSON response body.
|
36
|
+
def get(uri, internet = nil)
|
37
|
+
if internet.nil?
|
38
|
+
require 'net/http'
|
39
|
+
response = Net::HTTP.get_response(uri)
|
40
|
+
[response.code, JSON.parse(response.body)]
|
41
|
+
else
|
42
|
+
response = internet.get(uri.to_s)
|
43
|
+
[response.status, JSON.parse(response.read)]
|
67
44
|
end
|
68
|
-
task.wait
|
69
|
-
logger.info('CemAcpt::Goss::Api') { 'Finished running test actions, returning results...' }
|
70
|
-
results
|
71
|
-
end
|
72
|
-
|
73
|
-
def run_action_async(context = {})
|
74
|
-
context[:results] ||= Queue.new
|
75
|
-
context[:hosts].each do |host|
|
76
|
-
context[:results] << run_action(context[:internet], host, context[:action])
|
77
|
-
end
|
78
|
-
context[:results]
|
79
45
|
end
|
80
46
|
|
81
47
|
# Run the specified action against the specified host.
|
82
|
-
# @param internet [Async::HTTP::Internet] The Async::HTTP::Internet object to use for the request.
|
83
48
|
# @param host [String] The host to run the action against. This should be
|
84
49
|
# a public IP address or a DNS-resolvable name.
|
85
50
|
# @param action [Symbol] The action to run.
|
51
|
+
# @param internet [nil, Async::HTTP::Internet] The object to use for the request.
|
86
52
|
# @return [ActionResponse] The response from the action.
|
87
|
-
def run_action(
|
53
|
+
def run_action(host, action, internet = nil)
|
88
54
|
uri = action_uri(host, action)
|
89
|
-
|
90
|
-
|
91
|
-
|
55
|
+
status_code, body = get(uri, internet)
|
56
|
+
ActionResponse.new(host, action, status_code, body)
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_run_logs(host, internet = nil)
|
60
|
+
status_code, body = get(URI("http://#{host}:8083/run-logs"), internet)
|
61
|
+
ActionResponse.new(host, :run_logs, status_code, body)
|
92
62
|
end
|
93
63
|
end
|
94
64
|
end
|
data/lib/cem_acpt/logging.rb
CHANGED
@@ -198,7 +198,7 @@ module CemAcpt
|
|
198
198
|
else
|
199
199
|
severity
|
200
200
|
end
|
201
|
-
block_message =
|
201
|
+
block_message = block ? yield : nil
|
202
202
|
base = [progname, block_message].compact.join(': ')
|
203
203
|
return if base.empty?
|
204
204
|
|
@@ -272,7 +272,7 @@ module CemAcpt
|
|
272
272
|
|
273
273
|
@log_config = {
|
274
274
|
logdev: $stdout,
|
275
|
-
shift_age:
|
275
|
+
shift_age: 0,
|
276
276
|
shift_size: 1_048_576,
|
277
277
|
level: ::Logger::INFO,
|
278
278
|
progname: 'CemAcpt',
|
@@ -30,6 +30,9 @@ module CemAcpt
|
|
30
30
|
commands = [
|
31
31
|
"sudo /opt/puppetlabs/puppet/bin/puppet module install #{destination_provision_directory}/#{remote_module_package_name}",
|
32
32
|
'curl -fsSL https://goss.rocks/install | sudo sh',
|
33
|
+
'sudo /opt/puppetlabs/puppet/bin/gem install webrick',
|
34
|
+
'sudo chmod +x /opt/cem_acpt/log_service/log_service.rb',
|
35
|
+
'sudo /opt/cem_acpt/log_service/log_service.rb',
|
33
36
|
]
|
34
37
|
unless systemd_files.empty?
|
35
38
|
systemd_files.each do |file|
|
@@ -54,6 +57,10 @@ module CemAcpt
|
|
54
57
|
]
|
55
58
|
commands = (commands << provision_commands).flatten
|
56
59
|
commands
|
60
|
+
elsif image_name.include?('ubuntu')
|
61
|
+
commands = ['sudo apt purge -y unattended-upgrades', 'sudo apt-get update -y']
|
62
|
+
commands = (commands << provision_commands).flatten
|
63
|
+
commands
|
57
64
|
else
|
58
65
|
provision_commands
|
59
66
|
end
|
@@ -28,14 +28,14 @@ module CemAcpt
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def <<(result)
|
31
|
-
case result
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
31
|
+
@results_queue << case result
|
32
|
+
when TestActionResult, TestErrorActionResult
|
33
|
+
result
|
34
|
+
when StandardError
|
35
|
+
TestErrorActionResult.new(result, new_formatter(result))
|
36
|
+
else
|
37
|
+
TestActionResult.new(result, new_formatter(result))
|
38
|
+
end
|
39
39
|
end
|
40
40
|
|
41
41
|
def to_a
|
data/lib/cem_acpt/test_runner.rb
CHANGED
@@ -28,6 +28,7 @@ module CemAcpt
|
|
28
28
|
|
29
29
|
def initialize(config)
|
30
30
|
@config = config
|
31
|
+
@module_builder = CemAcpt::Utils::Puppet::ModulePackageBuilder.new(config.get('module_dir'))
|
31
32
|
@run_data = {}
|
32
33
|
@duration = 0
|
33
34
|
@exit_code = 0
|
@@ -101,8 +102,7 @@ module CemAcpt
|
|
101
102
|
destroy_test_nodes
|
102
103
|
end
|
103
104
|
rescue StandardError => e
|
104
|
-
logger.verbose('CemAcpt::TestRunner') { "Error cleaning up: #{e}" }
|
105
|
-
logger.verbose('CemAcpt::TestRunner') { e.backtrace.join("\n") }
|
105
|
+
logger.verbose('CemAcpt::TestRunner') { "Error cleaning up: #{e}\n#{e.backtrace.join("\n")}" }
|
106
106
|
ensure
|
107
107
|
logger.end_ci_group
|
108
108
|
end
|
@@ -118,16 +118,20 @@ module CemAcpt
|
|
118
118
|
c.register_group(:goss, order: 0, async: true)
|
119
119
|
CemAcpt::Goss::Api::ACTIONS.each_key do |a|
|
120
120
|
c[:goss].register_action(a) do |context|
|
121
|
-
|
121
|
+
context[:hosts] = @hosts
|
122
|
+
context[:results] = @results
|
123
|
+
context[:hosts].each do |host|
|
124
|
+
action_res = CemAcpt::Goss::Api.run_action(host, context[:action], context[:internet])
|
125
|
+
action_res.metadata[:run_logs] = CemAcpt::Goss::Api.get_run_logs(host, context[:internet]).body
|
126
|
+
context[:results] << action_res
|
127
|
+
end
|
128
|
+
context[:results]
|
122
129
|
end
|
123
130
|
end
|
124
131
|
c.register_group(:bolt, order: 1).register_action(:bolt) do |context|
|
125
132
|
run_bolt_tests(context)
|
126
133
|
end
|
127
134
|
end
|
128
|
-
logger.debug('CemAcpt::TestRunner') { "All actions #{CemAcpt::Actions.config.action_names}" }
|
129
|
-
logger.debug('CemAcpt::TestRunner') { "Only actions: #{CemAcpt::Actions.config.only}" }
|
130
|
-
logger.debug('CemAcpt::TestRunner') { "Except actions: #{CemAcpt::Actions.config.except}" }
|
131
135
|
logger.info('CemAcpt::TestRunner') do
|
132
136
|
"Configured and registered actions, will run actions: #{CemAcpt::Actions.config.action_names.join(', ')}"
|
133
137
|
end
|
@@ -135,13 +139,7 @@ module CemAcpt
|
|
135
139
|
|
136
140
|
# @return [String] The path to the module package
|
137
141
|
def build_module_package
|
138
|
-
|
139
|
-
CemAcpt::Utils.package_win_module(config.get('module_dir'))
|
140
|
-
else
|
141
|
-
CemAcpt::Utils::Puppet.build_module_package(config.get('module_dir'))
|
142
|
-
end
|
143
|
-
logger.info('CemAcpt::TestRunner') { "Created module package: #{pkg_path}..." }
|
144
|
-
pkg_path
|
142
|
+
@module_builder.build
|
145
143
|
end
|
146
144
|
|
147
145
|
# @return [Array<String>] The paths to the ssh private key, public key, and known hosts file
|
@@ -261,20 +259,6 @@ module CemAcpt
|
|
261
259
|
CemAcpt::Actions.execute
|
262
260
|
end
|
263
261
|
|
264
|
-
def run_goss_tests(context = {})
|
265
|
-
logger.info('CemAcpt::TestRunner') { 'Running goss tests...' }
|
266
|
-
context[:hosts] = @hosts
|
267
|
-
context[:results] = @results
|
268
|
-
CemAcpt::Goss::Api.run_actions_async(context)
|
269
|
-
end
|
270
|
-
|
271
|
-
def run_goss_test(context = {})
|
272
|
-
logger.info('CemAcpt::TestRunner') { "Running Goss test for action #{context[:action]}..." }
|
273
|
-
context[:hosts] = @hosts
|
274
|
-
context[:results] = @results
|
275
|
-
CemAcpt::Goss::Api.run_action_async(context)
|
276
|
-
end
|
277
|
-
|
278
262
|
def run_bolt_tests(_context = {})
|
279
263
|
logger.info('CemAcpt::TestRunner') { 'Running Bolt tests...' }
|
280
264
|
# If the Bolt config has tests:only or tests:ignore lists, we need to filter the hosts
|
@@ -364,6 +348,18 @@ module CemAcpt
|
|
364
348
|
logger.info { r }
|
365
349
|
else
|
366
350
|
logger.error { r }
|
351
|
+
logs = if config.debug? && !config.get('puppet.no_debug')
|
352
|
+
result.metadata[:run_logs]&.dup
|
353
|
+
else
|
354
|
+
filtered = result.metadata[:run_logs]&.dup
|
355
|
+
filtered&.each { |_, v| v.reject! { |l| l.include?('(debug)') } }
|
356
|
+
filtered
|
357
|
+
end
|
358
|
+
unless logs.nil? || logs.empty?
|
359
|
+
logger.debug { "Logs for provision apply:\n#{logs['provision'].join}" } if logs['provision']
|
360
|
+
logger.error { "Logs for idempotent apply:\n#{logs['idempotent'].join}" } if logs['idempotent']
|
361
|
+
logger.error { "Logs for noop apply:\n#{logs['noop'].join}" } if logs['noop']
|
362
|
+
end
|
367
363
|
end
|
368
364
|
end
|
369
365
|
end
|
@@ -2,27 +2,61 @@
|
|
2
2
|
|
3
3
|
require 'puppet/modulebuilder'
|
4
4
|
require 'fileutils'
|
5
|
+
require_relative '../logging'
|
5
6
|
|
6
7
|
module CemAcpt
|
7
8
|
module Utils
|
8
9
|
# Puppet-related utilities
|
9
10
|
module Puppet
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
11
|
+
class ModulePackageBuilder
|
12
|
+
include CemAcpt::Logging
|
13
|
+
|
14
|
+
attr_reader :module_dir, :target_dir, :should_log, :metadata, :package_path
|
15
|
+
|
16
|
+
def initialize(module_dir, target_dir: nil, should_log: false, builder: ::Puppet::Modulebuilder::Builder)
|
17
|
+
@module_dir = ::File.expand_path(module_dir)
|
18
|
+
@target_dir = target_dir
|
19
|
+
@should_log = should_log
|
20
|
+
@builder = new_builder(builder)
|
21
|
+
@metadata = @builder.metadata # Validates metadata
|
22
|
+
@package_built = false
|
23
|
+
@package_path = nil
|
24
|
+
end
|
25
|
+
|
26
|
+
# Builds a Puppet module package.
|
27
|
+
# @return [String] Path to the built package.
|
28
|
+
def build
|
29
|
+
@package_path = @metadata['name'].include?('windows') ? build_windows_package : @builder.build
|
30
|
+
@package_built = true
|
31
|
+
logger.info('CemAcpt::Utils::Puppet::ModulePackageBuilder') { "Built module package: #{@package_path}" }
|
32
|
+
@package_path
|
33
|
+
end
|
34
|
+
|
35
|
+
# Determines if a package has been built.
|
36
|
+
def package_built?
|
37
|
+
@package_built
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# This method is used to create a new builder instance.
|
43
|
+
# It is used to allow for dependency injection in tests.
|
44
|
+
def new_builder(builder)
|
45
|
+
builder.new(@module_dir, @target_dir, @should_log ? logger : nil)
|
46
|
+
end
|
47
|
+
|
48
|
+
# This method is used to build a Windows module package.
|
49
|
+
# It's unknown exactly why we need to package the Windows module differently from the Linux module.
|
50
|
+
# When we find out, we should add an explanation here.
|
51
|
+
def build_windows_module
|
52
|
+
package_name = "#{@metadata['name']}.tar.gz"
|
53
|
+
package_file = ::File.join(@module_dir, package_name)
|
54
|
+
::FileUtils.rm_f(package_file) # Remove the old package file if it exists
|
55
|
+
Dir.chdir(@module_dir) do
|
56
|
+
`touch #{package_name} && tar -czf #{package_name} --exclude=#{package_name} *`
|
57
|
+
end
|
58
|
+
package_file
|
59
|
+
end
|
26
60
|
end
|
27
61
|
end
|
28
62
|
end
|
data/lib/cem_acpt/utils.rb
CHANGED
@@ -13,6 +13,7 @@ module CemAcpt
|
|
13
13
|
class << self
|
14
14
|
include CemAcpt::Logging
|
15
15
|
|
16
|
+
# This is method currently unused, see lib/cem_acpt/utils/puppet.rb for details.
|
16
17
|
def package_win_module(module_dir)
|
17
18
|
# Path to the package file
|
18
19
|
package_file = File.join(module_dir, 'puppetlabs-cem_windows.tar.gz')
|
@@ -53,7 +54,7 @@ module CemAcpt
|
|
53
54
|
def get_windows_login_info(instance_name, hash_of_instance)
|
54
55
|
password_and_username = {}
|
55
56
|
password_and_username[instance_name] = {}
|
56
|
-
info = reset_password_readiness_polling(instance_name).split(
|
57
|
+
info = reset_password_readiness_polling(instance_name).split(%r{\r?\n})[1..2]
|
57
58
|
info.each do |line|
|
58
59
|
key_val = line.split(' ')
|
59
60
|
password_and_username[instance_name][key_val[0].strip.delete(':')] = key_val[1].strip
|
data/lib/cem_acpt/version.rb
CHANGED
@@ -0,0 +1,62 @@
|
|
1
|
+
#!/opt/puppetlabs/puppet/bin/ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'json'
|
5
|
+
require 'webrick'
|
6
|
+
|
7
|
+
# Implements a simple HTTP server that serves the various run logs
|
8
|
+
class RunLogs < WEBrick::HTTPServlet::AbstractServlet
|
9
|
+
# rubocop:disable Naming/MethodName
|
10
|
+
def do_GET(_request, response)
|
11
|
+
run_logs = {}
|
12
|
+
p_logs = read_log_file('/opt/cem_acpt/provision_apply.log')
|
13
|
+
i_logs = read_log_file('/opt/cem_acpt/idempotent_apply.log')
|
14
|
+
n_logs = read_log_file('/opt/cem_acpt/noop_apply.log')
|
15
|
+
run_logs['provision'] = p_logs unless p_logs.empty?
|
16
|
+
run_logs['idempotent'] = i_logs unless i_logs.empty?
|
17
|
+
run_logs['noop'] = n_logs unless n_logs.empty?
|
18
|
+
response.status = run_logs.empty? ? 404 : 200
|
19
|
+
response['Content-Type'] = 'application/json'
|
20
|
+
response.body = run_logs.to_json
|
21
|
+
end
|
22
|
+
# rubocop:enable Naming/MethodName
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def read_log_file(file)
|
27
|
+
if File.exist?(file)
|
28
|
+
format_log(File.readlines(file))
|
29
|
+
else
|
30
|
+
[]
|
31
|
+
end
|
32
|
+
rescue StandardError => e
|
33
|
+
['Error reading log file', e.message, e.backtrace.join("\n")]
|
34
|
+
end
|
35
|
+
|
36
|
+
def format_log(log)
|
37
|
+
# Force UTF-8 on each line so they aren't mangled by the UTF to ASCII conversion
|
38
|
+
encoded = log.map { |l| l.force_encoding(Encoding::UTF_8) }
|
39
|
+
# Now we need to condense the lines into logical groups based on log entry. This
|
40
|
+
# allows us to filter out debug logs that span multiple lines.
|
41
|
+
memo = nil
|
42
|
+
encoded.each_with_object([]) do |line, formatted|
|
43
|
+
if memo.nil?
|
44
|
+
memo = line
|
45
|
+
elsif line.match?(%r{^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} \+\d{4}.*$})
|
46
|
+
formatted << memo
|
47
|
+
memo = line
|
48
|
+
else
|
49
|
+
memo += line
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
server = WEBrick::HTTPServer.new(Port: 8083)
|
56
|
+
server.mount '/run-logs', RunLogs
|
57
|
+
|
58
|
+
trap 'INT' do
|
59
|
+
server.shutdown
|
60
|
+
end
|
61
|
+
WEBrick::Daemon.start
|
62
|
+
server.start
|
@@ -2,7 +2,7 @@
|
|
2
2
|
Description=unit file for goss server acpt endpoint service
|
3
3
|
|
4
4
|
[Service]
|
5
|
-
ExecStart=/usr/local/bin/goss -g /opt/cem_acpt/goss.yaml serve -f json --endpoint "/acpt" --cache
|
5
|
+
ExecStart=/usr/local/bin/goss -g /opt/cem_acpt/goss.yaml serve -f json -o pretty --endpoint "/acpt" --cache '0s'
|
6
6
|
|
7
7
|
[Install]
|
8
8
|
WantedBy=multi-user.target
|
@@ -2,7 +2,7 @@
|
|
2
2
|
Description=unit file for goss server acpt endpoint service
|
3
3
|
|
4
4
|
[Service]
|
5
|
-
ExecStart=/usr/local/bin/goss -g /opt/cem_acpt/goss/puppet_idempotent.yaml serve -f json -l ":8081" --endpoint "/idempotent" --cache
|
5
|
+
ExecStart=/usr/local/bin/goss -g /opt/cem_acpt/goss/puppet_idempotent.yaml serve -f json -o pretty -l ":8081" --endpoint "/idempotent" --cache '0s'
|
6
6
|
|
7
7
|
[Install]
|
8
8
|
WantedBy=multi-user.target
|
@@ -2,7 +2,7 @@
|
|
2
2
|
Description=unit file for goss server acpt endpoint service
|
3
3
|
|
4
4
|
[Service]
|
5
|
-
ExecStart=/usr/local/bin/goss -g /opt/cem_acpt/goss/puppet_noop.yaml serve -f json -l ":8082" --endpoint "/noop" --cache
|
5
|
+
ExecStart=/usr/local/bin/goss -g /opt/cem_acpt/goss/puppet_noop.yaml serve -f json -o pretty -l ":8082" --endpoint "/noop" --cache '0s'
|
6
6
|
|
7
7
|
[Install]
|
8
8
|
WantedBy=multi-user.target
|
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.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- puppetlabs
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async-http
|
@@ -280,6 +280,7 @@ files:
|
|
280
280
|
- lib/cem_acpt/version.rb
|
281
281
|
- lib/terraform/gcp/linux/goss/puppet_idempotent.yaml
|
282
282
|
- lib/terraform/gcp/linux/goss/puppet_noop.yaml
|
283
|
+
- lib/terraform/gcp/linux/log_service/log_service.rb
|
283
284
|
- lib/terraform/gcp/linux/main.tf
|
284
285
|
- lib/terraform/gcp/linux/systemd/goss-acpt.service
|
285
286
|
- lib/terraform/gcp/linux/systemd/goss-idempotent.service
|
@@ -313,7 +314,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
313
314
|
- !ruby/object:Gem::Version
|
314
315
|
version: '0'
|
315
316
|
requirements: []
|
316
|
-
rubygems_version: 3.
|
317
|
+
rubygems_version: 3.5.18
|
317
318
|
signing_key:
|
318
319
|
specification_version: 4
|
319
320
|
summary: CEM Acceptance Tests
|