cem_acpt 0.7.1 → 0.7.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|