Skip to content

Commit 1bb953e

Browse files
Include SBOM generation into GCP images build pipeline (#1)
* Add initial sbom generation support * Add sbom generation from collected data and upload artifact * Update gcp 8 and 9 packer definitions * Update paths around SBOM generation * Run sbom_generator as sudo Also, remove dump_repo_metadata role * Restored commented actions * Pull cloud-images-sbom-tools from AlmaLinux organization Also, simplify installation of cloud-images-sbom-tools dependencies --------- Signed-off-by: Jonathan Wright <[email protected]> Co-authored-by: Jonathan Wright <[email protected]>
1 parent 8f6faab commit 1bb953e

File tree

8 files changed

+84
-76
lines changed

8 files changed

+84
-76
lines changed

.github/actions/shared-steps/action.yml

Lines changed: 51 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,25 @@ runs:
391391
# Install ansible
392392
sudo ${{ env.runner_os == 'ubuntu' && 'apt-get' || 'dnf -q' }} -y install ansible
393393
394+
- name: Clone SBOM tools
395+
shell: bash
396+
run: |
397+
rm -rf sbom-tools
398+
git clone --depth=1 https://github.com/AlmaLinux/cloud-images-sbom-tools.git sbom-tools
399+
400+
- name: Set up Python and install generator deps
401+
uses: actions/setup-python@v5
402+
with:
403+
python-version: '3.11'
404+
cache: 'pip'
405+
cache-dependency-path: sbom-tools/requirements.txt
406+
407+
- name: Create venv and install
408+
shell: bash
409+
run: |
410+
python -m venv .venv-sbom
411+
.venv-sbom/bin/pip install -r sbom-tools/requirements.txt
412+
394413
- name: Initialize packer
395414
shell: bash
396415
run: sudo /usr/bin/packer init -upgrade .
@@ -406,7 +425,8 @@ runs:
406425
- name: Locate image file, generate checksum
407426
shell: bash
408427
run: |
409-
# Locate image file, generate checksum
428+
# Locate image file, generate checksum, rename repo metadata file
429+
ls -la $(dirname '${{ env.output_mask }}')
410430
image_file=$(ls -1 ${{ env.output_mask }} | head -n 1)
411431
[ "x${image_file}" = "x" ] && false
412432
cd $(dirname ${image_file})
@@ -416,15 +436,15 @@ runs:
416436
echo "IMAGE_NAME=$(basename ${image_file})" >> $GITHUB_ENV
417437
418438
# don't fail if this doesn't exist, we may not always generate it
419-
sudo mv repo-metadata-*.txt $(basename ${image_file}).repo-metadata.txt || true
439+
sudo mv sbom-data-*.json $(basename ${image_file}).sbom-data.json || true
420440
421441
- id: 'google-auth-dev-images'
422442
if: env.IMAGE_TYPE == 'gcp'
423443
uses: 'google-github-actions/auth@v2'
424444
with:
425445
workload_identity_provider: 'projects/443728870479/locations/global/workloadIdentityPools/github-actions/providers/github'
426446
service_account: 'github-actions-cloud-images@almalinux-dev-images-469421.iam.gserviceaccount.com'
427-
447+
428448
- name: 'Set up Google Cloud SDK'
429449
if: env.IMAGE_TYPE == 'gcp'
430450
uses: 'google-github-actions/[email protected]'
@@ -477,64 +497,23 @@ runs:
477497
-source_gcs_path="gs://almalinux-images-dev/" \
478498
vm-scripts/gcp/almalinux_${version_major}${{ inputs.arch == 'aarch64' && '_arm64' || '' }}.publish.json
479499
480-
- name: Test/check release and architecture, list installed packages in ${{ env.IMAGE_FILE }} cloud image
481-
if: ${{ ! contains(inputs.type, 'vagrant') && ! contains(inputs.type, 'gcp') }}
500+
# - name: 'Run Google cloud-image-testing tests (basic suite)'
501+
# if: env.IMAGE_TYPE == 'gcp' && inputs.run_test == 'true'
502+
# shell: bash
503+
# run: |
504+
# cd cloud-image-tests
505+
# ./bin/manager \
506+
# -local_path bin \
507+
# -project almalinux-image-testing-469421 \
508+
# -filter '^(cvm|livemigrate|suspendresume|loadbalancer|guestagent|hostnamevalidation|imageboot|licensevalidation|network|security|hotattach|lssd|disk|packagevalidation|ssh|metadata|vmspec)$' \
509+
# -images 'projects/almalinux-dev-images-469421/global/images/family/almalinux-${{ env.version_major }}${{ inputs.arch == 'aarch64' && '-arm64' || '' }}' \
510+
# -parallel_stagger 10s -parallel_count 20
511+
512+
- name: Generate SBOM
482513
shell: bash
483514
run: |
484-
# List installed packages in ${{ env.IMAGE_FILE }} image
485-
486-
# Partition number with root file-system
487-
case ${{ inputs.arch }} in
488-
x86_64*) partition=4 ;;
489-
aarch64*) partition=3 ;;
490-
*) false ;;
491-
esac
492-
493-
# Image file format: raw or qcow2
494-
case ${{ inputs.type }} in
495-
oci|gencloud|opennebula) format=qcow2 ;;
496-
azure) format=raw ;;
497-
*) false ;;
498-
esac
499-
rootfs_path=/mnt/rootfs
500-
sudo mkdir -p ${rootfs_path}
501-
502-
# Install qemu-utils
503-
sudo ${{ env.runner_os == 'ubuntu' && 'apt-get' || 'dnf -q' }} \
504-
-y install \
505-
${{ env.runner_os == 'ubuntu' && 'qemu-utils' || 'qemu-img' }}
506-
507-
# Load nbd kernel module
508-
sudo modprobe nbd max_part=8
509-
510-
# Make a copy of the image file
511-
sudo cp ${{ env.IMAGE_FILE }} $(dirname ${rootfs_path})
512-
513-
# Attach the image file to the nbd device
514-
sudo qemu-nbd \
515-
--read-only \
516-
--format=${format} \
517-
--connect=/dev/nbd0 \
518-
$(dirname ${rootfs_path})/$(basename ${{ env.IMAGE_FILE }}) \
519-
&& sleep 10 || false
520-
521-
# Mount need partition
522-
sudo fdisk -l /dev/nbd0
523-
sudo mount /dev/nbd0p${partition} ${rootfs_path} \
524-
&& sleep 10 || false
525-
526-
echo "[Debug] AlmaLinux release:"
527-
grep '${{ env.RELEASE_STRING }}' ${rootfs_path}/etc/almalinux-release
528-
529-
echo "[Debug] System architecture:"
530-
rpm --dbpath=${rootfs_path}/var/lib/rpm -q --qf='%{ARCH}\n' ${{ env.RELEASE_PACKAGE }} | grep '${{ env.alma_arch }}'
531-
532-
# Get installed packages list
533-
sudo sh -c "rpm --dbpath=${rootfs_path}/var/lib/rpm -qa --queryformat '%{NAME}\n' | sort > ${{ env.IMAGE_FILE }}.txt"
534-
535-
[ -f ${{ env.IMAGE_FILE }}.txt ] \
536-
&& echo "got_pkgs_list=true" >> $GITHUB_ENV \
537-
|| echo "got_pkgs_list=false" >> $GITHUB_ENV
515+
echo "Generating SBOM document of ${{ env.IMAGE_FILE }}"
516+
sudo .venv-sbom/bin/python3 sbom-tools/sbom_generator.py "${{ env.IMAGE_NAME }}" "${{ env.IMAGE_FILE }}.sbom-data.json" "${{ env.IMAGE_FILE }}.sbom.spdx.json"
538517
539518
- name: Test ${{ inputs.type }} ${{ inputs.variant }} image
540519
if: inputs.run_test == 'true' && contains(inputs.type, 'vagrant')
@@ -636,13 +615,22 @@ runs:
636615
path: ${{ env.IMAGE_FILE }}
637616

638617
- uses: actions/upload-artifact@v4
639-
name: Store repo metadata as artifact
640-
id: repo-meta-artifact
618+
name: Store collected sbom data as artifact
619+
id: sbom-data-artifact
620+
if: inputs.store_as_artifact == 'true'
621+
with:
622+
compression-level: 9
623+
name: ${{ env.IMAGE_NAME }}.sbom-data.json
624+
path: ${{ env.IMAGE_FILE }}.sbom-data.json
625+
626+
- uses: actions/upload-artifact@v4
627+
name: Store SBOM as artifact
628+
id: sbom-artifact
641629
if: inputs.store_as_artifact == 'true'
642630
with:
643631
compression-level: 9
644-
name: ${{ env.IMAGE_NAME }}.repo-metadata.txt
645-
path: ${{ env.IMAGE_FILE }}.repo-metadata.txt
632+
name: ${{ env.IMAGE_NAME }}.sbom.spdx.json
633+
path: ${{ env.IMAGE_FILE }}.sbom.spdx.json
646634

647635
- uses: actions/upload-artifact@v4
648636
name: Store checksum as artifact

.github/workflows/test-gcp.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ on:
2626
description: 'Image to test, overrides version_major to test a direct image instead. Architecture must be set properly for the image being passed. This must be a full path to a GCP image, for example, projects/almalinux-dev-images-469421/global/images/almalinux-9-v20230920'
2727
required: false
2828
default: ''
29-
notify_mattermost:
30-
description: "Send notification to Mattermost"
31-
required: true
32-
type: boolean
33-
default: false
29+
# notify_mattermost:
30+
# description: "Send notification to Mattermost"
31+
# required: true
32+
# type: boolean
33+
# default: false
3434

3535
jobs:
3636
init-data:

almalinux-8-gcp.pkr.hcl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ build {
100100
only = ["qemu.almalinux-8-gcp-aarch64"]
101101
}
102102

103-
# copy the repo metadata file into output
103+
# copy SBOM metadata file into output
104104
post-processor "shell-local" {
105105
inline = [
106-
"cp /tmp/repo-metadata-$PACKER_BUILD_NAME.txt output-$PACKER_BUILD_NAME/"
106+
"cp /tmp/sbom-data-$PACKER_BUILD_NAME.json output-$PACKER_BUILD_NAME/"
107107
]
108108
}
109109

almalinux-9-gcp.pkr.hcl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ build {
100100
only = ["qemu.almalinux-9-gcp-aarch64"]
101101
}
102102

103-
# copy the repo metadata file into output
103+
# copy SBOM metadata file into output
104104
post-processor "shell-local" {
105105
inline = [
106-
"cp /tmp/repo-metadata-$PACKER_BUILD_NAME.txt output-$PACKER_BUILD_NAME/"
106+
"cp /tmp/sbom-data-$PACKER_BUILD_NAME.json output-$PACKER_BUILD_NAME/"
107107
]
108108
}
109109

almalinux_10_gcp.pkr.hcl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,10 @@ build {
117117
]
118118
}
119119

120-
# copy the repo metadata file into output
120+
# copy SBOM metadata file into output
121121
post-processor "shell-local" {
122122
inline = [
123-
"cp /tmp/repo-metadata-$PACKER_BUILD_NAME.txt output-$PACKER_BUILD_NAME/"
123+
"cp /tmp/sbom-data-$PACKER_BUILD_NAME.json output-$PACKER_BUILD_NAME/"
124124
]
125125
}
126126

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
---
22
cleanup_ssh_host_keys: true
3+
collect_sbom_data: true

ansible/roles/cleanup_vm/tasks/main.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
changed_when: removeoldoutput.rc == 0
66
ignore_errors: yes
77

8-
- name: Include repo metadata dump role (for SBOMs)
8+
- name: Include sbom_data role for SBOM data collection
99
include_role:
10-
name: dump_repo_metadata
10+
name: sbom_data
11+
when: collect_sbom_data | bool
1112

1213
- name: Find persistent net rules
1314
ansible.builtin.find:
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
- name: Copy SBOM data collector into the system
3+
ansible.builtin.copy:
4+
src: "{{ playbook_dir }}/../sbom-tools/sbom_data_collector.py"
5+
dest: /dev/shm/sbom_data_collector.py
6+
7+
- name: Collect SBOM data from the system
8+
ansible.builtin.shell: python3 /dev/shm/sbom_data_collector.py -o /dev/shm/sbom-data.json -v
9+
register: sbom_data_collector
10+
failed_when: false
11+
12+
- name: Write SBOM data to artifact file
13+
ansible.builtin.fetch:
14+
src: /dev/shm/sbom-data.json
15+
dest: /tmp/sbom-data-{{ packer_build_name }}.json
16+
flat: true
17+
become: false
18+
when: sbom_data_collector.changed

0 commit comments

Comments
 (0)