Skip to content

LXC container platform support #3333

LXC container platform support

LXC container platform support #3333

Workflow file for this run

# RaspberryMatic Continious Integration Check Workflow
# yamllint disable rule:truthy
---
name: CI Build
on:
push:
branches-ignore:
- 'gh-pages'
tags-ignore:
- '3.*'
paths-ignore:
- '**.md'
- 'helm/**'
- 'release/LATEST-VERSION.js'
- 'release/rpi-imager.json'
- 'home-assistant-addon-dev/config.yaml'
pull_request:
branches-ignore:
- 'gh-pages'
tags-ignore:
- '3.*'
paths-ignore:
- '**.md'
- 'helm/**'
- 'release/LATEST-VERSION.js'
- 'release/rpi-imager.json'
- 'home-assistant-addon-dev/config.yaml'
workflow_dispatch:
inputs:
skip_build:
description: 'Skip build (for testing workflow)?'
required: true
default: "true"
# default read-only permission
permissions:
contents: read
env:
# NOTE: secrets cannot be access directly in conditions
# https://github.com/actions/runner/issues/520
SECRETS_ARE_AVAILABLE: ${{ secrets.CR_PAT != '' }}
jobs:
skip_check:
name: Duplicate Check
runs-on: ubuntu-latest
outputs:
should_skip: ${{ steps.check.outputs.should_skip }}
steps:
- id: check
uses: fkirc/skip-duplicate-actions@v5.3.1
with:
skip_after_successful_duplicate: 'true'
concurrent_skipping: 'same_content_newer'
linter:
name: Linter Checks
needs: skip_check
if: ${{ needs.skip_check.outputs.should_skip != 'true' }}
runs-on: ubuntu-22.04
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Check Dockerfile
uses: brpaz/hadolint-action@v1.5.0
with:
dockerfile: ./buildroot-external/board/oci/Dockerfile
- name: Check shell scripts
uses: ludeeus/action-shellcheck@2.0.0
with:
ignore_paths: >-
buildroot-external/package/neoserver/pkg/mediola/neo_server
buildroot-patches/0001-setlocalversion/buildroot/support/scripts
buildroot-patches/0010-lib32-integration/buildroot/support/scripts
env:
SHELLCHECK_OPTS: -e SC3010 -e SC3014 -e SC3057 -e SC3036 -e SC3028 -e SC3020
- name: Check Home Assistant Add-on Lint
uses: frenck/action-addon-linter@main
with:
path: "./home-assistant-addon"
- name: Check Home Assistant Add-on Lint (dev)
uses: frenck/action-addon-linter@main
with:
path: "./home-assistant-addon-dev"
- name: Check yaml files
uses: frenck/action-yamllint@v1.4
- name: Check markdown files
uses: avto-dev/markdown-lint@v1
with:
ignore: '**/node_modules/** **/codemirror/README.md'
- name: Check Package consistency
run: |
pip install flake8
make check
build:
permissions:
contents: write # actions/upload-artifact
name: CI build [${{ matrix.platform }}]
if: ${{ (github.event_name != 'pull_request' || github.event.pull_request.user.login == 'jens-maus') && github.actor != 'dependabot[bot]' && github.repository == 'jens-maus/RaspberryMatic' }}
needs: linter
runs-on: self-hosted
timeout-minutes: 480
outputs:
build_datetime: ${{ steps.env.outputs.build_datetime }}
build_version: ${{ steps.env.outputs.build_version }}
strategy:
fail-fast: false
matrix:
platform: [rpi0, rpi2, rpi3, rpi4, rpi5, tinkerboard, odroid-c2, odroid-c4, odroid-n2, intelnuc, ova, oci_amd64, oci_arm64, oci_arm, generic-aarch64, lxc_amd64, lxc_arm64, lxc_arm]
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Install Dependencies
run: |
if ! dpkg-query -l wget bc cpio rsync zip python3 file >/dev/null 2>&1; then
apt update
apt install -y --no-install-recommends wget bc cpio rsync zip python3 file
fi
if ! getent group | grep -q ^builder:; then groupadd -g 48 builder; fi
if ! getent passwd | grep -q ^builder:; then useradd -m -u 1003 -g 48 -G sudo builder; fi
if ! grep -q ^builder; then echo "builder ALL=(ALL:ALL) NOPASSWD: ALL" >>/etc/sudoers; fi
chown -R builder:builder /home/builder
- name: Setup Environment
id: env
run: |
echo "DATE=$(date +%Y%m%d)" >> $GITHUB_ENV
echo "OCCU_VERSION=$(grep 'OCCU_VERSION =' buildroot-external/package/occu/occu.mk | cut -d' ' -f3 | cut -d'-' -f1)" >> $GITHUB_ENV
echo "VERSION=$(grep 'OCCU_VERSION =' buildroot-external/package/occu/occu.mk | cut -d' ' -f3 | cut -d'-' -f1).$(date +%Y%m%d)" >> $GITHUB_ENV
echo "GITHUB_SHA7=$(echo ${GITHUB_SHA::7})" >> $GITHUB_ENV
if [[ -z "${{ github.event.inputs.skip_build }}" ]]; then
echo "FAKE_BUILD=true" >> $GITHUB_ENV
else
echo "FAKE_BUILD=${{ github.event.inputs.skip_build }}" >> $GITHUB_ENV
fi
JLEVEL=0
if [[ -f /sys/fs/cgroup/cpu.max ]]; then # cgroups v2
CPU_QUOTA=$(cut -d ' ' -f1 /sys/fs/cgroup/cpu.max)
if [[ "${CPU_QUOTA}" != "max" ]]; then
CPU_PERIOD=$(cut -d ' ' -f2 /sys/fs/cgroup/cpu.max)
JLEVEL=$((CPU_QUOTA / CPU_PERIOD + 1))
fi
elif [[ -f /sys/fs/cgroup/cpu/cpu.cfs_quota_us ]]; then # cgroups v1
CPU_QUOTA=$(cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us)
if [[ "${CPU_QUOTA}" != "-1" ]]; then
CPU_PERIOD=$(cat /sys/fs/cgroup/cpu/cpu.cfs_period_us)
JLEVEL=$((CPU_QUOTA / CPU_PERIOD + 1))
fi
fi
echo "JLEVEL=${JLEVEL}" >> $GITHUB_ENV
echo "build_datetime=$(date +'%Y-%m-%d %H:%M:%S')" >> $GITHUB_OUTPUT
echo "build_version=$(grep 'OCCU_VERSION =' buildroot-external/package/occu/occu.mk | cut -d' ' -f3 | cut -d'-' -f1).$(date +%Y%m%d)" >> $GITHUB_OUTPUT
- name: Switch to experimental EULA files
run: |
mv -f release/updatepkg/raspmatic_${{ matrix.platform }}/EULA.de_nightly release/updatepkg/raspmatic_${{ matrix.platform }}/EULA.de
mv -f release/updatepkg/raspmatic_${{ matrix.platform }}/EULA.en_nightly release/updatepkg/raspmatic_${{ matrix.platform }}/EULA.en
# - name: remote debug tmate session
# uses: mxschmitt/action-tmate@v1
# if: matrix.platform == 'ova'
# major build step
- name: Build
timeout-minutes: 480
run: |
sudo -H -E -u builder nice -n 19 make DATE=${{ env.DATE }} BR2_DL_DIR=/mnt/download BR2_CCACHE_DIR=/mnt/ccache/${{ matrix.platform }} BR2_JLEVEL=${{ env.JLEVEL }} clean raspmatic_${{ matrix.platform }}-release
# cleanup
- name: Cleanup
run: |
rm -f release/*.img*
make clean
#########################
# upload build artifacts
- name: Upload build artifact [rpi*, tinkerboard, intelnuc, ova, generic-*]
if: |
!startsWith(matrix.platform, 'oci_') &&
!startsWith(matrix.platform, 'lxc_')
uses: actions/upload-artifact@v4
with:
path: release/RaspberryMatic-${{ env.VERSION }}-${{ matrix.platform }}.zip*
name: RaspberryMatic-${{ env.VERSION }}-${{ env.GITHUB_SHA7 }}-${{ matrix.platform }}.zip
continue-on-error: true
- name: Upload build artifact [ccu3]
if: |
matrix.platform == 'rpi3'
uses: actions/upload-artifact@v4
with:
path: release/RaspberryMatic-${{ env.VERSION }}-ccu3.tgz*
name: RaspberryMatic-${{ env.VERSION }}-${{ env.GITHUB_SHA7 }}-ccu3.tgz
continue-on-error: true
- name: Upload build artifact [ova]
if: |
matrix.platform == 'ova'
uses: actions/upload-artifact@v4
with:
path: release/RaspberryMatic-${{ env.VERSION }}.ova*
name: RaspberryMatic-${{ env.VERSION }}-${{ env.GITHUB_SHA7 }}.ova
continue-on-error: true
- name: Upload build artifact [oci]
if: |
startsWith(matrix.platform, 'oci_')
uses: actions/upload-artifact@v4
with:
path: release/RaspberryMatic-${{ env.VERSION }}-${{ matrix.platform }}.tgz*
name: RaspberryMatic-${{ env.VERSION }}-${{ env.GITHUB_SHA7 }}-${{ matrix.platform }}.tgz
continue-on-error: true
- name: Upload build artifact [lxc]
if: |
startsWith(matrix.platform, 'lxc_')
uses: actions/upload-artifact@v4
with:
path: release/RaspberryMatic-${{ env.VERSION }}-${{ matrix.platform }}.tar.gz*
name: RaspberryMatic-${{ env.VERSION }}-${{ env.GITHUB_SHA7 }}-${{ matrix.platform }}.tar.gz
continue-on-error: true
##########################################
# OCI/Docker build and registry push step
oci-multiarch-build-push:
permissions:
contents: write # actions/upload-artifact
packages: write # docker/build-push-action
name: OCI/Docker Build+Push
runs-on: ubuntu-22.04
needs: build
steps:
- uses: actions/checkout@v4
- name: Setup Environment
run: |
echo "BUILD_DATETIME=${{ needs.build.outputs.build_datetime }}" >> $GITHUB_ENV
echo "BUILD_VERSION=${{ needs.build.outputs.build_version }}" >> $GITHUB_ENV
echo "GIT_REF=$(git symbolic-ref -q --short HEAD || git describe --tags --exact-match)" >> $GITHUB_ENV
echo "GITHUB_SHA7=$(echo ${GITHUB_SHA::7})" >> $GITHUB_ENV
echo "CCU_OCI_REPO=ghcr.io/${{ github.repository_owner }}/raspberrymatic" >> $GITHUB_ENV
echo "CCU_OCI_TAG=${{ needs.build.outputs.build_version }}-$(echo ${GITHUB_SHA::7})" >> $GITHUB_ENV
# download OCI platform artifacts
- name: Download oci_amd64 artifact
uses: actions/download-artifact@v4
with:
name: RaspberryMatic-${{ env.BUILD_VERSION }}-${{ env.GITHUB_SHA7 }}-oci_amd64.tgz
- name: Download oci_arm64 artifact
uses: actions/download-artifact@v4
with:
name: RaspberryMatic-${{ env.BUILD_VERSION }}-${{ env.GITHUB_SHA7 }}-oci_arm64.tgz
- name: Download oci_arm artifact
uses: actions/download-artifact@v4
with:
name: RaspberryMatic-${{ env.BUILD_VERSION }}-${{ env.GITHUB_SHA7 }}-oci_arm.tgz
- name: Extract OCI artifacts
run: |
mkdir -p oci_build
cd oci_build
for f in ../*-oci_*.tgz; do
tar --wildcards --strip-components 1 -xf $f "*/layer.tar"
mv -f layer.tar $(basename $f .tgz).tar
rm -f $f
done
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3.0.0
with:
install: true
- name: Login to GitHub Container Registry
if: env.SECRETS_ARE_AVAILABLE == 'true'
uses: docker/login-action@v3.0.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.CR_PAT }}
- name: Build and push container image
if: github.event.inputs.skip_build == 'false'
uses: docker/build-push-action@v5.1.0
id: docker_build
with:
context: oci_build
file: buildroot-external/board/oci/Dockerfile
platforms: linux/amd64,linux/arm64,linux/arm/v7
# load not supported -> https://github.com/docker/buildx/issues/290
# load: true #load in docker - needed for testing later on
push: ${{ env.SECRETS_ARE_AVAILABLE }}
build-args: |
tar_prefix=RaspberryMatic-${{ env.BUILD_VERSION }}-oci_
labels: |
org.opencontainers.image.title=RaspberryMatic
org.opencontainers.image.description=Alternative OS for your HomeMatic CCU
org.opencontainers.image.vendor=RasperryMatic OpenSource Project
org.opencontainers.image.authors=RaspberryMatic OpenSource Team
org.opencontainers.image.licenses=Apache-2.0
org.opencontainers.image.url=https://raspberrymatic.de
org.opencontainers.image.source=https://github.com/${{ github.repository }}
org.opencontainers.image.documentation=https://github.com/${{ github.repository }}/wiki
org.opencontainers.image.created=${{ env.BUILD_DATETIME }}
org.opencontainers.image.ref.name=${{ env.GIT_REF }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.version=${{ env.BUILD_VERSION }}-${{ env.GITHUB_SHA7 }}
io.hass.name=RaspberryMatic CCU
io.hass.description=HomeMatic/homematicIP CCU central based on RaspberryMatic
io.hass.url=https://github.com/${{ github.repository }}/tree/master/home-assistant-addon
io.hass.version=${{ env.BUILD_VERSION }}-${{ env.GITHUB_SHA7 }}
io.hass.type=addon
io.hass.arch=armv7|aarch64|amd64
tags: |
${{ env.CCU_OCI_REPO }}:${{ env.CCU_OCI_TAG }}
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
# Testing
- name: Build and load container image for test
uses: docker/build-push-action@v5.1.0
id: docker_build_test
with:
context: oci_build
file: buildroot-external/board/oci/Dockerfile
platforms: linux/amd64 # load does not support muti-arch https://github.com/docker/buildx/issues/290
load: true # load in docker - needed for testing later on
push: false
build-args: |
tar_prefix=RaspberryMatic-${{ env.BUILD_VERSION }}-oci_
labels: |
org.opencontainers.image.title=RaspberryMatic
org.opencontainers.image.description=Alternative OS for your HomeMatic CCU
org.opencontainers.image.vendor=RasperryMatic OpenSource Project
org.opencontainers.image.authors=RaspberryMatic OpenSource Team
org.opencontainers.image.licenses=Apache-2.0
org.opencontainers.image.url=https://raspberrymatic.de
org.opencontainers.image.source=https://github.com/${{ github.repository }}
org.opencontainers.image.documentation=https://github.com/${{ github.repository }}/wiki
org.opencontainers.image.created=${{ env.BUILD_DATETIME }}
org.opencontainers.image.ref.name=${{ env.GIT_REF }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.version=${{ env.BUILD_VERSION }}-${{ env.GITHUB_SHA7 }}
io.hass.name=RaspberryMatic CCU
io.hass.description=HomeMatic/homematicIP CCU central based on RaspberryMatic
io.hass.url=https://github.com/${{ github.repository }}/tree/master/home-assistant-addon
io.hass.version=${{ env.BUILD_VERSION }}-${{ env.GITHUB_SHA7 }}
io.hass.type=addon
io.hass.arch=armv7|aarch64|amd64
tags: |
${{ env.CCU_OCI_REPO }}:${{ env.CCU_OCI_TAG }}
- name: Enable experimental features for the Docker daemon and CLI
run: |
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
mkdir -p ~/.docker
echo $'{\n "experimental": "enabled"\n}' | sudo tee ~/.docker/config.json
sudo service docker restart
#docker version -f '{{.Client.Experimental}}'
#docker version -f '{{.Server.Experimental}}'
docker version
- name: Test container deploy (install-docker.sh)
run: |
export CCU_DOCKER_PULL_REFRESH="false"
export CCU_CONTAINER_IP="192.168.178.4"
export CCU_CONTAINER_IP_AUX="192.168.178.2"
export CCU_NETWORK_NAME="none"
export CCU_NETWORK_INTERFACE="none"
export CCU_NETWORK_SUBNET="none"
sudo mknod /dev/eq3loop c 239 0 # fake /dev/eq3loop
sudo -E ./scripts/install-docker.sh
- name: Test container startup+stop
if: github.event.inputs.skip_build == 'false'
run: |
docker start ccu
error=0
n=1
while ! docker exec ccu test -e /var/status/startupFinished ; do
if [ "$n" -ge 120 ]; then
echo "ERROR: container not started after 120s. aborting."
error=1
break
fi
sleep 1
n=$((n+1))
done
docker exec ccu tar --owner=root --group=root --one-file-system --ignore-failed-read -czf - /tmp /usr/local > debug_output.tgz
docker stop ccu
docker logs ccu
exit $error
- name: Upload debug information
if: github.event.inputs.skip_build == 'false'
uses: actions/upload-artifact@v4
with:
path: debug_output.tgz
name: RaspberryMatic-debug_output-${{ env.BUILD_VERSION }}-${{ env.GITHUB_SHA7 }}.tgz
- name: Remove/Cleanup container environment
run: |
sudo -E ./scripts/install-docker.sh uninstall
docker volume rm ccu_data
docker image ls -a
docker image rm ${{ env.CCU_OCI_REPO }}:${{ env.CCU_OCI_TAG }}