cem_acpt 0.7.1 → 0.7.3
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/cli.rb +14 -2
- data/lib/cem_acpt/config/base.rb +23 -2
- data/lib/cem_acpt/config/cem_acpt.rb +0 -17
- data/lib/cem_acpt/config/cem_acpt_image.rb +11 -17
- data/lib/cem_acpt/image_builder/provision_commands.rb +1 -0
- data/lib/cem_acpt/image_builder.rb +49 -11
- data/lib/cem_acpt/provision/terraform/linux.rb +17 -1
- data/lib/cem_acpt/version.rb +1 -1
- 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 +89 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 251ddea81d792241accdd3e63fb1b33ce655e458c08939f6da6a043cb2eeeeef
|
4
|
+
data.tar.gz: 7cf6e742a5375c190bba491e607b742263e40e15b82e68d1c383d9ca634e7b4f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79709f1e861e2eea1b31be633076271fefa027656dcfb8e78c252d0492286cf6376547d8756772447b28c1fe6a625cf0fee289f4a84d7e5b7e9bbfa2ef182f71
|
7
|
+
data.tar.gz: 7fc8c5351bce46273f5d57e743e1865c6d844f89fd702da451082042921cf9aae01473f90b11a3a53e810c6e2f53132de9e75d7d8d0b97c08db105c2abe172f5
|
data/Gemfile.lock
CHANGED
data/lib/cem_acpt/cli.rb
CHANGED
@@ -36,15 +36,27 @@ module CemAcpt
|
|
36
36
|
options[:tests] = t.split(',')
|
37
37
|
end
|
38
38
|
when :cem_acpt_image
|
39
|
-
opts.on('
|
39
|
+
opts.on('--dry-run', 'Logs the information for the images that would be created. Does not create images.') do
|
40
|
+
options[:dry_run] = true
|
41
|
+
end
|
42
|
+
|
43
|
+
opts.on('--no-build-images', 'Do not build images. Can be combined with --no-destroy-nodes to just provision nodes.') do
|
44
|
+
options[:no_build_images] = true
|
45
|
+
end
|
46
|
+
|
47
|
+
opts.on('--no-linux', 'Do not build Linux images') do
|
40
48
|
options[:cem_acpt_image] ||= {}
|
41
49
|
options[:cem_acpt_image][:no_linux] = true
|
42
50
|
end
|
43
51
|
|
44
|
-
opts.on('
|
52
|
+
opts.on('--no-windows', 'Do not build Windows images') do
|
45
53
|
options[:cem_acpt_image] ||= {}
|
46
54
|
options[:cem_acpt_image][:no_windows] = true
|
47
55
|
end
|
56
|
+
|
57
|
+
opts.on('-F', '--filter FILTER', 'Filter images to build by name with regex. Example: -F "(alma|rhel)-8"') do |f|
|
58
|
+
options[:image_name_filter] = Regexp.new(f)
|
59
|
+
end
|
48
60
|
end
|
49
61
|
|
50
62
|
opts.on('-D', '--debug', 'Enable debug logging') do
|
data/lib/cem_acpt/config/base.rb
CHANGED
@@ -13,8 +13,9 @@ module CemAcpt
|
|
13
13
|
using CemAcpt::CoreExt::ExtendedHash
|
14
14
|
|
15
15
|
# Base class for other config classes
|
16
|
+
# Child classes should provide the following constant:
|
17
|
+
# - VALID_KEYS - provide an array of valid top-level keys for the config as symbols
|
16
18
|
# Child classes should implement the following methods:
|
17
|
-
# - valid_keys - provide an array of valid top-level keys for the config as symbols
|
18
19
|
# - defaults - provide a hash of default values for the config
|
19
20
|
# - env_var_prefix - provide a string to prefix environment variables with (defaults to 'CEM_ACPT').
|
20
21
|
# This will be converted to uppercase, have all non-alphanumeric characters replaced with
|
@@ -22,6 +23,22 @@ module CemAcpt
|
|
22
23
|
# variable name.
|
23
24
|
# However, they can override any of the methods in this class.
|
24
25
|
class Base
|
26
|
+
BASE_VALID_KEYS = %i[
|
27
|
+
ci_mode
|
28
|
+
config_file
|
29
|
+
log_level
|
30
|
+
log_file
|
31
|
+
log_format
|
32
|
+
no_destroy_nodes
|
33
|
+
no_ephemeral_ssh_key
|
34
|
+
platform
|
35
|
+
provisioner
|
36
|
+
quiet
|
37
|
+
terraform
|
38
|
+
user_config
|
39
|
+
verbose
|
40
|
+
].freeze
|
41
|
+
|
25
42
|
attr_reader :config, :env_vars
|
26
43
|
|
27
44
|
def initialize(opts: {}, config_file: nil, load_user_config: true)
|
@@ -36,7 +53,11 @@ module CemAcpt
|
|
36
53
|
|
37
54
|
# @return [Array<Symbol>] Valid top-level keys for the config
|
38
55
|
def valid_keys
|
39
|
-
|
56
|
+
if self.class.const_defined?(:VALID_KEYS)
|
57
|
+
(BASE_VALID_KEYS + self.class.const_get(:VALID_KEYS)).uniq
|
58
|
+
else
|
59
|
+
BASE_VALID_KEYS
|
60
|
+
end
|
40
61
|
end
|
41
62
|
|
42
63
|
# @return [Hash] The default configuration
|
@@ -8,30 +8,13 @@ module CemAcpt
|
|
8
8
|
class CemAcpt < Base
|
9
9
|
VALID_KEYS = %i[
|
10
10
|
actions
|
11
|
-
ci_mode
|
12
|
-
config_file
|
13
11
|
image_name_builder
|
14
|
-
log_level
|
15
|
-
log_file
|
16
|
-
log_format
|
17
12
|
module_dir
|
18
13
|
node_data
|
19
|
-
no_destroy_nodes
|
20
|
-
no_ephemeral_ssh_key
|
21
|
-
platform
|
22
|
-
provisioner
|
23
|
-
quiet
|
24
|
-
terraform
|
25
14
|
test_data
|
26
15
|
tests
|
27
|
-
user_config
|
28
|
-
verbose
|
29
16
|
].freeze
|
30
17
|
|
31
|
-
def valid_keys
|
32
|
-
VALID_KEYS
|
33
|
-
end
|
34
|
-
|
35
18
|
# The default configuration
|
36
19
|
def defaults
|
37
20
|
{
|
@@ -7,26 +7,13 @@ module CemAcpt
|
|
7
7
|
# Holds the configuration for cem_acpt_image
|
8
8
|
class CemAcptImage < Base
|
9
9
|
VALID_KEYS = %i[
|
10
|
-
|
11
|
-
|
10
|
+
cem_acpt_image
|
11
|
+
dry_run
|
12
12
|
images
|
13
|
-
|
14
|
-
|
15
|
-
log_format
|
16
|
-
no_destroy_nodes
|
17
|
-
no_ephemeral_ssh_key
|
18
|
-
platform
|
19
|
-
provisioner
|
20
|
-
quiet
|
21
|
-
terraform
|
22
|
-
user_config
|
23
|
-
verbose
|
13
|
+
image_name_filter
|
14
|
+
no_build_images
|
24
15
|
].freeze
|
25
16
|
|
26
|
-
def valid_keys
|
27
|
-
VALID_KEYS
|
28
|
-
end
|
29
|
-
|
30
17
|
def env_var_prefix
|
31
18
|
'CEM_ACPT_IMAGE'
|
32
19
|
end
|
@@ -34,12 +21,19 @@ module CemAcpt
|
|
34
21
|
# The default configuration
|
35
22
|
def defaults
|
36
23
|
{
|
24
|
+
cem_acpt_image: {
|
25
|
+
no_linux: false,
|
26
|
+
no_windows: false,
|
27
|
+
},
|
37
28
|
ci_mode: false,
|
38
29
|
config_file: nil,
|
30
|
+
dry_run: false,
|
39
31
|
images: {},
|
32
|
+
image_name_filter: Regexp.new('.*'),
|
40
33
|
log_level: 'info',
|
41
34
|
log_file: nil,
|
42
35
|
log_format: 'text',
|
36
|
+
no_destroy_nodes: false,
|
43
37
|
no_ephemeral_ssh_key: false,
|
44
38
|
platform: {
|
45
39
|
name: 'gcp',
|
@@ -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('ImageBuilder') { "Image builder finished after #{builder.duration} seconds" }
|
22
|
+
if builder.exit_code.zero?
|
23
|
+
logger.info('ImageBuilder') { 'Image builder finished successfully' }
|
24
|
+
else
|
25
|
+
logger.error('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,7 +48,7 @@ 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
|
@@ -44,17 +56,19 @@ module CemAcpt
|
|
44
56
|
def run
|
45
57
|
@start_time = Time.now
|
46
58
|
logger.with_ci_group("CemAcptImage v#{CemAcpt::VERSION} run started at #{@start_time}") do
|
47
|
-
logger.info('CemAcptImage') { "Using working directory: #{@working_dir}..." }
|
48
|
-
keep_terminal_alive
|
49
59
|
@all_tfvars = new_tfvars(@config)
|
50
|
-
@working_dir = new_working_dir
|
51
60
|
@linux_tfvars, @windows_tfvars = divide_tfvars_by_os(@all_tfvars)
|
52
|
-
save_vars_to_file!('linux', @linux_tfvars)
|
53
|
-
save_vars_to_file!('windows', @windows_tfvars)
|
54
|
-
terraform_init
|
55
61
|
image_types = []
|
56
62
|
image_types << [@linux_tfvars, 'linux'] unless no_linux?
|
57
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('CemAcptImage') { "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
|
58
72
|
image_types.each do |tfvars, os_str|
|
59
73
|
terraform_plan(os_str, tfvars, DEFAULT_PLAN_NAME)
|
60
74
|
begin
|
@@ -63,14 +77,27 @@ module CemAcpt
|
|
63
77
|
output.each do |instance_name, data|
|
64
78
|
logger.info('CemAcptImage') { "Stopping instance #{instance_name}..." }
|
65
79
|
@exec.run('compute', 'instances', 'stop', instance_name)
|
66
|
-
|
67
|
-
|
80
|
+
unless @config.get('no_build_images')
|
81
|
+
deprecate_old_images_in_family(data['image_family'])
|
82
|
+
create_image_from_disk(data['disk_link'], image_name_from_image_family(data['image_family']), data['image_family'])
|
83
|
+
end
|
84
|
+
@exit_code = 0
|
68
85
|
end
|
69
86
|
ensure
|
70
|
-
terraform_destroy(os_str, tfvars)
|
87
|
+
terraform_destroy(os_str, tfvars) unless @config.get('no_destroy_nodes')
|
71
88
|
end
|
72
89
|
end
|
73
90
|
end
|
91
|
+
rescue StandardError => e
|
92
|
+
logger.error('CemAcptImage') { "Image builder failed with error: #{e}" }
|
93
|
+
logger.verbose('CemAcptImage') { e.backtrace.join("\n") }
|
94
|
+
@exit_code = 1
|
95
|
+
ensure
|
96
|
+
if @start_time
|
97
|
+
@duration = Time.now - @start_time
|
98
|
+
else
|
99
|
+
@duration = 0
|
100
|
+
end
|
74
101
|
end
|
75
102
|
|
76
103
|
private
|
@@ -107,6 +134,15 @@ module CemAcpt
|
|
107
134
|
@linux_tfvars[:node_data].empty? || @config.get('cem_acpt_image.no_linux')
|
108
135
|
end
|
109
136
|
|
137
|
+
def dry_run(image_types)
|
138
|
+
logger.info('CemAcptImage') { 'Dry run mode enabled. No images will be built.' }
|
139
|
+
image_types.each do |tfvars, os_str|
|
140
|
+
logger.info('CemAcptImage') { "Dry run for #{os_str}..." }
|
141
|
+
logger.info('CemAcptImage') { "Terraform vars:\n#{JSON.pretty_generate(tfvars)}" }
|
142
|
+
end
|
143
|
+
@exit_code = 0
|
144
|
+
end
|
145
|
+
|
110
146
|
def terraform
|
111
147
|
return @terraform if defined?(@terraform)
|
112
148
|
|
@@ -233,6 +269,8 @@ module CemAcpt
|
|
233
269
|
tfvars[:private_key] = private_key if private_key
|
234
270
|
tfvars[:public_key] = public_key if public_key
|
235
271
|
config.get('images').each do |image_name, image|
|
272
|
+
next if config.get('image_name_filter')&.respond_to?(:match?) && !config.get('image_name_filter').match?(image_name)
|
273
|
+
|
236
274
|
platform = new_platform(config, **tfvars)
|
237
275
|
tfvars.merge!(platform.platform_data)
|
238
276
|
provision_commands = CemAcpt::ImageBuilder::ProvisionCommands.provision_commands(
|
@@ -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?
|
57
|
+
cmd << '--verbose' if @config.verbose?
|
58
|
+
cmd << "#{destination_provision_directory}/#{puppet_manifest_file}"
|
59
|
+
cmd.join(' ')
|
44
60
|
end
|
45
61
|
end
|
46
62
|
end
|
data/lib/cem_acpt/version.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
command:
|
2
2
|
puppet_idempotent:
|
3
|
-
exec: 'sudo /opt/puppetlabs/puppet/bin/puppet apply --verbose --detailed-exitcodes /opt/cem_acpt/manifest.pp'
|
3
|
+
exec: 'sudo /opt/puppetlabs/puppet/bin/puppet apply --logdest console,/opt/cem_acpt/idempotent_apply.log --debug --verbose --detailed-exitcodes /opt/cem_acpt/manifest.pp'
|
4
4
|
timeout: 300000 # 5 mins in miliseconds
|
5
5
|
stdout:
|
6
|
-
- "Applied catalog in"
|
6
|
+
- "/Applied catalog in.*/"
|
7
7
|
stderr:
|
8
8
|
- ""
|
9
9
|
exit-status: 0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
command:
|
2
2
|
puppet_noop:
|
3
|
-
exec: 'sudo /opt/puppetlabs/puppet/bin/puppet apply --verbose --detailed-exitcodes --noop /opt/cem_acpt/manifest.pp'
|
3
|
+
exec: 'sudo /opt/puppetlabs/puppet/bin/puppet apply --logdest console,/opt/cem_acpt/noop_apply.log --debug --verbose --detailed-exitcodes --noop /opt/cem_acpt/manifest.pp'
|
4
4
|
timeout: 300000 # 5 mins in miliseconds
|
5
5
|
stdout:
|
6
6
|
- "Applied catalog in"
|
@@ -0,0 +1,12 @@
|
|
1
|
+
command:
|
2
|
+
puppet_noop:
|
3
|
+
exec: 'C:\Program Files\Puppet Labs\Puppet\bin\puppet apply --verbose --detailed-exitcodes --noop C:\cem_acpt\manifest.pp'
|
4
|
+
timeout: 300000 # 5 mins in miliseconds
|
5
|
+
stdout:
|
6
|
+
- "Applied catalog in"
|
7
|
+
stderr:
|
8
|
+
- ""
|
9
|
+
exit-status:
|
10
|
+
or:
|
11
|
+
- 0
|
12
|
+
- 2
|
@@ -0,0 +1,89 @@
|
|
1
|
+
terraform {
|
2
|
+
required_providers {
|
3
|
+
google = {
|
4
|
+
source = "hashicorp/google"
|
5
|
+
version = "4.59.0"
|
6
|
+
}
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
variable "credentials_file" {
|
11
|
+
type = string
|
12
|
+
}
|
13
|
+
|
14
|
+
variable "project" {
|
15
|
+
type = string
|
16
|
+
}
|
17
|
+
|
18
|
+
variable "region" {
|
19
|
+
type = string
|
20
|
+
}
|
21
|
+
|
22
|
+
variable "zone" {
|
23
|
+
type = string
|
24
|
+
}
|
25
|
+
|
26
|
+
variable "subnetwork" {
|
27
|
+
type = string
|
28
|
+
}
|
29
|
+
|
30
|
+
variable "node_data" {
|
31
|
+
type = map(object({
|
32
|
+
machine_type = string
|
33
|
+
image = string
|
34
|
+
disk_size = number
|
35
|
+
test_name = string
|
36
|
+
}))
|
37
|
+
}
|
38
|
+
|
39
|
+
provider "google" {
|
40
|
+
credentials = file(var.credentials_file)
|
41
|
+
project = var.project
|
42
|
+
region = var.region
|
43
|
+
zone = var.zone
|
44
|
+
}
|
45
|
+
|
46
|
+
resource "google_compute_instance" "acpt-test-node" {
|
47
|
+
provider = google
|
48
|
+
for_each = var.node_data
|
49
|
+
name = each.key
|
50
|
+
machine_type = each.value.machine_type
|
51
|
+
|
52
|
+
boot_disk {
|
53
|
+
initialize_params {
|
54
|
+
image = each.value.image
|
55
|
+
size = each.value.disk_size
|
56
|
+
type = "pd-standard"
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
scheduling {
|
61
|
+
preemptible = true
|
62
|
+
automatic_restart = false
|
63
|
+
provisioning_model = "SPOT"
|
64
|
+
instance_termination_action = "DELETE"
|
65
|
+
}
|
66
|
+
|
67
|
+
network_interface {
|
68
|
+
subnetwork = var.subnetwork
|
69
|
+
access_config {
|
70
|
+
network_tier = "STANDARD"
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
metadata = {
|
75
|
+
"enable-oslogin" = "TRUE"
|
76
|
+
"cem-acpt-test" = each.value.test_name
|
77
|
+
}
|
78
|
+
|
79
|
+
tags = [ "cem-acpt-test-node" ]
|
80
|
+
}
|
81
|
+
|
82
|
+
output "instance_name_ip" {
|
83
|
+
value = {
|
84
|
+
for k, v in google_compute_instance.acpt-test-node : v.name => {
|
85
|
+
ip = v.network_interface.0.access_config.0.nat_ip,
|
86
|
+
test_name = v.metadata.cem-acpt-test,
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
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.7.
|
4
|
+
version: 0.7.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- puppetlabs
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-07-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async-http
|
@@ -210,6 +210,9 @@ files:
|
|
210
210
|
- lib/terraform/gcp/linux/systemd/goss-idempotent.service
|
211
211
|
- lib/terraform/gcp/linux/systemd/goss-noop.service
|
212
212
|
- lib/terraform/gcp/windows/.keep
|
213
|
+
- lib/terraform/gcp/windows/goss/puppet_idempotent.yaml
|
214
|
+
- lib/terraform/gcp/windows/goss/puppet_noop.yaml
|
215
|
+
- lib/terraform/gcp/windows/main.tf
|
213
216
|
- lib/terraform/image/gcp/linux/main.tf
|
214
217
|
- lib/terraform/image/gcp/windows/.keep
|
215
218
|
- sample_config.yaml
|