beaker-puppet 1.29.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +9 -0
- data/.github/workflows/release.yml +2 -2
- data/.github/workflows/test.yml +28 -7
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +842 -0
- data/CHANGELOG.md +31 -0
- data/Gemfile +5 -20
- data/Rakefile +64 -169
- data/acceptance/config/acceptance-options.rb +3 -3
- data/acceptance/config/gem/acceptance-options.rb +8 -8
- data/acceptance/config/git/acceptance-options.rb +8 -8
- data/acceptance/config/pkg/acceptance-options.rb +7 -7
- data/acceptance/pre_suite/gem/install.rb +6 -6
- data/acceptance/pre_suite/git/install.rb +22 -22
- data/acceptance/pre_suite/pkg/install.rb +3 -3
- data/acceptance/tests/backwards_compatible.rb +6 -7
- data/acceptance/tests/clone_git_repo_on_test.rb +12 -13
- data/acceptance/tests/create_tmpdir_on_test.rb +13 -9
- data/acceptance/tests/install_smoke_test.rb +5 -4
- data/acceptance/tests/stub_host.rb +11 -10
- data/acceptance/tests/web_helpers_test.rb +11 -10
- data/beaker-puppet.gemspec +16 -23
- data/bin/beaker-puppet +2 -4
- data/lib/beaker-puppet/helpers/facter_helpers.rb +9 -7
- data/lib/beaker-puppet/helpers/host_helpers.rb +10 -7
- data/lib/beaker-puppet/helpers/puppet_helpers.rb +151 -160
- data/lib/beaker-puppet/helpers/rake_helpers.rb +1 -1
- data/lib/beaker-puppet/helpers/tk_helpers.rb +22 -28
- data/lib/beaker-puppet/install_utils/aio_defaults.rb +39 -43
- data/lib/beaker-puppet/install_utils/ezbake_utils.rb +34 -42
- data/lib/beaker-puppet/install_utils/foss_defaults.rb +134 -138
- data/lib/beaker-puppet/install_utils/foss_utils.rb +293 -320
- data/lib/beaker-puppet/install_utils/module_utils.rb +58 -70
- data/lib/beaker-puppet/install_utils/puppet5.rb +30 -35
- data/lib/beaker-puppet/install_utils/puppet_utils.rb +58 -68
- data/lib/beaker-puppet/install_utils/windows_utils.rb +34 -36
- data/lib/beaker-puppet/version.rb +1 -1
- data/lib/beaker-puppet/wrappers.rb +13 -14
- data/lib/beaker-puppet.rb +4 -5
- data/setup/aio/010_Install_Puppet_Agent.rb +5 -6
- data/setup/common/000-delete-puppet-when-none.rb +2 -4
- data/setup/common/003_solaris_cert_fix.rb +74 -70
- data/setup/common/005_redhat_subscription_fix.rb +3 -2
- data/setup/common/011_Install_Puppet_Server.rb +7 -9
- data/setup/common/012_Finalize_Installs.rb +5 -5
- data/setup/common/025_StopFirewall.rb +1 -1
- data/setup/common/030_StopSssd.rb +2 -2
- data/setup/common/040_ValidateSignCert.rb +10 -12
- data/setup/common/045_EnsureMasterStarted.rb +2 -2
- data/setup/gem/010_GemInstall.rb +5 -4
- data/setup/git/000_EnvSetup.rb +48 -48
- data/setup/git/010_TestSetup.rb +13 -12
- data/setup/git/020_PuppetUserAndGroup.rb +3 -2
- data/setup/git/060_InstallModules.rb +14 -14
- data/setup/git/070_InstallCACerts.rb +82 -82
- data/spec/beaker-puppet/helpers/facter_helpers_spec.rb +22 -24
- data/spec/beaker-puppet/helpers/host_helpers_spec.rb +10 -6
- data/spec/beaker-puppet/helpers/puppet_helpers_spec.rb +506 -517
- data/spec/beaker-puppet/helpers/tk_helpers_spec.rb +20 -24
- data/spec/beaker-puppet/install_utils/ezbake_utils_spec.rb +86 -90
- data/spec/beaker-puppet/install_utils/foss_utils_spec.rb +636 -599
- data/spec/beaker-puppet/install_utils/module_utils_spec.rb +125 -116
- data/spec/beaker-puppet/install_utils/puppet5_spec.rb +159 -165
- data/spec/beaker-puppet/install_utils/puppet_utils_spec.rb +92 -77
- data/spec/beaker-puppet/install_utils/windows_utils_spec.rb +101 -89
- data/spec/beaker-puppet/wrappers_spec.rb +10 -10
- data/spec/helpers.rb +85 -91
- data/tasks/ci.rake +171 -179
- metadata +33 -62
- data/setup/common/020_InstallCumulusModules.rb +0 -13
- data/setup/common/021_InstallAristaModuleMasters.rb +0 -12
- data/setup/common/022_InstallAristaModuleAgents.rb +0 -13
@@ -1,84 +1,87 @@
|
|
1
1
|
test_name 'Add digicert to solaris keystore'
|
2
2
|
|
3
3
|
# Only need to run this on soliars 11, 11.2, and sparc
|
4
|
-
skip_test 'No solaris 11 version that needed keystore updating'
|
4
|
+
skip_test 'No solaris 11 version that needed keystore updating' unless hosts.any? do |host|
|
5
|
+
host.platform =~ /solaris-11(\.2)?-(i386|sparc)/
|
6
|
+
end
|
5
7
|
|
6
|
-
DigiCert =
|
7
|
-
-----BEGIN CERTIFICATE-----
|
8
|
-
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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-
hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
|
27
|
-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
-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
-
+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
-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
-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
-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
-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
-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
-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
-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
-
gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
|
38
|
-
-----END CERTIFICATE-----
|
8
|
+
DigiCert = <<~EOM
|
9
|
+
-----BEGIN CERTIFICATE-----
|
10
|
+
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
|
40
|
+
-----END CERTIFICATE-----
|
39
41
|
EOM
|
40
42
|
|
41
|
-
USERTrust =
|
42
|
-
-----BEGIN CERTIFICATE-----
|
43
|
-
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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-
+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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-
J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw
|
68
|
-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
|
69
|
-
Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9
|
70
|
-
-----END CERTIFICATE-----
|
43
|
+
USERTrust = <<~EOM
|
44
|
+
-----BEGIN CERTIFICATE-----
|
45
|
+
MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE
|
46
|
+
BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK
|
47
|
+
ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh
|
48
|
+
dGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE
|
49
|
+
BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK
|
50
|
+
ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh
|
51
|
+
dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz
|
52
|
+
0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j
|
53
|
+
Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn
|
54
|
+
RghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O
|
55
|
+
+T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq
|
56
|
+
/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE
|
57
|
+
Y1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM
|
58
|
+
lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8
|
59
|
+
yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+
|
60
|
+
eLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
|
61
|
+
BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
|
62
|
+
MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW
|
63
|
+
FPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ
|
64
|
+
7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ
|
65
|
+
Eg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM
|
66
|
+
8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi
|
67
|
+
FSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi
|
68
|
+
yA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c
|
69
|
+
J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw
|
70
|
+
sAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx
|
71
|
+
Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9
|
72
|
+
-----END CERTIFICATE-----
|
71
73
|
EOM
|
72
74
|
|
73
75
|
hosts.each do |host|
|
74
|
-
next unless host.platform =~ /solaris-11(\.2)?-(i386|sparc)/
|
75
|
-
|
76
|
+
next unless host.platform =~ /solaris-11(\.2)?-(i386|sparc)/
|
77
|
+
|
78
|
+
create_remote_file(host, 'DigiCert_Trusted_Root_G4.pem', DigiCert)
|
76
79
|
on(host, 'chmod a+r /root/DigiCert_Trusted_Root_G4.pem')
|
77
80
|
on(host, 'cp -p /root/DigiCert_Trusted_Root_G4.pem /etc/certs/CA/')
|
78
81
|
on(host, 'rm /root/DigiCert_Trusted_Root_G4.pem')
|
79
82
|
|
80
|
-
if host.platform=~ /solaris-11-sparc/
|
81
|
-
create_remote_file(host,
|
83
|
+
if host.platform =~ /solaris-11-sparc/
|
84
|
+
create_remote_file(host, 'USERTrust_RSA_Certification_Authority.pem', USERTrust)
|
82
85
|
on(host, 'chmod a+r /root/USERTrust_RSA_Certification_Authority.pem')
|
83
86
|
on(host, 'cp -p /root/USERTrust_RSA_Certification_Authority.pem /etc/certs/CA/')
|
84
87
|
on(host, 'rm /root/USERTrust_RSA_Certification_Authority.pem')
|
@@ -87,9 +90,10 @@ hosts.each do |host|
|
|
87
90
|
on(host, '/usr/sbin/svcadm restart /system/ca-certificates')
|
88
91
|
timeout = 60
|
89
92
|
counter = 0
|
90
|
-
while on(host, 'svcs -x ca-certificates').output !~ /State: online/
|
93
|
+
while on(host, 'svcs -x ca-certificates').output !~ /State: online/
|
91
94
|
raise 'ca-certificates services failed start up' if counter > timeout
|
95
|
+
|
92
96
|
sleep 5
|
93
|
-
counter
|
97
|
+
counter += 5
|
94
98
|
end
|
95
99
|
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
test_name 'Refresh Red Hat 8 subscription repository'
|
2
2
|
|
3
3
|
# Only need to run this on Red Hat Enterprise Linux 8 on little-endian PowerPC
|
4
|
-
skip_test 'Not Red Hat 8 PPCle'
|
4
|
+
skip_test 'Not Red Hat 8 PPCle' unless hosts.any? { |host| host.platform == 'el-8-ppc64le' }
|
5
5
|
|
6
6
|
hosts.each do |host|
|
7
7
|
next unless host.platform == 'el-8-ppc64le'
|
8
8
|
|
9
|
-
on(host,
|
9
|
+
on(host,
|
10
|
+
'/usr/sbin/subscription-manager repos --disable rhel-8-for-ppc64le-baseos-rpms && /usr/sbin/subscription-manager repos --enable rhel-8-for-ppc64le-baseos-rpms')
|
10
11
|
end
|
@@ -1,13 +1,11 @@
|
|
1
|
-
test_name
|
2
|
-
skip_test
|
1
|
+
test_name 'Install Puppet Server' do
|
2
|
+
skip_test 'not testing with puppetserver' unless @options['is_puppetserver']
|
3
3
|
|
4
4
|
opts = {
|
5
|
-
:
|
6
|
-
:
|
7
|
-
:
|
8
|
-
:
|
5
|
+
version: ENV.fetch('SERVER_VERSION', nil),
|
6
|
+
release_stream: ENV.fetch('RELEASE_STREAM', nil),
|
7
|
+
nightly_builds_url: ENV.fetch('NIGHTLY_BUILDS_URL', nil),
|
8
|
+
dev_builds_url: ENV.fetch('DEV_BUILDS_URL', nil),
|
9
9
|
}
|
10
|
-
unless master['use_existing_container']
|
11
|
-
install_puppetserver_on(master, opts)
|
12
|
-
end
|
10
|
+
install_puppetserver_on(master, opts) unless master['use_existing_container']
|
13
11
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
test_name
|
1
|
+
test_name 'Finalize Host Installation'
|
2
2
|
|
3
|
-
step
|
3
|
+
step 'Verify host times' do
|
4
4
|
# Get a rough estimate of clock skew among hosts
|
5
5
|
times = []
|
6
6
|
hosts.each do |host|
|
@@ -10,16 +10,16 @@ step "Verify host times" do
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
times.map! do |time|
|
13
|
-
(Time.strptime(time,
|
13
|
+
(Time.strptime(time, '%Y-%m-%d %T.%L %z').to_f * 1000.0).to_i
|
14
14
|
end
|
15
15
|
diff = times.max - times.min
|
16
|
-
if diff <
|
16
|
+
if diff < 60_000
|
17
17
|
logger.info "Host times vary #{diff} ms"
|
18
18
|
else
|
19
19
|
logger.warn "Host times vary #{diff} ms, tests may fail"
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
step
|
23
|
+
step 'Configure gem mirror' do
|
24
24
|
configure_gem_mirror(hosts)
|
25
25
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
test_name
|
1
|
+
test_name 'Stop sssd' do
|
2
2
|
# The sssd service causes local users/groups to be cached,
|
3
3
|
# which can cause unexpected results when tests are trying
|
4
4
|
# to restore state. We ensure that it is not running to
|
5
5
|
# prevent such caching from occurring.
|
6
6
|
hosts.each do |host|
|
7
|
-
on(host, puppet('resource', 'service', 'sssd', 'ensure=stopped'), :
|
7
|
+
on(host, puppet('resource', 'service', 'sssd', 'ensure=stopped'), accept_all_exit_codes: true)
|
8
8
|
end
|
9
9
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
test_name
|
1
|
+
test_name 'Validate Sign Cert' do
|
2
2
|
need_to_run = false
|
3
3
|
hosts.each do |host|
|
4
4
|
need_to_run ||= !host['use_existing_container']
|
@@ -7,17 +7,17 @@ test_name "Validate Sign Cert" do
|
|
7
7
|
skip_test 'not testing with puppetserver' unless @options['is_puppetserver']
|
8
8
|
hostname = on(master, 'facter hostname').stdout.strip
|
9
9
|
fqdn = on(master, 'facter fqdn').stdout.strip
|
10
|
-
puppet_version = on(master, puppet(
|
10
|
+
puppet_version = on(master, puppet('--version')).stdout.chomp
|
11
11
|
|
12
12
|
if master.use_service_scripts?
|
13
|
-
step
|
13
|
+
step 'Ensure puppet is stopped'
|
14
14
|
# Passenger, in particular, must be shutdown for the cert setup steps to work,
|
15
15
|
# but any running puppet master will interfere with webrick starting up and
|
16
16
|
# potentially ignore the puppet.conf changes.
|
17
|
-
on(master, puppet('resource', 'service', master['puppetservice'],
|
17
|
+
on(master, puppet('resource', 'service', master['puppetservice'], 'ensure=stopped'))
|
18
18
|
end
|
19
19
|
|
20
|
-
step
|
20
|
+
step 'Clear SSL on all hosts'
|
21
21
|
hosts.each do |host|
|
22
22
|
ssldir = on(host, puppet('agent --configprint ssldir')).stdout.chomp
|
23
23
|
# preserve permissions for master's ssldir so puppetserver can read it
|
@@ -29,22 +29,20 @@ test_name "Validate Sign Cert" do
|
|
29
29
|
on(host, puppet("config set server #{master.hostname} --section main"))
|
30
30
|
end
|
31
31
|
|
32
|
-
step
|
32
|
+
step 'Start puppetserver' do
|
33
33
|
master_opts = {
|
34
34
|
main: {
|
35
35
|
dns_alt_names: "puppet,#{hostname},#{fqdn}",
|
36
36
|
server: fqdn,
|
37
|
-
autosign: true
|
37
|
+
autosign: true,
|
38
38
|
},
|
39
39
|
}
|
40
40
|
|
41
41
|
# In Puppet 6, we want to be using an intermediate CA
|
42
|
-
|
43
|
-
on master, 'puppetserver ca setup' unless master['use_existing_container']
|
44
|
-
end
|
42
|
+
on master, 'puppetserver ca setup' if !version_is_less(puppet_version, '5.99') && !master['use_existing_container']
|
45
43
|
with_puppet_running_on(master, master_opts) do
|
46
|
-
step
|
47
|
-
on agents, puppet(
|
44
|
+
step 'Agents: Run agent --test with autosigning enabled to get cert'
|
45
|
+
on agents, puppet('agent --test'), acceptable_exit_codes: [0, 2]
|
48
46
|
end
|
49
47
|
end
|
50
48
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
test_name
|
1
|
+
test_name 'Ensure the master is running'
|
2
2
|
skip_test 'not testing with puppetserver' unless @options['is_puppetserver']
|
3
3
|
|
4
|
-
on(master, puppet('resource', 'service', master['puppetservice'],
|
4
|
+
on(master, puppet('resource', 'service', master['puppetservice'], 'ensure=running', 'enable=true'))
|
data/setup/gem/010_GemInstall.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
test_name
|
1
|
+
test_name 'Install puppet gem'
|
2
2
|
|
3
3
|
agents.each do |agent|
|
4
|
-
sha = ENV
|
4
|
+
sha = ENV.fetch('SHA', nil)
|
5
5
|
base_url = "http://builds.delivery.puppetlabs.net/puppet/#{sha}/artifacts"
|
6
6
|
|
7
7
|
ruby_command = ruby_command(agent)
|
@@ -10,7 +10,8 @@ agents.each do |agent|
|
|
10
10
|
# retrieve the build data, since the gem version is based on the short git
|
11
11
|
# describe, not the full git SHA
|
12
12
|
on(agent, "curl -s -o build_data.yaml #{base_url}/#{sha}.yaml")
|
13
|
-
gem_version = on(agent,
|
13
|
+
gem_version = on(agent,
|
14
|
+
"#{ruby_command} -ryaml -e 'puts YAML.load_file(\"build_data.yaml\")[:gemversion]'").stdout.chomp
|
14
15
|
|
15
16
|
if agent['platform'] =~ /windows/
|
16
17
|
# wipe existing gems first
|
@@ -27,7 +28,7 @@ agents.each do |agent|
|
|
27
28
|
step "Download puppet gem from #{url}"
|
28
29
|
on(agent, "curl -s -o puppet.gem #{url}")
|
29
30
|
|
30
|
-
step
|
31
|
+
step 'Install puppet.gem'
|
31
32
|
on(agent, "#{gem_command} install puppet.gem")
|
32
33
|
|
33
34
|
step "Verify it's sane"
|
data/setup/git/000_EnvSetup.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
test_name
|
1
|
+
test_name 'Setup environment'
|
2
2
|
|
3
3
|
require 'json'
|
4
4
|
require 'open-uri'
|
@@ -8,19 +8,19 @@ step 'Configure paths' do
|
|
8
8
|
add_puppet_paths_on(hosts)
|
9
9
|
end
|
10
10
|
|
11
|
-
step
|
11
|
+
step 'Install git and tar'
|
12
12
|
PACKAGES = {
|
13
|
-
:
|
14
|
-
:
|
15
|
-
[
|
13
|
+
redhat: ['git'],
|
14
|
+
debian: [
|
15
|
+
%w[git git-core],
|
16
16
|
],
|
17
|
-
:
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
solaris_10: %w[
|
18
|
+
coreutils
|
19
|
+
git
|
20
|
+
gtar
|
21
21
|
],
|
22
|
-
:
|
23
|
-
:
|
22
|
+
windows: ['git'],
|
23
|
+
sles: ['git'],
|
24
24
|
}
|
25
25
|
|
26
26
|
# We need to be able override which tar we use on solaris, which we call later
|
@@ -38,28 +38,28 @@ agents.each do |host|
|
|
38
38
|
# solaris 11 using pkg by default, we can't use that method for sol11.
|
39
39
|
# We have to override it so that we can get git from opencws, as it has
|
40
40
|
# the updated ssl certs we need to access github repos.
|
41
|
-
create_remote_file host,
|
42
|
-
mail=
|
43
|
-
# Overwrite already installed instances
|
44
|
-
instance=overwrite
|
45
|
-
# Do not bother checking for partially installed packages
|
46
|
-
partial=nocheck
|
47
|
-
# Do not bother checking the runlevel
|
48
|
-
runlevel=nocheck
|
49
|
-
# Do not bother checking package dependencies (We take care of this)
|
50
|
-
idepend=nocheck
|
51
|
-
rdepend=nocheck
|
52
|
-
# DO check for available free space and abort if there isn't enough
|
53
|
-
space=quit
|
54
|
-
# Do not check for setuid files.
|
55
|
-
setuid=nocheck
|
56
|
-
# Do not check if files conflict with other packages
|
57
|
-
conflict=nocheck
|
58
|
-
# We have no action scripts. Do not check for them.
|
59
|
-
action=nocheck
|
60
|
-
# Install to the default base directory.
|
61
|
-
basedir=default
|
62
|
-
|
41
|
+
create_remote_file host, '/root/shutupsolaris', <<~END
|
42
|
+
mail=
|
43
|
+
# Overwrite already installed instances
|
44
|
+
instance=overwrite
|
45
|
+
# Do not bother checking for partially installed packages
|
46
|
+
partial=nocheck
|
47
|
+
# Do not bother checking the runlevel
|
48
|
+
runlevel=nocheck
|
49
|
+
# Do not bother checking package dependencies (We take care of this)
|
50
|
+
idepend=nocheck
|
51
|
+
rdepend=nocheck
|
52
|
+
# DO check for available free space and abort if there isn't enough
|
53
|
+
space=quit
|
54
|
+
# Do not check for setuid files.
|
55
|
+
setuid=nocheck
|
56
|
+
# Do not check if files conflict with other packages
|
57
|
+
conflict=nocheck
|
58
|
+
# We have no action scripts. Do not check for them.
|
59
|
+
action=nocheck
|
60
|
+
# Install to the default base directory.
|
61
|
+
basedir=default
|
62
|
+
END
|
63
63
|
on host, 'pkgadd -d http://get.opencsw.org/now -a /root/shutupsolaris -n all'
|
64
64
|
on host, '/opt/csw/bin/pkgutil -U all'
|
65
65
|
on host, '/opt/csw/bin/pkgutil -y -i git'
|
@@ -69,9 +69,9 @@ basedir=default
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
install_packages_on(agents, PACKAGES, :
|
72
|
+
install_packages_on(agents, PACKAGES, check_if_exists: true)
|
73
73
|
|
74
|
-
step
|
74
|
+
step 'Unpack puppet-runtime' do
|
75
75
|
need_to_run = false
|
76
76
|
agents.each do |host|
|
77
77
|
# we only need to unpack the runtime if the host doesn't already have runtime
|
@@ -92,7 +92,7 @@ step "Unpack puppet-runtime" do
|
|
92
92
|
runtime_url = "#{dev_builds_url}/puppet-runtime/#{runtime_tag}/artifacts/"
|
93
93
|
|
94
94
|
runtime_prefix = "agent-runtime-#{branch}-#{runtime_tag}."
|
95
|
-
runtime_suffix =
|
95
|
+
runtime_suffix = '.tar.gz'
|
96
96
|
|
97
97
|
agents.each do |host|
|
98
98
|
next if host['has_runtime'] || host['use_existing_container']
|
@@ -113,16 +113,16 @@ step "Unpack puppet-runtime" do
|
|
113
113
|
when /windows/
|
114
114
|
on host, "gunzip -c #{tarball_name} | tar -k -C /cygdrive/c/ -xf -"
|
115
115
|
|
116
|
-
if arch == 'x64'
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
if branch == '5.5.x'
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
116
|
+
program_files = if arch == 'x64'
|
117
|
+
'ProgramFiles64Folder'
|
118
|
+
else
|
119
|
+
'ProgramFilesFolder'
|
120
|
+
end
|
121
|
+
bindir = if branch == '5.5.x'
|
122
|
+
"/cygdrive/c/#{program_files}/PuppetLabs/Puppet/sys/ruby/bin"
|
123
|
+
else
|
124
|
+
"/cygdrive/c/#{program_files}/PuppetLabs/Puppet/puppet/bin"
|
125
|
+
end
|
126
126
|
on host, "chmod 755 #{bindir}/*"
|
127
127
|
|
128
128
|
# Because the runtime archive for windows gets installed in a non-standard
|
@@ -132,7 +132,7 @@ step "Unpack puppet-runtime" do
|
|
132
132
|
host.add_env_var('PATH', bindir)
|
133
133
|
when /osx/
|
134
134
|
on host, "tar -xzf #{tarball_name}"
|
135
|
-
on host,
|
135
|
+
on host, 'for d in opt var private; do rsync -ka "${d}/" "/${d}/"; done'
|
136
136
|
else
|
137
137
|
on host, "gunzip -c #{tarball_name} | #{tar} -k -C / -xf -"
|
138
138
|
end
|
@@ -140,7 +140,7 @@ step "Unpack puppet-runtime" do
|
|
140
140
|
end
|
141
141
|
end
|
142
142
|
|
143
|
-
step
|
143
|
+
step 'Install bundler' do
|
144
144
|
# Only configure gem mirror after Ruby has been installed, but before any gems are installed.
|
145
145
|
configure_gem_mirror(agents)
|
146
146
|
|
data/setup/git/010_TestSetup.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
test_name
|
2
|
-
|
1
|
+
test_name 'Install repositories on target machines...' do
|
3
2
|
repositories = options[:install].map do |url|
|
4
3
|
extract_repo_info_from(build_git_url(url))
|
5
4
|
end
|
@@ -29,20 +28,20 @@ test_name "Install repositories on target machines..." do
|
|
29
28
|
repo_dir = host.tmpdir(repository[:name])
|
30
29
|
on(host, "chmod 755 #{repo_dir}")
|
31
30
|
|
32
|
-
gem_source = ENV[
|
31
|
+
gem_source = ENV['GEM_SOURCE'] || 'https://rubygems.org'
|
33
32
|
|
34
33
|
case repository[:path]
|
35
34
|
when /^(git:|https:|git@)/
|
36
35
|
sha = ENV['SHA'] || `git rev-parse HEAD`.chomp
|
37
36
|
gem_path = ":git => '#{repository[:path]}', :ref => '#{sha}'"
|
38
|
-
when
|
39
|
-
gem_path = ":path => '#{
|
37
|
+
when %r{^file://(.*)}
|
38
|
+
gem_path = ":path => '#{Regexp.last_match(1)}'"
|
40
39
|
else
|
41
40
|
gem_path = repository[:path]
|
42
41
|
end
|
43
|
-
create_remote_file(host, "#{repo_dir}/Gemfile",
|
44
|
-
source '#{gem_source}'
|
45
|
-
gem '#{repository[:name]}', #{gem_path}
|
42
|
+
create_remote_file(host, "#{repo_dir}/Gemfile", <<~END)
|
43
|
+
source '#{gem_source}'
|
44
|
+
gem '#{repository[:name]}', #{gem_path}
|
46
45
|
END
|
47
46
|
|
48
47
|
case host['platform']
|
@@ -50,7 +49,7 @@ gem '#{repository[:name]}', #{gem_path}
|
|
50
49
|
# bundle must be passed a Windows style path for a binstubs location
|
51
50
|
bindir = host['puppetbindir'].split(':').first
|
52
51
|
binstubs_dir = on(host, "cygpath -m \"#{bindir}\"").stdout.chomp
|
53
|
-
#
|
52
|
+
# NOTE: passing --shebang to bundle is not useful because Cygwin
|
54
53
|
# already finds the Ruby interpreter OK with the standard shebang of:
|
55
54
|
# !/usr/bin/env ruby
|
56
55
|
# the problem is a Cygwin style path is passed to the interpreter and this can't be modified:
|
@@ -61,16 +60,18 @@ gem '#{repository[:name]}', #{gem_path}
|
|
61
60
|
# so we have to manually copy the batch files over
|
62
61
|
gemdir = on(host, "#{gem_command(host)} environment gemdir").stdout.chomp
|
63
62
|
gembindir = File.join(gemdir, 'bin')
|
64
|
-
on host,
|
63
|
+
on host,
|
64
|
+
"cd '#{host['puppetbindir']}' && test -f ./#{repository[:name]}.bat || cp '#{gembindir}/#{repository[:name]}.bat' '#{host['puppetbindir']}/#{repository[:name]}.bat'"
|
65
65
|
else
|
66
66
|
on host, "cd #{repo_dir} && #{bundle_command(host)} install --system --binstubs #{host['puppetbindir']}"
|
67
67
|
end
|
68
|
-
puppet_bundler_install_dir ||= on(host,
|
68
|
+
puppet_bundler_install_dir ||= on(host,
|
69
|
+
"cd #{repo_dir} && #{bundle_command(host)} show #{repository[:name]}").stdout.chomp
|
69
70
|
host.add_env_var('RUBYLIB', File.join(puppet_bundler_install_dir, 'lib'))
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|
73
|
-
step
|
74
|
+
step 'Hosts: create environments directory like AIO does' do
|
74
75
|
agents.each do |host|
|
75
76
|
codedir = host.puppet['codedir']
|
76
77
|
on host, "mkdir -p #{codedir}/environments/production/manifests"
|
@@ -1,8 +1,9 @@
|
|
1
1
|
test_name 'Puppet User and Group' do
|
2
2
|
hosts.each do |host|
|
3
3
|
next if host['use_existing_container']
|
4
|
-
|
5
|
-
|
4
|
+
|
5
|
+
step 'ensure puppet user and group added to all nodes because this is what the packages do' do
|
6
|
+
on host, puppet('resource user puppet ensure=present')
|
6
7
|
end
|
7
8
|
end
|
8
9
|
end
|