simp-beaker-helpers 1.20.1 → 1.23.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.
@@ -18,6 +18,95 @@ module Simp::BeakerHelpers
18
18
  "simp-beaker-helpers-#{t}-#{$$}-#{rand(0x100000000).to_s(36)}.tmp"
19
19
  end
20
20
 
21
+ # Sets a single YUM option in the form that yum-config-manager/dnf
22
+ # config-manager would expect.
23
+ #
24
+ # If not prefaced with a repository, the option will be applied globally.
25
+ #
26
+ # Has no effect if yum or dnf is not present.
27
+ def set_yum_opt_on(suts, key, value)
28
+ parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
29
+ block_on(suts, :run_in_parallel => parallel) do |sut|
30
+ repo,target = key.split('.')
31
+
32
+ unless target
33
+ key = "\\*.#{repo}"
34
+ end
35
+
36
+ command = nil
37
+ if !sut.which('dnf').empty?
38
+ install_package_unless_present_on(sut, 'dnf-plugins-core', :accept_all_exit_codes => true)
39
+ command = 'dnf config-manager'
40
+ elsif !sut.which('yum').empty?
41
+ command = 'yum-config-manager'
42
+ end
43
+
44
+ on(sut, %{#{command} --save --setopt=#{key}=#{value}}, :silent => true) if command
45
+ end
46
+ end
47
+
48
+ # Takes a hash of YUM options to set in the form that yum-config-manager/dnf
49
+ # config-manager would expect.
50
+ #
51
+ # If not prefaced with a repository, the option will be applied globally.
52
+ #
53
+ # Example:
54
+ # {
55
+ # 'skip_if_unavailable' => '1', # Applies globally
56
+ # 'foo.installonly_limit' => '5' # Applies only to the 'foo' repo
57
+ # }
58
+ def set_yum_opts_on(suts, yum_opts={})
59
+ parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
60
+ block_on(suts, :run_in_parallel => parallel) do |sut|
61
+ yum_opts.each_pair do |k,v|
62
+ set_yum_opt_on(sut, k, v)
63
+ end
64
+ end
65
+ end
66
+
67
+ def install_package_unless_present_on(suts, package_name, package_source=nil, opts={})
68
+ default_opts = {
69
+ max_retries: 3,
70
+ retry_interval: 10
71
+ }
72
+
73
+ parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
74
+ block_on(suts, :run_in_parallel => parallel) do |sut|
75
+ package_source = package_name unless package_source
76
+
77
+ unless sut.check_for_package(package_name)
78
+ sut.install_package(
79
+ package_source,
80
+ '',
81
+ nil,
82
+ default_opts.merge(opts)
83
+ )
84
+ end
85
+ end
86
+ end
87
+
88
+ def install_latest_package_on(suts, package_name, package_source=nil, opts={})
89
+ default_opts = {
90
+ max_retries: 3,
91
+ retry_interval: 10
92
+ }
93
+
94
+ parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
95
+ block_on(suts, :run_in_parallel => parallel) do |sut|
96
+ package_source = package_name unless package_source
97
+
98
+ if sut.check_for_package(package_name)
99
+ sut.upgrade_package(
100
+ package_source,
101
+ '',
102
+ default_opts.merge(opts)
103
+ )
104
+ else
105
+ install_package_unless_present_on(sut, package_name, package_source, opts)
106
+ end
107
+ end
108
+ end
109
+
21
110
  def is_windows?(sut)
22
111
  sut[:platform] =~ /windows/i
23
112
  end
@@ -80,7 +169,35 @@ module Simp::BeakerHelpers
80
169
  else
81
170
  container_id = sut.host_hash[:docker_container_id]
82
171
  end
83
- %x(tar #{exclude_list.join(' ')} -hcf - -C "#{File.dirname(src)}" "#{File.basename(src)}" | docker exec -i "#{container_id}" tar -C "#{dest}" -xf -)
172
+
173
+ if ENV['BEAKER_docker_cmd']
174
+ docker_cmd = ENV['BEAKER_docker_cmd']
175
+ else
176
+ docker_cmd = 'docker'
177
+
178
+ if ::Docker.version['Components'].any?{|x| x['Name'] =~ /podman/i}
179
+ docker_cmd = 'podman'
180
+
181
+ if ENV['CONTAINER_HOST']
182
+ docker_cmd = 'podman --remote'
183
+ elsif ENV['DOCKER_HOST']
184
+ docker_cmd = "podman --remote --url=#{ENV['DOCKER_HOST']}"
185
+ end
186
+ end
187
+ end
188
+
189
+ sut.mkdir_p(File.dirname(dest)) unless directory_exists_on(sut, dest)
190
+
191
+ if File.file?(src)
192
+ cmd = %{#{docker_cmd} cp "#{src}" "#{container_id}:#{dest}"}
193
+ else
194
+ cmd = [
195
+ %{tar #{exclude_list.join(' ')} -hcf - -C "#{File.dirname(src)}" "#{File.basename(src)}"},
196
+ %{#{docker_cmd} exec -i "#{container_id}" tar -C "#{File.dirname(dest)}" -xf -)}
197
+ ].join(' | ')
198
+ end
199
+
200
+ %x(#{cmd})
84
201
  elsif rsync_functional_on?(sut)
85
202
  # This makes rsync_to work like beaker and scp usually do
86
203
  exclude_hack = %(__-__' -L --exclude '__-__)
@@ -116,34 +233,34 @@ module Simp::BeakerHelpers
116
233
 
117
234
  # use the `puppet fact` face to look up facts on an SUT
118
235
  def pfact_on(sut, fact_name)
119
- require 'ostruct'
120
-
236
+ found_fact = nil
121
237
  # If puppet is not installed, there are no puppet facts to fetch
122
238
  if sut.which('puppet').empty?
123
- fact_on(sut, fact_name, :silent => true)
239
+ found_fact = fact_on(sut, fact_name)
124
240
  else
125
241
  facts_json = nil
126
242
  begin
127
243
  cmd_output = on(sut, 'facter -p --json', :silent => true)
128
-
129
244
  # Facter 4+
130
245
  raise('skip facter -p') if (cmd_output.stderr =~ /no longer supported/)
131
246
 
132
- facts = JSON.parse(cmd_output.stdout, object_class: OpenStruct)
247
+ facts = JSON.parse(cmd_output.stdout)
133
248
  rescue StandardError
134
249
  # If *anything* fails, we need to fall back to `puppet facts`
135
250
 
136
251
  facts_json = on(sut, 'puppet facts find garbage_xxx', :silent => true).stdout
137
- facts = JSON.parse(facts_json, object_class: OpenStruct).values
252
+ facts = JSON.parse(facts_json)['values']
138
253
  end
139
254
 
140
255
  found_fact = facts.dig(*(fact_name.split('.')))
141
256
 
142
- # Fall back to the behavior in fact_on
143
- found_fact = '' if found_fact.nil?
144
-
145
- return found_fact
257
+ # If we did not find a fact, we should use the upstream function since
258
+ # puppet may be installed via a gem or through some other means.
259
+ found_fact = fact_on(sut, fact_name) if found_fact.nil?
146
260
  end
261
+
262
+ # Ensure that Hashes return as Hash objects
263
+ found_fact.is_a?(OpenStruct) ? found_fact.marshal_dump : found_fact
147
264
  end
148
265
 
149
266
  # Returns the modulepath on the SUT, as an Array
@@ -325,13 +442,16 @@ module Simp::BeakerHelpers
325
442
  file_exists_on(sut, '/etc/crypto-policies/config')
326
443
  end
327
444
 
328
- def munge_ssh_crypto_policies(sut, key_types=['ssh-rsa'])
329
- if has_crypto_policies(sut)
330
- on(sut, "yum update -y crypto-policies", :accept_all_exit_codes => true)
445
+ def munge_ssh_crypto_policies(suts, key_types=['ssh-rsa'])
446
+ parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
447
+ block_on(suts, :run_in_parallel => parallel) do |sut|
448
+ if has_crypto_policies(sut)
449
+ install_latest_package_on(sut, 'crypto-policies', nil, :accept_all_exit_codes => true)
331
450
 
332
- # Since we may be doing this prior to having a box flip into FIPS mode, we
333
- # need to find and modify *all* of the affected policies
334
- on( sut, %{sed --follow-symlinks -i 's/\\(HostKeyAlgorithms\\|PubkeyAcceptedKeyTypes\\)\\(.\\)/\\1\\2#{key_types.join(',')},/g' $( grep -L ssh-rsa $( find /etc/crypto-policies /usr/share/crypto-policies -type f -a \\( -name '*.txt' -o -name '*.config' \\) -exec grep -l PubkeyAcceptedKeyTypes {} \\; ) ) })
451
+ # Since we may be doing this prior to having a box flip into FIPS mode, we
452
+ # need to find and modify *all* of the affected policies
453
+ on( sut, %{sed --follow-symlinks -i 's/\\(HostKeyAlgorithms\\|PubkeyAcceptedKeyTypes\\)\\(.\\)/\\1\\2#{key_types.join(',')},/g' $( grep -L ssh-rsa $( find /etc/crypto-policies /usr/share/crypto-policies -type f -a \\( -name '*.txt' -o -name '*.config' \\) -exec grep -l PubkeyAcceptedKeyTypes {} \\; ) ) })
454
+ end
335
455
  end
336
456
  end
337
457
 
@@ -341,7 +461,10 @@ module Simp::BeakerHelpers
341
461
  puts ' -- (use BEAKER_fips=no to disable)'
342
462
  parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
343
463
 
464
+ parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
344
465
  block_on(suts, :run_in_parallel => parallel) do |sut|
466
+ next if sut[:hypervisor] == 'docker'
467
+
345
468
  if is_windows?(sut)
346
469
  puts " -- SKIPPING #{sut} because it is windows"
347
470
  next
@@ -378,13 +501,16 @@ module Simp::BeakerHelpers
378
501
 
379
502
  fips_enable_modulepath = '--modulepath=/root/.beaker_fips/modules'
380
503
 
381
- module_install_cmd = 'puppet module install simp-fips --target-dir=/root/.beaker_fips/modules'
504
+ modules_to_install = {
505
+ 'simp-fips' => ENV['BEAKER_fips_module_version'],
506
+ 'simp-crypto_policy' => nil
507
+ }
382
508
 
383
- if ENV['BEAKER_fips_module_version']
384
- module_install_cmd += " --version #{ENV['BEAKER_fips_module_version']}"
509
+ modules_to_install.each_pair do |to_install, version|
510
+ module_install_cmd = "puppet module install #{to_install} --target-dir=/root/.beaker_fips/modules"
511
+ module_install_cmd += " --version #{version}" if version
512
+ on(sut, module_install_cmd)
385
513
  end
386
-
387
- on(sut, module_install_cmd)
388
514
  end
389
515
 
390
516
  # Work around Vagrant and cipher restrictions in EL8+
@@ -490,143 +616,173 @@ module Simp::BeakerHelpers
490
616
  # Enable EPEL if appropriate to do so and the system is online
491
617
  #
492
618
  # Can be disabled by setting BEAKER_enable_epel=no
493
- def enable_epel_on(sut)
494
- if ONLINE && (ENV['BEAKER_stringify_facts'] != 'no')
495
- os_info = fact_on(sut, 'os')
496
- os_maj_rel = os_info['release']['major']
497
-
498
- # This is based on the official EPEL docs https://fedoraproject.org/wiki/EPEL
499
- if ['RedHat', 'CentOS'].include?(os_info['name'])
500
- # EL7 returns 1 if install is called and there is nothing to do
501
- yum_operation = 'install'
502
- yum_operation = 'update' if sut.check_for_package('epel-release')
503
-
504
- on(
505
- sut,
506
- %{yum #{yum_operation} -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-#{os_maj_rel}.noarch.rpm},
507
- :max_retries => 3,
508
- :retry_interval => 10
509
- )
619
+ def enable_epel_on(suts)
620
+ parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
621
+ block_on(suts, :run_in_parallel => parallel) do |sut|
622
+ if ONLINE
623
+ os_info = fact_on(sut, 'os')
624
+ os_maj_rel = os_info['release']['major']
625
+
626
+ # This is based on the official EPEL docs https://fedoraproject.org/wiki/EPEL
627
+ case os_info['name']
628
+ when 'RedHat','CentOS'
629
+ install_latest_package_on(
630
+ sut,
631
+ 'epel-release',
632
+ "https://dl.fedoraproject.org/pub/epel/epel-release-latest-#{os_maj_rel}.noarch.rpm",
633
+ )
634
+
635
+ if os_info['name'] == 'RedHat'
636
+ if os_maj_rel == '7'
637
+ on sut, %{subscription-manager repos --enable "rhel-*-optional-rpms"}
638
+ on sut, %{subscription-manager repos --enable "rhel-*-extras-rpms"}
639
+ on sut, %{subscription-manager repos --enable "rhel-ha-for-rhel-*-server-rpms"}
640
+ end
510
641
 
511
- if os_info['name'] == 'RedHat'
512
- if os_maj_rel == '7'
513
- on sut, %{subscription-manager repos --enable "rhel-*-optional-rpms"}
514
- on sut, %{subscription-manager repos --enable "rhel-*-extras-rpms"}
515
- on sut, %{subscription-manager repos --enable "rhel-ha-for-rhel-*-server-rpms"}
642
+ if os_maj_rel == '8'
643
+ on sut, %{subscription-manager repos --enable "codeready-builder-for-rhel-8-#{os_info['architecture']}-rpms"}
644
+ end
516
645
  end
517
646
 
518
- if os_maj_rel == '8'
519
- on sut, %{subscription-manager repos --enable "codeready-builder-for-rhel-8-#{os_info['architecture']}-rpms"}
647
+ if os_info['name'] == 'CentOS'
648
+ if os_maj_rel == '8'
649
+ # 8.0 fallback
650
+ install_latest_package_on(sut, 'dnf-plugins-core')
651
+ on sut, %{dnf config-manager --set-enabled powertools || dnf config-manager --set-enabled PowerTools}
652
+ end
520
653
  end
654
+ when 'OracleLinux'
655
+ package_name = "oracle-epel-release-el#{os_maj_rel}"
656
+ install_latest_package_on(sut,package_name)
521
657
  end
522
658
 
523
- if os_info['name'] == 'CentOS'
524
- if os_maj_rel == '8'
525
- # 8.0 fallback
526
- on sut, %{dnf config-manager --set-enabled powertools || dnf config-manager --set-enabled PowerTools}
527
- end
528
- end
529
659
  end
530
660
  end
531
661
  end
532
662
 
533
- def linux_errata( sut )
534
- # We need to be able to flip between server and client without issue
535
- on sut, 'puppet resource group puppet gid=52'
536
- on sut, 'puppet resource user puppet comment="Puppet" gid="52" uid="52" home="/var/lib/puppet" managehome=true'
663
+ def update_package_from_centos_stream(suts, package_name)
664
+ parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
665
+ block_on(suts, :run_in_parallel => parallel) do |sut|
666
+ sut.install_package('centos-release-stream') unless sut.check_for_package('centos-release-stream')
667
+ install_latest_package_on(sut, package_name)
668
+ sut.uninstall_package('centos-release-stream')
669
+ end
670
+ end
537
671
 
538
- # Make sure we have a domain on our host
539
- current_domain = fact_on(sut, 'domain').strip
540
- hostname = fact_on(sut, 'hostname').strip
672
+ def linux_errata( suts )
673
+ parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
674
+ block_on(suts, :run_in_parallel => parallel) do |sut|
675
+ # We need to be able to flip between server and client without issue
676
+ on sut, 'puppet resource group puppet gid=52'
677
+ on sut, 'puppet resource user puppet comment="Puppet" gid="52" uid="52" home="/var/lib/puppet" managehome=true'
541
678
 
542
- if current_domain.empty?
543
- new_fqdn = hostname + '.beaker.test'
679
+ os_info = fact_on(sut, 'os')
544
680
 
545
- on(sut, "sed -i 's/#{hostname}.*/#{new_fqdn} #{hostname}/' /etc/hosts")
546
- on(sut, "echo '#{new_fqdn}' > /etc/hostname", :accept_all_exit_codes => true)
547
- on(sut, "hostname #{new_fqdn}", :accept_all_exit_codes => true)
681
+ # Make sure we have a domain on our host
682
+ current_domain = fact_on(sut, 'domain').strip
683
+ hostname = fact_on(sut, 'hostname').strip
548
684
 
549
- if sut.file_exist?('/etc/sysconfig/network')
550
- on(sut, "sed -s '/HOSTNAME=/d' /etc/sysconfig/network")
551
- on(sut, "echo 'HOSTNAME=#{new_fqdn}' >> /etc/sysconfig/network")
552
- end
553
- end
685
+ if current_domain.empty?
686
+ new_fqdn = hostname + '.beaker.test'
554
687
 
555
- if fact_on(sut, 'domain').strip.empty?
556
- fail("Error: hosts must have an FQDN, got domain='#{current_domain}'")
557
- end
688
+ on(sut, "sed -i 's/#{hostname}.*/#{new_fqdn} #{hostname}/' /etc/hosts")
689
+ on(sut, "echo '#{new_fqdn}' > /etc/hostname", :accept_all_exit_codes => true)
690
+ on(sut, "hostname #{new_fqdn}", :accept_all_exit_codes => true)
558
691
 
559
- # This may not exist in docker so just skip the whole thing
560
- if sut.file_exist?('/etc/ssh')
561
- # SIMP uses a central ssh key location so we prep that spot in case we
562
- # flip to the SIMP SSH module.
563
- on(sut, 'mkdir -p /etc/ssh/local_keys')
564
- on(sut, 'chown -R root:root /etc/ssh/local_keys')
565
- on(sut, 'chmod 755 /etc/ssh/local_keys')
566
-
567
- user_info = on(sut, 'getent passwd').stdout.lines
568
-
569
- # Hash of user => home_dir
570
- # Exclude silly directories
571
- # * /
572
- # * /dev/*
573
- # * /s?bin
574
- # * /proc
575
- user_info = Hash[
576
- user_info.map do |u|
577
- u.strip!
578
- u = u.split(':')
579
- u[5] =~ %r{^(/|/dev/.*|/s?bin/?.*|/proc/?.*)$} ? [nil] : [u[0], u[5]]
692
+ if sut.file_exist?('/etc/sysconfig/network')
693
+ on(sut, "sed -s '/HOSTNAME=/d' /etc/sysconfig/network")
694
+ on(sut, "echo 'HOSTNAME=#{new_fqdn}' >> /etc/sysconfig/network")
580
695
  end
581
- ]
696
+ end
697
+
698
+ if fact_on(sut, 'domain').strip.empty?
699
+ fail("Error: hosts must have an FQDN, got domain='#{current_domain}'")
700
+ end
582
701
 
583
- user_info.keys.each do |user|
584
- src_file = "#{user_info[user]}/.ssh/authorized_keys"
585
- tgt_file = "/etc/ssh/local_keys/#{user}"
702
+ # This may not exist in docker so just skip the whole thing
703
+ if sut.file_exist?('/etc/ssh')
704
+ # SIMP uses a central ssh key location so we prep that spot in case we
705
+ # flip to the SIMP SSH module.
706
+ on(sut, 'mkdir -p /etc/ssh/local_keys')
707
+ on(sut, 'chown -R root:root /etc/ssh/local_keys')
708
+ on(sut, 'chmod 755 /etc/ssh/local_keys')
709
+
710
+ user_info = on(sut, 'getent passwd').stdout.lines
711
+
712
+ # Hash of user => home_dir
713
+ # Exclude silly directories
714
+ # * /
715
+ # * /dev/*
716
+ # * /s?bin
717
+ # * /proc
718
+ user_info = Hash[
719
+ user_info.map do |u|
720
+ u.strip!
721
+ u = u.split(':')
722
+ u[5] =~ %r{^(/|/dev/.*|/s?bin/?.*|/proc/?.*)$} ? [nil] : [u[0], u[5]]
723
+ end
724
+ ]
586
725
 
587
- on(sut, %{if [ -f "#{src_file}" ]; then cp -a -f "#{src_file}" "#{tgt_file}" && chmod 644 "#{tgt_file}"; fi}, :silent => true)
726
+ user_info.keys.each do |user|
727
+ src_file = "#{user_info[user]}/.ssh/authorized_keys"
728
+ tgt_file = "/etc/ssh/local_keys/#{user}"
729
+
730
+ on(sut, %{if [ -f "#{src_file}" ]; then cp -a -f "#{src_file}" "#{tgt_file}" && chmod 644 "#{tgt_file}"; fi}, :silent => true)
731
+ end
588
732
  end
589
- end
590
733
 
591
- # SIMP uses structured facts, therefore stringify_facts must be disabled
592
- unless ENV['BEAKER_stringify_facts'] == 'yes'
593
- on sut, 'puppet config set stringify_facts false'
594
- end
734
+ # SIMP uses structured facts, therefore stringify_facts must be disabled
735
+ unless ENV['BEAKER_stringify_facts'] == 'yes'
736
+ on sut, 'puppet config set stringify_facts false'
737
+ end
595
738
 
596
- # Occasionally we run across something similar to BKR-561, so to ensure we
597
- # at least have the host defaults:
598
- #
599
- # :hieradatadir is used as a canary here; it isn't the only missing key
600
- unless sut.host_hash.key? :hieradatadir
601
- configure_type_defaults_on(sut)
602
- end
739
+ # Occasionally we run across something similar to BKR-561, so to ensure we
740
+ # at least have the host defaults:
741
+ #
742
+ # :hieradatadir is used as a canary here; it isn't the only missing key
743
+ unless sut.host_hash.key? :hieradatadir
744
+ configure_type_defaults_on(sut)
745
+ end
603
746
 
604
- if fact_on(sut, 'osfamily') == 'RedHat'
605
- if fact_on(sut, 'operatingsystem') == 'RedHat'
606
- RSpec.configure do |c|
607
- c.before(:all) do
608
- rhel_rhsm_subscribe(sut)
609
- end
747
+ if os_info['family'] == 'RedHat'
748
+ # OS-specific items
749
+ if os_info['name'] == 'RedHat'
750
+ RSpec.configure do |c|
751
+ c.before(:all) do
752
+ rhel_rhsm_subscribe(sut)
753
+ end
610
754
 
611
- c.after(:all) do
612
- rhel_rhsm_unsubscribe(sut)
755
+ c.after(:all) do
756
+ rhel_rhsm_unsubscribe(sut)
757
+ end
613
758
  end
614
759
  end
615
- end
616
760
 
617
- enable_yum_repos_on(sut)
618
- enable_epel_on(sut)
761
+ if ['CentOS','RedHat','OracleLinux'].include?(os_info['name'])
762
+ enable_yum_repos_on(sut)
763
+ enable_epel_on(sut)
619
764
 
620
- # net-tools required for netstat utility being used by be_listening
621
- if fact_on(sut, 'operatingsystemmajrelease') == '7'
622
- pp = <<-EOS
623
- package { 'net-tools': ensure => installed }
624
- EOS
625
- apply_manifest_on(sut, pp, :catch_failures => false)
626
- end
765
+ # net-tools required for netstat utility being used by be_listening
766
+ if os_info['release']['major'].to_i >= 7
767
+ pp = <<-EOS
768
+ package { 'net-tools': ensure => installed }
769
+ EOS
770
+ apply_manifest_on(sut, pp, :catch_failures => false)
771
+ end
772
+
773
+ unless sut[:hypervisor] == 'docker'
774
+ if (os_info['name'] == 'CentOS') && (os_info['release']['major'].to_i >= 8)
775
+ if os_info['release']['minor'].to_i == 3
776
+ update_package_from_centos_stream(sut, 'kernel')
777
+ sut.reboot
778
+ end
779
+ end
780
+ end
627
781
 
628
- # Clean up YUM prior to starting our test runs.
629
- on(sut, 'yum clean all')
782
+ # Clean up YUM prior to starting our test runs.
783
+ on(sut, 'yum clean all')
784
+ end
785
+ end
630
786
  end
631
787
  end
632
788
 
@@ -634,85 +790,100 @@ module Simp::BeakerHelpers
634
790
  #
635
791
  # Must set BEAKER_RHSM_USER and BEAKER_RHSM_PASS environment variables or pass them in as
636
792
  # parameters
637
- def rhel_rhsm_subscribe(sut, *opts)
793
+ def rhel_rhsm_subscribe(suts, *opts)
638
794
  require 'securerandom'
639
795
 
640
- rhsm_opts = {
641
- :username => ENV['BEAKER_RHSM_USER'],
642
- :password => ENV['BEAKER_RHSM_PASS'],
643
- :system_name => "#{sut}_beaker_#{Time.now.to_i}_#{SecureRandom.uuid}",
644
- :repo_list => {
645
- '7' => [
646
- 'rhel-7-server-extras-rpms',
647
- 'rhel-7-server-optional-rpms',
648
- 'rhel-7-server-rh-common-rpms',
649
- 'rhel-7-server-rpms',
650
- 'rhel-7-server-supplementary-rpms'
651
- ],
652
- '8' => [
653
- 'rhel-8-for-x86_64-baseos-rpms',
654
- 'rhel-8-for-x86_64-supplementary-rpms'
655
- ]
796
+ parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
797
+ block_on(suts, :run_in_parallel => parallel) do |sut|
798
+ rhsm_opts = {
799
+ :username => ENV['BEAKER_RHSM_USER'],
800
+ :password => ENV['BEAKER_RHSM_PASS'],
801
+ :system_name => "#{sut}_beaker_#{Time.now.to_i}_#{SecureRandom.uuid}",
802
+ :repo_list => {
803
+ '7' => [
804
+ 'rhel-7-server-extras-rpms',
805
+ 'rhel-7-server-optional-rpms',
806
+ 'rhel-7-server-rh-common-rpms',
807
+ 'rhel-7-server-rpms',
808
+ 'rhel-7-server-supplementary-rpms'
809
+ ],
810
+ '8' => [
811
+ 'rhel-8-for-x86_64-baseos-rpms',
812
+ 'rhel-8-for-x86_64-supplementary-rpms'
813
+ ]
814
+ }
656
815
  }
657
- }
658
816
 
659
- if opts && opts.is_a?(Hash)
660
- rhsm_opts.merge!(opts)
661
- end
817
+ if opts && opts.is_a?(Hash)
818
+ rhsm_opts.merge!(opts)
819
+ end
662
820
 
663
- os = fact_on(sut, 'operatingsystem').strip
664
- os_release = fact_on(sut, 'operatingsystemmajrelease').strip
821
+ os = fact_on(sut, 'operatingsystem').strip
822
+ os_release = fact_on(sut, 'operatingsystemmajrelease').strip
665
823
 
666
- if os == 'RedHat'
667
- unless rhsm_opts[:username] && rhsm_opts[:password]
668
- fail("You must set BEAKER_RHSM_USER and BEAKER_RHSM_PASS environment variables to register RHEL systems")
669
- end
824
+ if os == 'RedHat'
825
+ unless rhsm_opts[:username] && rhsm_opts[:password]
826
+ fail("You must set BEAKER_RHSM_USER and BEAKER_RHSM_PASS environment variables to register RHEL systems")
827
+ end
670
828
 
671
- sub_status = on(sut, 'subscription-manager status', :accept_all_exit_codes => true)
672
- unless sub_status.exit_code == 0
673
- logger.info("Registering #{sut} via subscription-manager")
674
- on(sut, %{subscription-manager register --auto-attach --name='#{rhsm_opts[:system_name]}' --username='#{rhsm_opts[:username]}' --password='#{rhsm_opts[:password]}'}, :silent => true)
675
- end
829
+ sub_status = on(sut, 'subscription-manager status', :accept_all_exit_codes => true)
830
+ unless sub_status.exit_code == 0
831
+ logger.info("Registering #{sut} via subscription-manager")
832
+ on(sut, %{subscription-manager register --auto-attach --name='#{rhsm_opts[:system_name]}' --username='#{rhsm_opts[:username]}' --password='#{rhsm_opts[:password]}'}, :silent => true)
833
+ end
676
834
 
677
- if rhsm_opts[:repo_list][os_release]
678
- rhel_repo_enable(sut, rhsm_opts[:repo_list][os_release])
679
- else
680
- logger.warn("simp-beaker-helpers:#{__method__} => Default repos for RHEL '#{os_release}' not found")
681
- end
835
+ if rhsm_opts[:repo_list][os_release]
836
+ rhel_repo_enable(sut, rhsm_opts[:repo_list][os_release])
837
+ else
838
+ logger.warn("simp-beaker-helpers:#{__method__} => Default repos for RHEL '#{os_release}' not found")
839
+ end
682
840
 
683
- # Ensure that all users can access the entitlements since we don't know
684
- # who we'll be running jobs as (often not root)
685
- on(sut, 'chmod -R ugo+rX /etc/pki/entitlement', :accept_all_exit_codes => true)
841
+ # Ensure that all users can access the entitlements since we don't know
842
+ # who we'll be running jobs as (often not root)
843
+ on(sut, 'chmod -R ugo+rX /etc/pki/entitlement', :accept_all_exit_codes => true)
844
+ end
686
845
  end
687
846
  end
688
847
 
689
- def sosreport(sut, dest='sosreports')
690
- on(sut, 'puppet resource package sos ensure=latest')
691
- on(sut, 'sosreport --batch')
848
+ def sosreport(suts, dest='sosreports')
849
+ parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
850
+ block_on(suts, :run_in_parallel => parallel) do |sut|
851
+ install_latest_package_on(sut, 'sos')
852
+ on(sut, 'sosreport --batch')
692
853
 
693
- files = on(sut, 'ls /var/tmp/sosreport* /tmp/sosreport* 2>/dev/null', :accept_all_exit_codes => true).output.lines.map(&:strip)
854
+ files = on(sut, 'ls /var/tmp/sosreport* /tmp/sosreport* 2>/dev/null', :accept_all_exit_codes => true).output.lines.map(&:strip)
694
855
 
695
- FileUtils.mkdir_p(dest)
856
+ FileUtils.mkdir_p(dest)
696
857
 
697
- files.each do |file|
698
- scp_from(sut, file, File.absolute_path(dest))
858
+ files.each do |file|
859
+ scp_from(sut, file, File.absolute_path(dest))
860
+ end
699
861
  end
700
862
  end
701
863
 
702
- def rhel_repo_enable(sut, repos)
703
- Array(repos).each do |repo|
704
- on(sut, %{subscription-manager repos --enable #{repo}})
864
+ def rhel_repo_enable(suts, repos)
865
+ parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
866
+ block_on(suts, :run_in_parallel => parallel) do |sut|
867
+ Array(repos).each do |repo|
868
+ on(sut, %{subscription-manager repos --enable #{repo}})
869
+ end
705
870
  end
706
871
  end
707
872
 
708
- def rhel_repo_disable(sut, repos)
709
- Array(repos).each do |repo|
710
- on(sut, %{subscription-manager repos --disable #{repo}}, :accept_all_exit_codes => true)
873
+ def rhel_repo_disable(suts, repos)
874
+ parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
875
+ block_on(suts, :run_in_parallel => parallel) do |sut|
876
+ Array(repos).each do |repo|
877
+ on(sut, %{subscription-manager repos --disable #{repo}}, :accept_all_exit_codes => true)
878
+ end
711
879
  end
712
880
  end
713
881
 
714
- def rhel_rhsm_unsubscribe(sut)
715
- on(sut, %{subscription-manager unregister}, :accept_all_exit_codes => true)
882
+ def rhel_rhsm_unsubscribe(suts)
883
+ parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
884
+ block_on(suts, :run_in_parallel => parallel) do |sut|
885
+ on(sut, %{subscription-manager unregister}, :accept_all_exit_codes => true)
886
+ end
716
887
  end
717
888
 
718
889
  # Apply known OS fixes we need to run Beaker on each SUT
@@ -786,6 +957,9 @@ module Simp::BeakerHelpers
786
957
 
787
958
  host_entry = { fqdn => [] }
788
959
 
960
+ # Add the short name because containers can't change the hostname
961
+ host_entry[fqdn] << host.name if (host[:hypervisor] == 'docker')
962
+
789
963
  # Ensure that all interfaces are active prior to collecting data
790
964
  activate_interfaces(host) unless ENV['BEAKER_no_fix_interfaces']
791
965
 
@@ -799,7 +973,7 @@ module Simp::BeakerHelpers
799
973
  host_entry[fqdn] << ipaddress.strip
800
974
 
801
975
  unless host_entry[fqdn].empty?
802
- suts_network_info[fqdn] = host_entry[fqdn]
976
+ suts_network_info[fqdn] = host_entry[fqdn].sort.uniq
803
977
  end
804
978
  end
805
979
  end
@@ -828,6 +1002,7 @@ module Simp::BeakerHelpers
828
1002
  end
829
1003
 
830
1004
  copy_to(ca_sut, pki_hosts_file, host_dir)
1005
+
831
1006
  # generate certs
832
1007
  on(ca_sut, "cd #{host_dir}; cat #{host_dir}/pki.hosts | xargs bash make.sh")
833
1008
  end
@@ -862,8 +1037,8 @@ module Simp::BeakerHelpers
862
1037
  sut.mkdir_p("#{sut_pki_dir}/public")
863
1038
  sut.mkdir_p("#{sut_pki_dir}/private")
864
1039
  sut.mkdir_p("#{sut_pki_dir}/cacerts")
865
- copy_to(sut, "#{local_host_pki_tree}/#{fqdn}.pem", "#{sut_pki_dir}/private/")
866
- copy_to(sut, "#{local_host_pki_tree}/#{fqdn}.pub", "#{sut_pki_dir}/public/")
1040
+ copy_to(sut, "#{local_host_pki_tree}/#{fqdn}.pem", "#{sut_pki_dir}/private/")
1041
+ copy_to(sut, "#{local_host_pki_tree}/#{fqdn}.pub", "#{sut_pki_dir}/public/")
867
1042
 
868
1043
  copy_to(sut, local_cacert, "#{sut_pki_dir}/cacerts/simp_auto_ca.pem")
869
1044
 
@@ -873,18 +1048,19 @@ module Simp::BeakerHelpers
873
1048
  # Need to hash all of the CA certificates so that apps can use them
874
1049
  # properly! This must happen on the host itself since it needs to match
875
1050
  # the native hashing algorithms.
876
- hash_cmd = <<-EOM.strip
877
- cd #{sut_pki_dir}/cacerts; \
878
- for x in *; do \
879
- if [ ! -h "$x" ]; then \
880
- `openssl x509 -in $x >/dev/null 2>&1`; \
881
- if [ $? -eq 0 ]; then \
882
- hash=`openssl x509 -in $x -hash | head -1`; \
883
- ln -sf $x $hash.0; \
884
- fi; \
885
- fi; \
886
- done
887
- EOM
1051
+ hash_cmd = <<~EOM.strip
1052
+ PATH=/opt/puppetlabs/puppet/bin:$PATH; \
1053
+ cd #{sut_pki_dir}/cacerts; \
1054
+ for x in *; do \
1055
+ if [ ! -h "$x" ]; then \
1056
+ `openssl x509 -in $x >/dev/null 2>&1`; \
1057
+ if [ $? -eq 0 ]; then \
1058
+ hash=`openssl x509 -in $x -hash | head -1`; \
1059
+ ln -sf $x $hash.0; \
1060
+ fi; \
1061
+ fi; \
1062
+ done
1063
+ EOM
888
1064
 
889
1065
  on(sut, hash_cmd)
890
1066
  end
@@ -1296,64 +1472,79 @@ done
1296
1472
  # * 'simp-community-postgres'
1297
1473
  # * 'simp-community-puppet'
1298
1474
  #
1299
- def install_simp_repos(sut, disable = [])
1475
+ #
1476
+ # Environment Variables:
1477
+ # * BEAKER_SIMP_install_repos
1478
+ # * 'no' => disable the capability
1479
+ # * BEAKER_SIMP_disable_repos
1480
+ # * Comma delimited list of active yum repo names to disable
1481
+ def install_simp_repos(suts, disable = [])
1300
1482
  # NOTE: Do *NOT* use puppet in this method since it may not be available yet
1301
1483
 
1302
- # EL7 returns 1 if install is called and there is nothing to do
1303
- yum_operation = 'install'
1304
- yum_operation = 'update' if sut.check_for_package('yum-utils')
1305
-
1306
- on(
1307
- sut,
1308
- "yum -y #{yum_operation} yum-utils",
1309
- :max_retries => 3,
1310
- :retry_interval => 10
1311
- )
1312
-
1313
- # EL7 returns 1 if install is called and there is nothing to do
1314
- yum_operation = 'install'
1315
- yum_operation = 'update' if sut.check_for_package('simp-release-community')
1316
-
1317
- on(
1318
- sut,
1319
- %{yum -y #{yum_operation} "https://download.simp-project.com/simp-release-community.rpm"},
1320
- :max_retries => 3,
1321
- :retry_interval => 10
1322
- )
1323
-
1324
- to_disable = disable.dup
1325
-
1326
- unless to_disable.empty?
1327
- if to_disable.include?('simp')
1328
- to_disable.delete('simp')
1329
- to_disable << 'simp-community-simp'
1330
- end
1484
+ return if (ENV.fetch('SIMP_install_repos', 'yes') == 'no')
1331
1485
 
1332
- if to_disable.include?('simp_deps')
1333
- to_disable.delete('simp_deps')
1334
- to_disable << 'simp-community-epel'
1335
- to_disable << 'simp-community-postgres'
1336
- to_disable << 'simp-community-puppet'
1337
- end
1486
+ parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
1487
+ block_on(suts, :run_in_parallel => parallel) do |sut|
1488
+ install_package_unless_present_on(sut, 'yum-utils')
1338
1489
 
1339
- # NOTE: This --enablerepo enables the repos for listing and is inherited
1340
- # from YUM. This does not actually "enable" the repos, that would require
1341
- # the "--enable" option (from yum-config-manager) :-D.
1342
- #
1343
- # Note: Certain versions of EL8 do not dump by default and EL7 does not
1344
- # have the '--dump' option.
1345
- available_repos = on(sut, %{yum-config-manager --enablerepo="*" || yum-config-manager --enablerepo="*" --dump}).stdout.lines.grep(/\A\[(.+)\]\Z/){|x| $1}
1490
+ install_package_unless_present_on(
1491
+ sut,
1492
+ 'simp-release-community',
1493
+ "https://download.simp-project.com/simp-release-community.rpm",
1494
+ )
1346
1495
 
1347
- invalid_repos = (to_disable - available_repos)
1496
+ to_disable = disable.dup
1497
+ to_disable += ENV.fetch('BEAKER_SIMP_disable_repos', '').split(',').map(&:strip)
1348
1498
 
1349
- # Verify that the repos passed to disable are in the list of valid repos
1350
- unless invalid_repos.empty?
1351
- logger.warn(%{WARN: install_simp_repo - requested repos to disable do not exist on the target system '#{invalid_repos.join("', '")}'.})
1352
- end
1499
+ unless to_disable.empty?
1500
+ if to_disable.include?('simp')
1501
+ to_disable.delete('simp')
1502
+ to_disable << 'simp-community-simp'
1503
+ end
1504
+
1505
+ if to_disable.include?('simp_deps')
1506
+ to_disable.delete('simp_deps')
1507
+ to_disable << 'simp-community-epel'
1508
+ to_disable << 'simp-community-postgres'
1509
+ to_disable << 'simp-community-puppet'
1510
+ end
1511
+
1512
+ # NOTE: This --enablerepo enables the repos for listing and is inherited
1513
+ # from YUM. This does not actually "enable" the repos, that would require
1514
+ # the "--enable" option (from yum-config-manager) :-D.
1515
+ #
1516
+ # Note: Certain versions of EL8 do not dump by default and EL7 does not
1517
+ # have the '--dump' option.
1518
+ available_repos = on(sut, %{yum-config-manager --enablerepo="*" || yum-config-manager --enablerepo="*" --dump}).stdout.lines.grep(/\A\[(.+)\]\Z/){|x| $1}
1353
1519
 
1354
- (to_disable - invalid_repos).each do |repo|
1355
- on(sut, %{yum-config-manager --disable "#{repo}"})
1520
+ invalid_repos = (to_disable - available_repos)
1521
+
1522
+ # Verify that the repos passed to disable are in the list of valid repos
1523
+ unless invalid_repos.empty?
1524
+ logger.warn(%{WARN: install_simp_repo - requested repos to disable do not exist on the target system '#{invalid_repos.join("', '")}'.})
1525
+ end
1526
+
1527
+ (to_disable - invalid_repos).each do |repo|
1528
+ on(sut, %{yum-config-manager --disable "#{repo}"})
1529
+ end
1356
1530
  end
1357
1531
  end
1532
+
1533
+ set_yum_opts_on(suts, {'simp*.skip_if_unavailable' => '1' })
1534
+ end
1535
+
1536
+ # Set the release and release type of the SIMP yum repos
1537
+ #
1538
+ # Environment variables may be used to set either one
1539
+ # * BEAKER_SIMP_repo_release => The actual release (version number)
1540
+ # * BEAKER_SIMP_repo_release_type => The type of release (stable, unstable, rolling, etc...)
1541
+ def set_simp_repo_release(sut, simp_release_type='stable', simp_release='6')
1542
+ simp_release = ENV.fetch('BEAKER_SIMP_repo_release', simp_release)
1543
+ simp_release_type = ENV.fetch('BEAKER_SIMP_repo_release_type', simp_release_type)
1544
+
1545
+ simp_release_type = 'releases' if (simp_release_type == 'stable')
1546
+
1547
+ create_remote_file(sut, '/etc/yum/vars/simprelease', simp_release)
1548
+ create_remote_file(sut, '/etc/yum/vars/simpreleasetype', simp_release_type)
1358
1549
  end
1359
1550
  end