-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add an bootc-image-builder test and a related podman library
Signed-off-by: Jiri Jaburek <[email protected]>
- Loading branch information
Showing
4 changed files
with
249 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
summary: Runs bootc-image-builder remediation and scan inside VMs | ||
test: python3 -m lib.runtest ./test.py | ||
result: custom | ||
environment+: | ||
PYTHONPATH: ../../.. | ||
duration: 1h | ||
require+: | ||
# virt library dependencies | ||
- libvirt-daemon | ||
- libvirt-daemon-driver-qemu | ||
- libvirt-daemon-driver-storage-core | ||
- libvirt-daemon-driver-network | ||
- firewalld | ||
- qemu-kvm | ||
- libvirt-client | ||
- virt-install | ||
- rpm-build | ||
- createrepo | ||
# podman library dependencies | ||
- podman | ||
extra-hardware: | | ||
keyvalue = HVM=1 | ||
hostrequire = memory>=3720 | ||
adjust: | ||
- when: arch != x86_64 | ||
enabled: false | ||
because: we want to run virtualization on x86_64 only | ||
- when: distro ~< rhel-8.10 or distro ~< rhel-9.5 | ||
enabled: false | ||
because: TODO - what is bootc supported on? | ||
|
||
/anssi_bp28_high: | ||
|
||
/anssi_bp28_enhanced: | ||
tag+: | ||
- subset-profile | ||
|
||
/anssi_bp28_intermediary: | ||
tag+: | ||
- subset-profile | ||
|
||
/anssi_bp28_minimal: | ||
tag+: | ||
- subset-profile | ||
|
||
/cis: | ||
|
||
/cis_server_l1: | ||
tag+: | ||
- subset-profile | ||
|
||
/cis_workstation_l2: | ||
|
||
/cis_workstation_l1: | ||
tag+: | ||
- subset-profile | ||
|
||
/cui: | ||
adjust+: | ||
- when: distro >= rhel-10 | ||
enabled: false | ||
because: there is no CUI profile on RHEL-10+ | ||
|
||
/e8: | ||
|
||
/hipaa: | ||
|
||
/ism_o: | ||
|
||
/ospp: | ||
adjust+: | ||
- when: distro >= rhel-10 | ||
enabled: false | ||
because: there is no OSPP profile on RHEL-10+ | ||
|
||
/pci-dss: | ||
|
||
/stig: | ||
|
||
/stig_gui: | ||
adjust+: | ||
- enabled: false | ||
because: not supported without GUI, use stig instead | ||
|
||
/ccn_advanced: | ||
adjust+: | ||
- when: distro == rhel-8 or distro == rhel-10 | ||
enabled: false | ||
because: CCN profiles are not present on RHEL-8 and on RHEL-10 | ||
|
||
/ccn_intermediate: | ||
tag+: | ||
- subset-profile | ||
adjust+: | ||
- when: distro == rhel-8 or distro == rhel-10 | ||
enabled: false | ||
because: CCN profiles are not present on RHEL-8 and on RHEL-10 | ||
|
||
/ccn_basic: | ||
tag+: | ||
- subset-profile | ||
adjust+: | ||
- when: distro == rhel-8 or distro == rhel-10 | ||
enabled: false | ||
because: CCN profiles are not present on RHEL-8 and on RHEL-10 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
#!/usr/bin/python3 | ||
|
||
#import contextlib | ||
import shutil | ||
from pathlib import Path | ||
|
||
from lib import results, oscap, osbuild, virt, podman, util | ||
from conf import remediation | ||
|
||
# | ||
# TODO: specify --root and --storage-opt for all podman commands, | ||
# have ie. /var/lib/containers/contest-storage to not conflict | ||
# with other images (image names) that might be on the system | ||
# while having a storage share-able across tests | ||
# | ||
|
||
#podman.Host.setup() | ||
virt.Host.setup() | ||
|
||
_, variant, profile = util.get_test_name().rsplit('/', 2) | ||
|
||
oscap.unselect_rules(util.get_datastream(), 'remediation-ds.xml', remediation.excludes()) | ||
|
||
|
||
pull_images = [ | ||
'quay.io/centos-bootc/centos-bootc:stream9', | ||
'quay.io/centos-bootc/bootc-image-builder:latest', | ||
] | ||
for img in pull_images: | ||
# --quiet because screen-redrawing progress bars don't work well with logs | ||
podman.podman('image', 'pull', '--quiet', img) | ||
|
||
|
||
# TODO: Containerfile, needs 'podman' module support for 'class Repository' | ||
# using a locally-hosted HTTP server | ||
# TODO: probably use localhost/ for pulled images ? | ||
containerfile_text = util.dedent(fr''' | ||
FROM quay.io/centos-bootc/centos-bootc:stream9 | ||
RUN ["dnf", "-y", "install", "dnf-plugins-core"] | ||
RUN ["dnf", "-y", "copr", "enable", "packit/OpenSCAP-openscap-2170", "centos-stream-9-x86_64"] | ||
RUN ["dnf", "-y", "install", "openscap-utils"] | ||
COPY remediation-ds.xml /root/. | ||
RUN ["oscap-bootc", "--profile", "{profile}", "/root/remediation-ds.xml"] | ||
''') | ||
|
||
Path('Containerfile').write_text(containerfile_text) | ||
podman.podman('image', 'build', '--tag', 'bootc-centos-openscap', '.') | ||
|
||
|
||
guest = virt.Guest() | ||
guest.wipe() | ||
guest.generate_ssh_keypair() | ||
|
||
# TODO: probably move this to class Containerfile, managed by the 'podman' module, | ||
# so sshkey insertion is generic across all container-based workflows | ||
blueprint = osbuild.Blueprint(template='') | ||
blueprint.add_user('root', password=virt.GUEST_LOGIN_PASS, ssh_pubkey=guest.ssh_pubkey) | ||
|
||
#c = podman.Container('quay.io/centos-bootc/bootc-image-builder:latest') | ||
|
||
|
||
bootc_output_dir = Path(virt.GUEST_IMG_DIR) / 'bootc-image-builder-output' | ||
if bootc_output_dir.exists(): | ||
shutil.rmtree(bootc_output_dir) | ||
bootc_output_dir.mkdir(parents=True) | ||
|
||
#with contextlib.ExitStack() as stack: | ||
#with tempfile.NamedTemporaryFile(mode='w', suffix='.toml') as config_toml: | ||
# Path(config_toml).write_text(blueprint | ||
|
||
with blueprint.to_tmpfile() as config_toml: | ||
# TODO: maybe refer to pulled images as localhost/ so they don't get re-queried? | ||
# (and drop --pull never) | ||
podman.podman( | ||
'container', 'run', | ||
'--rm', | ||
'--pull', 'never', | ||
'--privileged', | ||
'--security-opt', 'label=type:unconfined_t', | ||
'--volume', f'{config_toml}:/config.toml:ro', | ||
'--volume', f'{bootc_output_dir}:/output', | ||
'--volume', '/var/lib/containers/storage:/var/lib/containers/storage', | ||
'quay.io/centos-bootc/bootc-image-builder:latest', | ||
'build', | ||
'--type', 'qcow2', | ||
'--local', | ||
'localhost/bootc-centos-openscap:latest', | ||
) | ||
# 'quay.io/centos-bootc/centos-bootc:stream9', | ||
|
||
# seems to be hardcoded by bootc-image-builder | ||
qcow2_path = bootc_output_dir / 'qcow2' / 'disk.qcow2' | ||
|
||
guest.import_image(qcow2_path, 'qcow2') | ||
|
||
|
||
with guest.booted(): | ||
# copy the original DS to the guest | ||
guest.copy_to(util.get_datastream(), 'scan-ds.xml') | ||
# scan the remediated system | ||
proc, lines = guest.ssh_stream( | ||
f'oscap xccdf eval --profile {profile} --progress --report report.html' | ||
f' --results-arf results-arf.xml scan-ds.xml' | ||
) | ||
oscap.report_from_verbose(lines) | ||
if proc.returncode not in [0,2]: | ||
raise RuntimeError("post-reboot oscap failed unexpectedly") | ||
|
||
guest.copy_from('report.html') | ||
guest.copy_from('results-arf.xml') | ||
|
||
util.subprocess_run(['gzip', '-9', 'results-arf.xml'], check=True) | ||
|
||
results.report_and_exit(logs=['report.html', 'results-arf.xml.gz']) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
""" | ||
Provides utilities and wrappers for creating and manipulating images and | ||
containers using the 'podman' utility. | ||
""" | ||
|
||
from lib import util | ||
|
||
|
||
def podman(*args, **kwargs): | ||
""" | ||
A simple wrapper for the podman(1) CLI, passing python arguments | ||
as shell arguments. | ||
""" | ||
# TODO: make subprocess_run able to pass skip_frames to underlying calls, | ||
# and use it here, to print out our caller, not podman.podman() | ||
util.subprocess_run(['podman', *args], check=True, universal_newlines=True, **kwargs) |