mirror of
https://github.com/AlbrechtL/openwrt-docker.git
synced 2026-10-14 00:01:26 +00:00
361 lines
13 KiB
YAML
361 lines
13 KiB
YAML
|
|
name: OpenWrt master build
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- master
|
|
schedule:
|
|
- cron: '0 20 * * *'
|
|
|
|
env:
|
|
OPENWRT_VERSION: master
|
|
|
|
jobs:
|
|
build:
|
|
name: Build
|
|
runs-on: ubuntu-26.04
|
|
|
|
services:
|
|
registry:
|
|
image: registry:2
|
|
ports:
|
|
- 5000:5000
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v7
|
|
|
|
- name: Set Swap Space
|
|
uses: pierotofy/set-swap-space@master
|
|
with:
|
|
swap-size-gb: 10
|
|
|
|
- name: Set up QEMU
|
|
uses: docker/setup-qemu-action@v4
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v4
|
|
with:
|
|
driver-opts: network=host # Important to access local Docker registry
|
|
|
|
- name: Login into Docker Hub
|
|
uses: docker/login-action@v4
|
|
with:
|
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
|
|
- name: Build Docker image
|
|
uses: docker/build-push-action@v7
|
|
env:
|
|
DOCKER_BUILD_RECORD_UPLOAD: false
|
|
with:
|
|
context: .
|
|
push: true
|
|
provenance: false
|
|
platforms: |
|
|
linux/x86_64
|
|
linux/arm64
|
|
build-args: |
|
|
OPENWRT_VERSION=${{ env.OPENWRT_VERSION }}
|
|
BUILDKIT_MULTI_PLATFORM=1
|
|
tags: |
|
|
albrechtloh/openwrt-docker:ci-openwrt-master-snapshot
|
|
localhost:5000/local/openwrt-docker:latest
|
|
|
|
- name: Inspect
|
|
run: |
|
|
docker buildx imagetools inspect localhost:5000/local/openwrt-docker:latest
|
|
|
|
- name: Build and export
|
|
uses: docker/build-push-action@v7
|
|
env:
|
|
DOCKER_BUILD_SUMMARY: false
|
|
DOCKER_BUILD_RECORD_UPLOAD: false
|
|
with:
|
|
context: . # TODO: Just for testing
|
|
tags: openwrt-docker:latest
|
|
build-args: OPENWRT_VERSION=${{ env.OPENWRT_VERSION }}
|
|
allow: security.insecure,network.host
|
|
outputs: type=docker,dest=/tmp/openwrt-docker-image.tar
|
|
|
|
- name: Upload artifact
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: OpenWrt Docker Image
|
|
path: /tmp/openwrt-docker-image.tar
|
|
|
|
- name: Login to Weidmueller wmucdev
|
|
uses: docker/login-action@v4
|
|
with:
|
|
registry: wmucdev.azurecr.io
|
|
username: ${{ secrets.WMUCDEV_USERNAME }}
|
|
password: ${{ secrets.WMUCDEV_TOKEN }}
|
|
|
|
- name: Create Weidmueller u-OS app
|
|
id: create_u-os-app
|
|
run: |
|
|
# uc-aom-packager accept only version that has to be greater than the previous one. Lets use the datetime to ensure that.
|
|
DATETIME=$(date "+%Y%m%d%H%M%S")
|
|
|
|
# uc-aom-packager allow only decimal numbers as version number for an unkonwn reason
|
|
# see https://github.com/weidmueller/uc-addon/blob/main/uc-manifest.schema-doc.md#version)
|
|
# So lets convert the git hash into a decimal value
|
|
GIT_HASH=`git rev-parse --short HEAD`
|
|
GIT_HASH_DECIMAL=$((16#$GIT_HASH))
|
|
|
|
# Create app version
|
|
#APP_VERSION=$OPENWRT_VERSION.$DATETIME-$GIT_HASH_DECIMAL
|
|
APP_VERSION=0.0.0.$DATETIME-$GIT_HASH_DECIMAL # TODO just for SNAPSHOT
|
|
|
|
echo "***** Create manifest from template *****"
|
|
mv u-os-app/manifest.json.template u-os-app/manifest.json
|
|
sed -i 's/APPVERSION_TO_INSERT/'"$APP_VERSION"'/g' u-os-app/manifest.json
|
|
cat u-os-app/manifest.json | grep version
|
|
|
|
echo "***** Run uc-aom-packager to create the u-OS app *****"
|
|
# uc-aom-packager accepts only multiarch images. "--build-arg BUILDKIT_MULTI_PLATFORM=1" has to set to ensure that.
|
|
# uc-aom-packager needs to Docker registry credentials in a clear text file. Because of security concerns we use a local registry without credentials here.
|
|
|
|
docker run --rm --network=host --pull=always \
|
|
--mount src=$(pwd)/u-os-app,target=/tmp/u-os-app-openwrt,type=bind wmucdev.azurecr.io/u-control/uc-aom-packager:0 \
|
|
uc-aom-packager push \
|
|
-m /tmp/u-os-app-openwrt \
|
|
-s /tmp/u-os-app-openwrt/source-credentials.json \
|
|
-t /tmp/u-os-app-openwrt/target-credentials.json \
|
|
-v
|
|
|
|
echo "***** Create SWU app file*****"
|
|
docker run --rm --network=host --pull=always \
|
|
--mount src=$(pwd)/u-os-app,target=/tmp/u-os-app-openwrt,type=bind wmucdev.azurecr.io/u-control/uc-aom-packager:0 \
|
|
uc-aom-packager \
|
|
export \
|
|
-t /tmp/u-os-app-openwrt/target-credentials.json \
|
|
--version $APP_VERSION \
|
|
-o /tmp/u-os-app-openwrt/u-os-app-openwrt_$APP_VERSION.swu \
|
|
-v
|
|
|
|
find u-os-app/
|
|
|
|
- name: Archive artifacts (OpenWrt u-OS app)
|
|
if: always() && steps.create_u-os-app.outcome == 'success'
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: OpenWrt u-OS app
|
|
path: |
|
|
u-os-app/u-os-app-openwrt_*.swu/linux-arm64/*.swu
|
|
u-os-app/u-os-app-openwrt_*.swu/linux-amd64/*.swu
|
|
if-no-files-found: error
|
|
|
|
|
|
sbom:
|
|
name: SBOM generation
|
|
needs: build
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v7
|
|
|
|
- name: Generate alpine SBOM
|
|
uses: anchore/sbom-action@v0
|
|
with:
|
|
image: albrechtloh/openwrt-docker:ci-openwrt-master-snapshot
|
|
upload-artifact: false
|
|
format: cyclonedx-json
|
|
output-file: alpine_sbom.json
|
|
|
|
- name: Prepare OpenWrt rootfs
|
|
run: |
|
|
# Use automated generated image
|
|
sed -i 's/image: albrechtloh\/openwrt-docker:latest/image: albrechtloh\/openwrt-docker:ci-openwrt-master-snapshot/g' docker-compose.yml
|
|
|
|
# Run OpenWrt container for some time to install additional IPKs
|
|
set +e # Enable that the next command can fail
|
|
timeout --preserve-status 60 docker compose up
|
|
set -e # Revert set +e
|
|
|
|
# Get image from volume
|
|
sudo find /var/lib/docker/volumes/
|
|
IMAGE=$(sudo cat /var/lib/docker/volumes/openwrt-docker_data/_data/current_version)
|
|
echo $IMAGE
|
|
|
|
# Mount volume
|
|
wget https://raw.githubusercontent.com/AlbrechtL/openwrt-docker/refs/heads/master/src/mount_openwrt_squashfs_combined.sh
|
|
chmod +x mount_openwrt_squashfs_combined.sh
|
|
sudo ./mount_openwrt_squashfs_combined.sh "/var/lib/docker/volumes/openwrt-docker_data/_data/${IMAGE}"
|
|
|
|
- name: Generate OpenWrt SBOM
|
|
uses: anchore/sbom-action@v0
|
|
with:
|
|
path: /mnt
|
|
upload-artifact: false
|
|
format: cyclonedx-json
|
|
output-file: openwrt_sbom.json
|
|
|
|
- name: Generate web-frontend SBOM
|
|
uses: anchore/sbom-action@v0
|
|
with:
|
|
path: web-frontend
|
|
upload-artifact: false
|
|
format: cyclonedx-json
|
|
output-file: web-frontend_sbom.json
|
|
|
|
- name: Generate web-backend SBOM
|
|
uses: anchore/sbom-action@v0
|
|
with:
|
|
path: web-backend
|
|
upload-artifact: false
|
|
format: cyclonedx-json
|
|
output-file: web-backend_sbom.json
|
|
|
|
- name: Archive artifacts (SBOMs)
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: Software Bill of Material (SBOM)
|
|
path: ./*.json
|
|
if-no-files-found: error
|
|
|
|
test:
|
|
name: Test
|
|
runs-on: ubuntu-latest
|
|
needs: build
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v7
|
|
|
|
- name: Download artifact
|
|
uses: actions/download-artifact@v8
|
|
with:
|
|
name: OpenWrt Docker Image
|
|
path: .
|
|
|
|
- name: Install VMs
|
|
run: |
|
|
set -x
|
|
sudo snap install multipass # need multipass >= 1.15 because of networks support
|
|
|
|
# Workaround for "multipass_root_cert.pem': No such file or directory" issue, see https://github.com/canonical/multipass/issues/5015
|
|
sleep 180
|
|
|
|
# Workaround for 'multipass socket access denied'
|
|
sudo chmod a+w /var/snap/multipass/common/multipass_socket
|
|
|
|
multipass find
|
|
|
|
# Set up some bridges for the VMs
|
|
sudo ip link add lannetvm type bridge
|
|
sudo ip link add wannetvm type bridge
|
|
sudo ip link set dev lannetvm up
|
|
sudo ip link set dev wannetvm up
|
|
ip addr
|
|
|
|
# We need to disable the firewall otherwise the tap devices are not working properly
|
|
sudo ufw disable
|
|
|
|
# Start VMs
|
|
# Multipass and the OpenWrt container are using the same MAC QUI 52:54:00 which creates error. Let's use differnet MAC addresses here
|
|
multipass launch docker --network name=wannetvm,mac=06:00:00:11:22:33 --network name=lannetvm,mac=06:00:00:44:55:66 --name router-vm
|
|
multipass mount $GITHUB_WORKSPACE router-vm
|
|
|
|
multipass launch --network wannetvm --name wan-vm
|
|
multipass launch --network lannetvm --name lan-vm
|
|
|
|
- name: Show VM and and environments variables
|
|
run: |
|
|
export
|
|
multipass exec router-vm -- lsb_release -a
|
|
multipass info
|
|
|
|
- name: Load image
|
|
run: |
|
|
multipass exec router-vm -- docker load --input openwrt-docker-image.tar
|
|
multipass exec router-vm -- docker image ls -a
|
|
|
|
- name: Prepare VMs
|
|
run: |
|
|
# By default portainer is running at port 9000. But we need port 9000
|
|
multipass exec router-vm -- docker stop portainer
|
|
|
|
# Install python
|
|
multipass exec router-vm -- sudo apt-get -y install python3-pip python-is-python3 python3-venv
|
|
|
|
# Install everthing for pytest
|
|
multipass exec router-vm -- find .
|
|
multipass exec router-vm -- bash -c 'python -m venv ~/.venv'
|
|
multipass exec router-vm -- bash -c 'source ~/.venv/bin/activate && pip install -r test/requirements.txt'
|
|
|
|
echo '******** router-vm IPs ********'
|
|
multipass exec router-vm -- ip addr
|
|
|
|
# Prepare WAN VM
|
|
echo '******** wan-vm IPs ********'
|
|
# Add IP address
|
|
multipass exec wan-vm -- sudo ip addr add 192.168.22.1/24 dev ens4
|
|
multipass exec wan-vm -- ip addr
|
|
# Install DHCP server
|
|
multipass exec wan-vm -- sudo sh -c 'apt-get update && apt-get install -y isc-dhcp-server && echo "default-lease-time 600;\nmax-lease-time 7200;\nsubnet 192.168.22.0 netmask 255.255.255.0 {\n range 192.168.22.100 192.168.22.200;\n option routers 192.168.22.1;\n option domain-name-servers 8.8.8.8, 8.8.4.4;\n option domain-name \"example.org\";\n}" > /etc/dhcp/dhcpd.conf && systemctl enable isc-dhcp-server && systemctl restart isc-dhcp-server'
|
|
multipass exec wan-vm -- cat /etc/dhcp/dhcpd.conf
|
|
# Enable NAT
|
|
multipass exec wan-vm -- sudo modprobe iptable_nat
|
|
multipass exec wan-vm -- sudo iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
|
|
multipass exec wan-vm -- sudo sysctl -w net.ipv4.ip_forward=1
|
|
|
|
# Prepare LAN VM
|
|
echo '******** lan-vm IPs ********'
|
|
multipass exec lan-vm -- sudo ip addr add 172.31.1.2/24 dev ens4
|
|
multipass exec lan-vm -- sudo ip addr add 172.31.22.2/24 dev ens4
|
|
multipass exec lan-vm -- ip addr
|
|
|
|
# Double check if virtual networks are working
|
|
echo '******** host IPs ********'
|
|
ip addr
|
|
sudo ufw status
|
|
|
|
echo '******** router-vm IPs ********'
|
|
multipass exec router-vm -- sudo ip addr add 192.168.22.99/24 dev ens4
|
|
multipass exec router-vm -- sudo ip addr add 172.31.22.99/24 dev ens5
|
|
multipass exec router-vm -- ip addr
|
|
|
|
echo '******** Test connection between router-vm, lan-vm and wan-vm ********'
|
|
multipass exec router-vm -- ping -c 1 192.168.22.1 # to wan-vm
|
|
multipass exec router-vm -- ping -c 1 172.31.22.2 # to lan-vm
|
|
|
|
- name: Prepare tests
|
|
run: |
|
|
# Use local image instead of hub.docker.com
|
|
sed -i 's/image: albrechtloh\/openwrt-docker:latest/image: openwrt-docker/g' test/tests/docker-compose.yml.template
|
|
cat test/tests/docker-compose.yml.template
|
|
|
|
- name: Run tests
|
|
run: |
|
|
cat test/tests/docker-compose.yml.template
|
|
# Run pytest
|
|
multipass exec router-vm -- bash -c 'source ~/.venv/bin/activate && cd test/ && pytest -v -s --html=report.html --self-contained-html --reruns 3'
|
|
|
|
- name: Archive test report
|
|
if: always()
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: Test report
|
|
path: test/*.html
|
|
if-no-files-found: error
|
|
|
|
publish:
|
|
name: Publish
|
|
needs: test
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Login into Docker Hub
|
|
uses: docker/login-action@v4
|
|
with:
|
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
|
|
- name: Tag image at Docker Hub
|
|
run: |
|
|
docker buildx imagetools create \
|
|
--tag albrechtloh/openwrt-docker:openwrt-master-snapshot \
|
|
albrechtloh/openwrt-docker:ci-openwrt-master-snapshot
|