Skip to content

Commit c4d8dc5

Browse files
committed
test workflow
1 parent 4794654 commit c4d8dc5

File tree

2 files changed

+372
-0
lines changed

2 files changed

+372
-0
lines changed

.github/README.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# GitHub Actions Workflows
2+
3+
This directory contains GitHub Actions workflows for the sandboxed-containers-operator project.
4+
5+
## Bootc PodVM Build Workflow
6+
7+
The `bootc-podvm-build.yml` workflow builds bootc-based PodVM container images and converts them to disk images for deployment.
8+
9+
### Features
10+
11+
- **Multi-target builds**: Builds both standard and NVIDIA-enabled PodVM images
12+
- **Disk image conversion**: Converts bootc container images to qcow2 disk images using bootc-image-builder
13+
- **Artifact-based workflow**: Uses container artifacts for efficient container-to-disk conversion
14+
- **Artifact management**: Uploads both container images and disk images as artifacts
15+
- **Cloud provider support**: Configurable for Azure, AWS, and libvirt
16+
17+
### Triggers
18+
19+
The workflow runs on:
20+
- **Push events** to `main` or `devel` branches when bootc files change
21+
- **Pull requests** to `main` or `devel` branches (container build only, no push)
22+
- **Manual dispatch** with configurable options
23+
24+
### Manual Execution
25+
26+
You can manually trigger the workflow from the GitHub Actions tab with these options:
27+
28+
- **Cloud Provider**: Choose between `azure`, `aws`, or `libvirt`
29+
- **Build Disk**: Whether to build the disk image from the container
30+
- **Container Variant**: Choose between `standard` or `nvidia` variant for disk conversion
31+
32+
33+
34+
### Workflow Jobs
35+
36+
#### 1. build-container
37+
- Builds the standard bootc PodVM container image
38+
- Saves container as workflow artifact
39+
- Uses Docker layer caching for efficiency
40+
41+
#### 2. build-nvidia-container
42+
- Builds NVIDIA GPU-enabled PodVM container image
43+
- Only runs for Azure cloud provider
44+
- Saves container as workflow artifact
45+
46+
#### 3. build-disk-image
47+
- Downloads container image artifacts from previous jobs (no registry required)
48+
- Supports both standard and nvidia container variants
49+
- Converts the container image to a qcow2 disk image using bootc-image-builder
50+
- Compresses the disk image with xz
51+
- Uploads as workflow artifacts
52+
- Generates metadata including checksums
53+
54+
### Artifacts
55+
56+
The workflow generates these artifacts:
57+
58+
- **Container Images**: Saved as workflow artifacts (`podvm-bootc-container-{sha}`, `podvm-bootc-nvidia-container-{sha}`)
59+
- **Disk Images**: Available as workflow artifacts (`podvm-disk-{variant}-{provider}-{sha}`)
60+
- **Metadata**: JSON file with build information and checksums (`podvm-disk-metadata-{variant}-{provider}-{sha}`)
61+
62+
### Usage Examples
63+
64+
#### Building for Azure with NVIDIA support:
65+
```bash
66+
# Trigger manually from GitHub Actions UI
67+
# Select: cloud_provider=azure, container_variant=nvidia, build_disk=true
68+
```
69+
70+
#### Building for AWS:
71+
```bash
72+
# Trigger manually from GitHub Actions UI
73+
# Select: cloud_provider=aws, build_disk=true
74+
```
75+
76+
#### Development workflow:
77+
```bash
78+
# Create a pull request with changes to bootc files
79+
# Workflow will build containers and generate artifacts
80+
```
81+
82+
### Artifact-Based Workflow Benefits
83+
84+
This workflow uses GitHub Actions artifacts to pass container images between jobs:
85+
86+
- **No registry required**: Complete workflow runs without external registry dependencies
87+
- **Faster builds**: Eliminates registry push/pull overhead
88+
- **Cost efficient**: No registry bandwidth usage
89+
- **Secure**: Container images stay within the GitHub Actions environment
90+
- **Reliable**: No dependency on external registry availability
91+
- **Simplified setup**: No secrets or registry configuration needed
92+
93+
The workflow saves container images as tar files in the first job, uploads them as artifacts, then downloads and loads them in the disk conversion job.
94+
95+
### Disk Image Usage
96+
97+
The generated disk images can be used:
98+
99+
1. **Direct deployment**: Download the compressed qcow2 from artifacts
100+
2. **Cloud upload**: Use the disk image for VM creation in your cloud provider
101+
3. **OSC integration**: Reference the container image URI in OSC ConfigMaps
102+
103+
### Configuration
104+
105+
The workflow uses the `config.toml` file in the bootc directory for bootc-image-builder configuration. Modify this file to customize:
106+
107+
- Root filesystem size
108+
- User accounts
109+
- Additional packages
110+
- Kernel parameters
111+
112+
### Troubleshooting
113+
114+
#### Common Issues:
115+
116+
1. **Disk space**: The workflow includes cleanup steps to free space on runners
117+
2. **Build failures**: Check the bootc-image-builder logs in the workflow output
118+
3. **Missing artifacts**: If disk conversion fails, check that the container build job completed successfully
119+
4. **Container loading**: Verify that the tar file was properly created and downloaded
120+
121+
#### Debugging:
122+
123+
- Enable debug logging by setting `ACTIONS_STEP_DEBUG=true` in repository secrets
124+
- Check individual job logs for detailed error messages
125+
- Verify the Containerfile syntax and build context
126+
- Check artifact upload/download logs for container image transfer issues
127+
128+
### Contributing
129+
130+
When modifying the workflow:
131+
132+
1. Test changes in a fork first
133+
2. Ensure all paths in triggers are correct
134+
3. Consider impact on artifact storage limits
135+
4. Verify container image naming consistency across jobs
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
name: Build Bootc PodVM Image
2+
3+
on:
4+
push:
5+
branches: [ devel ]
6+
paths:
7+
- 'config/peerpods/podvm/bootc/**'
8+
pull_request:
9+
branches: [ devel ]
10+
paths:
11+
- 'config/peerpods/podvm/bootc/**'
12+
workflow_dispatch:
13+
inputs:
14+
cloud_provider:
15+
description: 'Cloud provider (azure, aws, libvirt)'
16+
required: true
17+
default: 'azure'
18+
type: choice
19+
options:
20+
- azure
21+
- aws
22+
- libvirt
23+
24+
build_disk:
25+
description: 'Build disk image from container'
26+
required: false
27+
default: true
28+
type: boolean
29+
container_variant:
30+
description: 'Container variant to convert to disk (standard or nvidia)'
31+
required: false
32+
default: 'standard'
33+
type: choice
34+
options:
35+
- standard
36+
- nvidia
37+
38+
env:
39+
CLOUD_PROVIDER: ${{ github.event.inputs.cloud_provider || 'azure' }}
40+
41+
jobs:
42+
build-container:
43+
runs-on: ubuntu-latest
44+
steps:
45+
- name: Delete huge unnecessary tools folder
46+
run: rm -rf /opt/hostedtoolcache
47+
48+
- name: Checkout repository
49+
uses: actions/checkout@v4
50+
51+
- name: Set up Docker Buildx
52+
uses: docker/setup-buildx-action@v3
53+
54+
- name: Build container image
55+
id: build
56+
uses: docker/build-push-action@v6
57+
with:
58+
context: config/peerpods/podvm/bootc
59+
file: config/peerpods/podvm/bootc/Containerfile.fedora
60+
target: default-target
61+
build-args: |
62+
CLOUD_PROVIDER=${{ env.CLOUD_PROVIDER }}
63+
tags: podvm-bootc:${{ github.sha }}
64+
cache-from: type=gha
65+
cache-to: type=gha,mode=max
66+
platforms: linux/amd64
67+
outputs: type=docker,dest=/tmp/podvm-bootc.tar
68+
69+
- name: Upload container image artifact
70+
uses: actions/upload-artifact@v4
71+
with:
72+
name: podvm-bootc-container-${{ github.sha }}
73+
path: /tmp/podvm-bootc.tar
74+
retention-days: 7
75+
76+
77+
78+
build-nvidia-container:
79+
runs-on: ubuntu-latest
80+
if: github.event.inputs.cloud_provider == 'azure' || github.event_name != 'workflow_dispatch'
81+
steps:
82+
- name: Delete huge unnecessary tools folder
83+
run: rm -rf /opt/hostedtoolcache
84+
85+
- name: Checkout repository
86+
uses: actions/checkout@v4
87+
88+
- name: Set up Docker Buildx
89+
uses: docker/setup-buildx-action@v3
90+
91+
- name: Build NVIDIA container image
92+
id: build
93+
uses: docker/build-push-action@v6
94+
with:
95+
context: config/peerpods/podvm/bootc
96+
file: config/peerpods/podvm/bootc/Containerfile.fedora
97+
target: nvidia-podvm-bootc
98+
build-args: |
99+
CLOUD_PROVIDER=${{ env.CLOUD_PROVIDER }}
100+
tags: podvm-bootc-nvidia:${{ github.sha }}
101+
cache-from: type=gha
102+
cache-to: type=gha,mode=max
103+
platforms: linux/amd64
104+
outputs: type=docker,dest=/tmp/podvm-bootc-nvidia.tar
105+
106+
- name: Upload NVIDIA container image artifact
107+
uses: actions/upload-artifact@v4
108+
with:
109+
name: podvm-bootc-nvidia-container-${{ github.sha }}
110+
path: /tmp/podvm-bootc-nvidia.tar
111+
retention-days: 7
112+
113+
build-disk-image:
114+
runs-on: ubuntu-latest
115+
needs: [build-container, build-nvidia-container]
116+
if: github.event_name != 'pull_request' && (github.event.inputs.build_disk != 'false') && (always() && !cancelled() && !failure())
117+
steps:
118+
- name: Delete huge unnecessary tools folder
119+
run: rm -rf /opt/hostedtoolcache
120+
121+
- name: Checkout repository
122+
uses: actions/checkout@v4
123+
124+
- name: Set up Docker Buildx
125+
uses: docker/setup-buildx-action@v3
126+
127+
- name: Determine container variant
128+
run: |
129+
VARIANT="${{ github.event.inputs.container_variant || 'standard' }}"
130+
echo "CONTAINER_VARIANT=$VARIANT" >> $GITHUB_ENV
131+
132+
if [ "$VARIANT" = "nvidia" ]; then
133+
echo "ARTIFACT_NAME=podvm-bootc-nvidia-container-${{ github.sha }}" >> $GITHUB_ENV
134+
echo "CONTAINER_FILE=podvm-bootc-nvidia.tar" >> $GITHUB_ENV
135+
else
136+
echo "ARTIFACT_NAME=podvm-bootc-container-${{ github.sha }}" >> $GITHUB_ENV
137+
echo "CONTAINER_FILE=podvm-bootc.tar" >> $GITHUB_ENV
138+
fi
139+
140+
- name: Download container image artifact
141+
uses: actions/download-artifact@v4
142+
with:
143+
name: ${{ env.ARTIFACT_NAME }}
144+
path: /tmp
145+
146+
- name: Load container image
147+
run: |
148+
# Load the container image from the artifact
149+
echo "Loading container from: /tmp/${{ env.CONTAINER_FILE }}"
150+
docker load -i /tmp/${{ env.CONTAINER_FILE }}
151+
152+
# Get the loaded image name and tag
153+
IMAGE_NAME=$(docker images --format "table {{.Repository}}:{{.Tag}}" | grep -v REPOSITORY | head -n1)
154+
echo "Loaded image: $IMAGE_NAME (variant: ${{ env.CONTAINER_VARIANT }})"
155+
echo "LOADED_IMAGE=$IMAGE_NAME" >> $GITHUB_ENV
156+
157+
# Transfer image from Docker to Podman storage for bootc-image-builder
158+
echo "Transferring image to Podman storage..."
159+
docker save "$IMAGE_NAME" | sudo podman load
160+
161+
# Verify image is available in Podman
162+
sudo podman images | grep -E "(REPOSITORY|$(echo $IMAGE_NAME | cut -d: -f1))"
163+
164+
- name: Create output directory
165+
run: |
166+
mkdir -p output
167+
sudo chown -R $(id -u):$(id -g) output
168+
169+
- name: Convert container to disk image
170+
run: |
171+
echo "Converting container image: $LOADED_IMAGE"
172+
173+
# Convert bootc container to qcow2 disk image using the loaded image
174+
sudo podman run \
175+
--rm \
176+
--privileged \
177+
--security-opt label=type:unconfined_t \
178+
-v $(pwd)/config/peerpods/podvm/bootc/config.toml:/config.toml:ro \
179+
-v $(pwd)/output:/output \
180+
-v /var/lib/containers/storage:/var/lib/containers/storage \
181+
quay.io/centos-bootc/bootc-image-builder:latest \
182+
--type qcow2 \
183+
--rootfs xfs \
184+
--use-librepo=True \
185+
"$LOADED_IMAGE"
186+
187+
- name: Compress disk image
188+
run: |
189+
cd output/qcow2
190+
if [ -f disk.qcow2 ]; then
191+
echo "Compressing disk image..."
192+
xz -9 -T 0 disk.qcow2
193+
ls -lah disk.qcow2.xz
194+
else
195+
echo "Error: disk.qcow2 not found"
196+
ls -la
197+
exit 1
198+
fi
199+
200+
- name: Upload disk image artifact
201+
uses: actions/upload-artifact@v4
202+
with:
203+
name: podvm-disk-${{ env.CONTAINER_VARIANT }}-${{ env.CLOUD_PROVIDER }}-${{ github.sha }}
204+
path: output/qcow2/disk.qcow2.xz
205+
retention-days: 30
206+
207+
- name: Generate disk image metadata
208+
run: |
209+
cd output/qcow2
210+
if [ -f disk.qcow2.xz ]; then
211+
echo "DISK_SIZE=$(stat -c%s disk.qcow2.xz)" >> $GITHUB_ENV
212+
echo "DISK_SHA256=$(sha256sum disk.qcow2.xz | cut -d' ' -f1)" >> $GITHUB_ENV
213+
fi
214+
215+
- name: Create release info
216+
if: github.ref == 'refs/heads/devel'
217+
run: |
218+
cat > disk-info.json << EOF
219+
{
220+
"cloud_provider": "${{ env.CLOUD_PROVIDER }}",
221+
"container_variant": "${{ env.CONTAINER_VARIANT }}",
222+
"container_image": "${{ env.LOADED_IMAGE }}",
223+
"disk_size_bytes": "${{ env.DISK_SIZE }}",
224+
"disk_sha256": "${{ env.DISK_SHA256 }}",
225+
"build_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
226+
"git_commit": "${{ github.sha }}",
227+
"git_ref": "${{ github.ref }}"
228+
}
229+
EOF
230+
231+
- name: Upload disk metadata
232+
if: github.ref == 'refs/heads/devel'
233+
uses: actions/upload-artifact@v4
234+
with:
235+
name: podvm-disk-metadata-${{ env.CONTAINER_VARIANT }}-${{ env.CLOUD_PROVIDER }}-${{ github.sha }}
236+
path: disk-info.json
237+
retention-days: 90

0 commit comments

Comments
 (0)