diff --git a/.github/actions/test/integration/build/action.yml b/.github/actions/test/integration/build/action.yml
index eca53a3..447de18 100644
--- a/.github/actions/test/integration/build/action.yml
+++ b/.github/actions/test/integration/build/action.yml
@@ -11,7 +11,7 @@ runs:
- name: Set ENV
shell: bash
env:
- REPO: ghcr.io/gardenlinux/gardenlinux-ccloud
+ REPO: ghcr.io/gardenlinux/gardenlinux-sci
TAG: ${{ inputs.image_tag }}
ESP_SIZE: 2 # GiB
DISK_SIZE: 8 # GiB
@@ -135,7 +135,7 @@ runs:
# - name: Upload artifacts
# uses: actions/upload-artifact@v4
# with:
- # name: gardenlinux-ccloud-${{ inputs.image_tag }}
+ # name: gardenlinux-sci-${{ inputs.image_tag }}
# path: /opt/${{ inputs.image_tag }}.*
# retention-days: 1
# overwrite: true
diff --git a/.github/actions/test/integration/build/dev-user-butane.yaml b/.github/actions/test/integration/build/dev-user-butane.yaml
index 9eb08a1..ac08d4a 100644
--- a/.github/actions/test/integration/build/dev-user-butane.yaml
+++ b/.github/actions/test/integration/build/dev-user-butane.yaml
@@ -1,5 +1,5 @@
variant: fcos
-version: 1.3.0
+version: 1.7.0
passwd:
users:
- name: root
@@ -49,7 +49,7 @@ storage:
contents:
inline: |
# pull the image from GHCR instead of keppel
- OCI_REPO=ghcr.io/gardenlinux/gardenlinux-ccloud
+ OCI_REPO=ghcr.io/gardenlinux/gardenlinux-sci
# point to a custom tag to download for the persist step
OCI_TAG=TAG_GOES_HERE
# Enable unlimited core dumps for all systemd services
diff --git a/.github/actions/test/integration/collect-logs/action.yml b/.github/actions/test/integration/collect-logs/action.yml
index 0974c81..51df119 100644
--- a/.github/actions/test/integration/collect-logs/action.yml
+++ b/.github/actions/test/integration/collect-logs/action.yml
@@ -34,6 +34,44 @@ runs:
scp $SSH_OPTS $USER@$HV2_IP:/var/log/QEMU.log "serial-VM-QEMU-HV2.log" || true
scp $SSH_OPTS $USER@$HV2_IP:/var/log/CHV.log "serial-VM-CHV-HV2.log" || true
+ - name: Obtain network diagnostics from hypervisors
+ shell: bash
+ run: |
+ KEY=/opt/ssh_host_ed25519_key
+ SSH_OPTS="-i $KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
+ USER="root"
+
+ for HV_NAME in HV1 HV2; do
+ IP="192.168.122.$([[ $HV_NAME == HV1 ]] && echo 2 || echo 3)"
+
+ ssh $SSH_OPTS $USER@$IP "
+ echo '=== ip addr ==='
+ ip addr
+ echo '=== ip route ==='
+ ip route
+ echo '=== bridge link ==='
+ bridge link 2>/dev/null || true
+ echo '=== arp -n ==='
+ arp -n 2>/dev/null || ip neigh || true
+ echo '=== iptables -L -n ==='
+ iptables -L -n 2>/dev/null || true
+ echo '=== iptables -t nat -L -n ==='
+ iptables -t nat -L -n 2>/dev/null || true
+ echo '=== virsh net-list ==='
+ virsh net-list --all 2>/dev/null || true
+ echo '=== virsh net-dumpxml default ==='
+ virsh net-dumpxml default 2>/dev/null || true
+ echo '=== dnsmasq leases ==='
+ cat /var/lib/libvirt/dnsmasq/*.leases 2>/dev/null || true
+ echo '=== systemctl status systemd-networkd ==='
+ systemctl status systemd-networkd --no-pager 2>/dev/null || true
+ echo '=== networkctl status ==='
+ networkctl status --no-pager 2>/dev/null || true
+ echo '=== ssh -V ==='
+ ssh -V 2>&1 || true
+ " > "network-diag-${HV_NAME}.log" 2>&1 || true
+ done
+
- name: Set permissions
shell: bash
run: |
diff --git a/.github/actions/test/integration/dependencies/action.yml b/.github/actions/test/integration/dependencies/action.yml
index e1923df..65fb700 100644
--- a/.github/actions/test/integration/dependencies/action.yml
+++ b/.github/actions/test/integration/dependencies/action.yml
@@ -34,7 +34,7 @@ runs:
- name: butane
shell: bash
run: |
- BUTANE_VERSION="0.24.0"
+ BUTANE_VERSION="0.27.0"
curl -LO "https://github.com/coreos/butane/releases/download/v${BUTANE_VERSION}/butane-x86_64-unknown-linux-gnu"
chmod +x "butane-x86_64-unknown-linux-gnu"
sudo mv "butane-x86_64-unknown-linux-gnu" /usr/local/bin/butane
diff --git a/.github/actions/test/integration/setup/hv.xml b/.github/actions/test/integration/setup/hv.xml
index 63341fb..c8f6f0d 100644
--- a/.github/actions/test/integration/setup/hv.xml
+++ b/.github/actions/test/integration/setup/hv.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/.github/actions/test/integration/test/cloudhypervisor/action.yml b/.github/actions/test/integration/test/cloudhypervisor/action.yml
index f3eeabc..078de40 100644
--- a/.github/actions/test/integration/test/cloudhypervisor/action.yml
+++ b/.github/actions/test/integration/test/cloudhypervisor/action.yml
@@ -52,7 +52,14 @@ runs:
IP=\$(virsh -c ch:///session domifaddr VM-CHV | awk '/ipv4/ {print \$4}' | cut -d'/' -f1)
if [ -z "\$IP" ]; then
echo "No IP address found for VM. Retrying..."
- elif ssh \$SSH_OPTS "\$USER@\$IP" 'exit' ; then
+ elif (( i >= MAX_ITER - 2 )); then
+ # Show SSH errors on last 3 attempts for debugging
+ if ssh \$SSH_OPTS "\$USER@\$IP" 'exit'; then
+ echo "VM is up at IP: \$IP"
+ ssh \$SSH_OPTS "\$USER@\$IP" 'echo "Hello, World!" > /opt/hello.txt'
+ break
+ fi
+ elif ssh \$SSH_OPTS "\$USER@\$IP" 'exit' 2>/dev/null; then
echo "VM is up at IP: \$IP"
# create a dummy file for verification later
ssh \$SSH_OPTS "\$USER@\$IP" 'echo "Hello, World!" > /opt/hello.txt'
@@ -60,6 +67,18 @@ runs:
fi
if (( i == MAX_ITER )); then
echo "Timeout waiting for VM to respond to SSH."
+ echo "=== DIAGNOSTICS ==="
+ echo "--- virsh -c ch:///session domifaddr VM-CHV ---"
+ virsh -c ch:///session domifaddr VM-CHV || true
+ echo "--- ip addr show virbr0 ---"
+ ip addr show virbr0 || true
+ echo "--- ip route ---"
+ ip route || true
+ echo "--- arp -n ---"
+ arp -n 2>/dev/null || ip neigh || true
+ echo "--- ssh -v attempt ---"
+ ssh -v \$SSH_OPTS "\$USER@\$IP" 'exit' 2>&1 || true
+ echo "=== END DIAGNOSTICS ==="
exit 1
fi
echo "Waiting for VM to respond to SSH... (\$i/\$MAX_ITER)"
@@ -111,7 +130,7 @@ runs:
MAX_ITER=15
for ((i=1; i<=MAX_ITER; i++)); do
- if ssh \$SSH_OPTS "\$USER@\$IP" 'exit' ; then
+ if ssh \$SSH_OPTS "\$USER@\$IP" 'exit' 2>/dev/null; then
echo "VM is up at IP: \$IP"
# verify the migration by checking the dummy file
if ssh \$SSH_OPTS "\$USER@\$IP" 'test -f /opt/hello.txt'; then
@@ -124,6 +143,14 @@ runs:
fi
if (( i == MAX_ITER )); then
echo "Timeout waiting for VM to respond to SSH."
+ echo "=== DIAGNOSTICS ==="
+ echo "--- ip addr show virbr0 ---"
+ ip addr show virbr0 || true
+ echo "--- ip route ---"
+ ip route || true
+ echo "--- ssh -v attempt ---"
+ ssh -v \$SSH_OPTS "\$USER@\$IP" 'exit' 2>&1 || true
+ echo "=== END DIAGNOSTICS ==="
exit 1
fi
echo "Waiting for VM to respond to SSH... (\$i/\$MAX_ITER)"
diff --git a/.github/actions/test/integration/test/qemu/action.yml b/.github/actions/test/integration/test/qemu/action.yml
index 0dab034..e6887e5 100644
--- a/.github/actions/test/integration/test/qemu/action.yml
+++ b/.github/actions/test/integration/test/qemu/action.yml
@@ -50,6 +50,13 @@ runs:
IP=\$(virsh domifaddr VM-QEMU | awk '/ipv4/ {print \$4}' | cut -d'/' -f1)
if [ -z "\$IP" ]; then
echo "No IP address found for VM. Retrying..."
+ elif (( i >= MAX_ITER - 2 )); then
+ # Show SSH errors on last 3 attempts for debugging
+ if ssh \$SSH_OPTS "\$USER@\$IP" 'exit'; then
+ echo "VM is up at IP: \$IP"
+ ssh \$SSH_OPTS "\$USER@\$IP" 'echo "Hello, World!" > /opt/hello.txt'
+ break
+ fi
elif ssh \$SSH_OPTS "\$USER@\$IP" 'exit' 2>/dev/null; then
echo "VM is up at IP: \$IP"
# create a dummy file for verification later
@@ -58,6 +65,18 @@ runs:
fi
if (( i == MAX_ITER )); then
echo "Timeout waiting for VM to respond to SSH."
+ echo "=== DIAGNOSTICS ==="
+ echo "--- virsh domifaddr VM-QEMU ---"
+ virsh domifaddr VM-QEMU || true
+ echo "--- ip addr show virbr0 ---"
+ ip addr show virbr0 || true
+ echo "--- ip route ---"
+ ip route || true
+ echo "--- arp -n ---"
+ arp -n 2>/dev/null || ip neigh || true
+ echo "--- ssh -v attempt ---"
+ ssh -v \$SSH_OPTS "\$USER@\$IP" 'exit' 2>&1 || true
+ echo "=== END DIAGNOSTICS ==="
exit 1
fi
echo "Waiting for VM to respond to SSH... (\$i/\$MAX_ITER)"
@@ -122,6 +141,14 @@ runs:
fi
if (( i == MAX_ITER )); then
echo "Timeout waiting for VM to respond to SSH."
+ echo "=== DIAGNOSTICS ==="
+ echo "--- ip addr show virbr0 ---"
+ ip addr show virbr0 || true
+ echo "--- ip route ---"
+ ip route || true
+ echo "--- ssh -v attempt ---"
+ ssh -v \$SSH_OPTS "\$USER@\$IP" 'exit' 2>&1 || true
+ echo "=== END DIAGNOSTICS ==="
exit 1
fi
echo "Waiting for VM to respond to SSH... (\$i/\$MAX_ITER)"
diff --git a/.github/actions/test/integration/test/qemu/vm.xml b/.github/actions/test/integration/test/qemu/vm.xml
index 3626dc1..1fe453b 100644
--- a/.github/actions/test/integration/test/qemu/vm.xml
+++ b/.github/actions/test/integration/test/qemu/vm.xml
@@ -15,12 +15,12 @@
-
+
-
+
-
+
diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml
index af0d441..351fed3 100644
--- a/.github/workflows/dev.yml
+++ b/.github/workflows/dev.yml
@@ -3,6 +3,7 @@ on:
push:
branches:
- main
+ - rel-2150-dev
paths-ignore:
- "**/README.md"
- "docs/**"
@@ -26,23 +27,19 @@ jobs:
VERSION: ${{ steps.version.outputs.VERSION }}
steps:
- name: Checkout repository
- uses: actions/checkout@v4
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
submodules: recursive
- name: use VERSION file to support dev build on rel-branch
id: version
run: |
- if [ "${{ github.event_name }}" = "pull_request" ]; then
- echo "VERSION=today" >> $GITHUB_OUTPUT
- else
- echo "VERSION=$(cat VERSION)" >> $GITHUB_OUTPUT
- fi
+ echo "VERSION=$(cat VERSION)" >> $GITHUB_OUTPUT
build:
needs: [set_version]
if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }}
- uses: gardenlinux/gardenlinux/.github/workflows/build.yml@36078a576d0767433423289f2fa217b96cd951c9
+ uses: gardenlinux/gardenlinux/.github/workflows/build.yml@a6e35cf0c955dde584c67163a3a8dff6d60e9d56
with:
version: ${{ needs.set_version.outputs.VERSION }}
# to set target to "release" or "nightly" we need proper KMS secrets
@@ -64,7 +61,7 @@ jobs:
image_tag: ${{ steps.meta.outputs.image_tag }}
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Compute image metadata
id: meta
run: |
@@ -112,7 +109,7 @@ jobs:
response=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
- "https://api.github.com/orgs/gardenlinux/packages/container/gardenlinux-ccloud/versions?per_page=$page_size&page=$page")
+ "https://api.github.com/orgs/gardenlinux/packages/container/gardenlinux-sci/versions?per_page=$page_size&page=$page")
page_ids=$(echo "$response" | jq -r --arg prefix "${UPLOAD_VERSION}" '
.[] | select(.metadata.container.tags[]? | test("^" + $prefix + "(-.*)?$")) | .id
@@ -141,7 +138,7 @@ jobs:
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
- "https://api.github.com/orgs/gardenlinux/packages/container/gardenlinux-ccloud/versions/$version_id")
+ "https://api.github.com/orgs/gardenlinux/packages/container/gardenlinux-sci/versions/$version_id")
if [ "$http_code" != "204" ]; then
echo "Failed to delete version $version_id (HTTP $http_code)"
fi
diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml
index 3157546..e358b1f 100644
--- a/.github/workflows/nightly.yaml
+++ b/.github/workflows/nightly.yaml
@@ -14,12 +14,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
submodules: recursive
build:
needs: [checkout]
- uses: gardenlinux/gardenlinux/.github/workflows/build.yml@36078a576d0767433423289f2fa217b96cd951c9
+ uses: gardenlinux/gardenlinux/.github/workflows/build.yml@a6e35cf0c955dde584c67163a3a8dff6d60e9d56
with:
version: ${{ inputs.version || 'now' }}
# to set target to "release" or "nightly" we need proper KMS secrets
@@ -39,7 +39,7 @@ jobs:
image_tag: ${{ steps.meta.outputs.image_tag }}
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Compute image tag
id: meta
run: |
@@ -49,7 +49,7 @@ jobs:
name: Run glcli to publish to OCI
needs: [build]
# use custom upload_oci.yml as we do not sign the images
- # uses: gardenlinux/gardenlinux/.github/workflows/upload_oci.yml@36078a576d0767433423289f2fa217b96cd951c9
+ # uses: gardenlinux/gardenlinux/.github/workflows/upload_oci.yml@a6e35cf0c955dde584c67163a3a8dff6d60e9d56
uses: ./.github/workflows/upload_oci.yml
with:
version: ${{ needs.build.outputs.version }}
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 729fffd..87ecf16 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -18,9 +18,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Install oras
- uses: oras-project/setup-oras@v1
+ uses: oras-project/setup-oras@1d808f7d7f6995cc68b7bf507bfe5c5446e1dc9d # v2
with:
version: 1.2.2
- name: Validate image tag
@@ -31,8 +31,8 @@ jobs:
fi
echo "Verifying image ${{ inputs.image_tag }} exists in GHCR..."
- if ! digest=$(oras resolve ghcr.io/gardenlinux/gardenlinux-ccloud:${{ inputs.image_tag }} 2>&1); then
- echo "Error: Image tag '${{ inputs.image_tag }}' not found in ghcr.io/gardenlinux/gardenlinux-ccloud"
+ if ! digest=$(oras resolve ghcr.io/gardenlinux/gardenlinux-sci:${{ inputs.image_tag }} 2>&1); then
+ echo "Error: Image tag '${{ inputs.image_tag }}' not found in ghcr.io/gardenlinux/gardenlinux-sci"
echo "Resolve output: $digest"
exit 1
fi
diff --git a/.github/workflows/upload_oci.yml b/.github/workflows/upload_oci.yml
index 4574361..c46c226 100644
--- a/.github/workflows/upload_oci.yml
+++ b/.github/workflows/upload_oci.yml
@@ -14,7 +14,7 @@ on:
jobs:
generate_matrix_publish:
name: Generate flavors matrix to publish
- uses: gardenlinux/gardenlinux/.github/workflows/build_flavors_matrix.yml@36078a576d0767433423289f2fa217b96cd951c9
+ uses: gardenlinux/gardenlinux/.github/workflows/build_flavors_matrix.yml@a6e35cf0c955dde584c67163a3a8dff6d60e9d56
with:
flags: '${{ inputs.flavor_filter }} --no-arch --json-by-arch --build --test'
upload_gl_artifacts:
@@ -37,14 +37,14 @@ jobs:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # pin@v4.1.1
with:
submodules: true
- - uses: oras-project/setup-oras@v1
+ - uses: oras-project/setup-oras@1d808f7d7f6995cc68b7bf507bfe5c5446e1dc9d # v2
- run: oras version
- name: Install python-gardenlinux-lib
- uses: gardenlinux/python-gardenlinux-lib/.github/actions/setup@19c1b24c01faab81a7fe24713748dd172d00904a
+ uses: gardenlinux/python-gardenlinux-lib/.github/actions/setup@efdffb9a6b279cd7aada23b02baf4ec2534dc6d2
- name: Install cosign
- uses: sigstore/cosign-installer@v3.9.1
+ uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
with:
- cosign-release: 'v2.4.1'
+ cosign-release: 'v3.1.3'
- name: Set flavor version reference
run: |
git rev-parse HEAD | cut -c1-8 | tee COMMIT
diff --git a/Containerfile b/Containerfile
new file mode 100644
index 0000000..9893378
--- /dev/null
+++ b/Containerfile
@@ -0,0 +1,3 @@
+FROM ghcr.io/gardenlinux/builder:98ee0d480844b2d041524841bfdbbb4007d32248@sha256:d7063f72c0db3e7cdd618136efb292379794a0c4d4b5ddfc3759795c17d963ab
+
+RUN sed 's/version="$2"/version=\$(echo \$2 | cut -d. -f 1-2).0/' -i /builder/bootstrap
diff --git a/VERSION b/VERSION
deleted file mode 120000
index e96da46..0000000
--- a/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-gardenlinux/VERSION
\ No newline at end of file
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..52dfea6
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+2150.9.0
diff --git a/bin/garden-version b/bin/garden-version
deleted file mode 120000
index d88969e..0000000
--- a/bin/garden-version
+++ /dev/null
@@ -1 +0,0 @@
-../gardenlinux/bin/garden-version
\ No newline at end of file
diff --git a/bin/garden-version b/bin/garden-version
new file mode 100755
index 0000000..c2212f8
--- /dev/null
+++ b/bin/garden-version
@@ -0,0 +1,154 @@
+#!/usr/bin/env bash
+
+# Contains sources from https://github.com/debuerreotype/debuerreotype
+
+set -Eeuo pipefail
+# shellcheck disable=2128
+thisDir="$(dirname "$(readlink -f "${BASH_SOURCE}")")"
+versionfile="$(readlink -f "${thisDir}/../VERSION")"
+startdate="Mar 31 00:00:00 UTC 2020"
+build_os="$(uname -s)"
+
+function check_command() {
+ if ! command -v "$1" >/dev/null 2>&1; then
+ echo "Error: The binary '$1' could not be found. Please make sure to install it." >&2
+ exit 1
+ fi
+}
+
+# Use "gdate" & sed (GNU) which must be installed by "Homebrew"
+# on macOS systems to have a normalized date interface
+if [ "Darwin" == "$build_os" ]; then
+ date_gnu="gdate"
+ sed_gnu="gsed"
+else
+ date_gnu="date"
+ sed_gnu="sed"
+fi
+check_command "$date_gnu"
+check_command "$sed_gnu"
+
+# shellcheck disable=1091
+source "${thisDir}/.constants.sh" \
+ --flags 'major,minor,patch,date,datefull,epoch,git' \
+ --usage '[ --major | --minor | --patch | --date | --datefull | --epoch | --git ] [|]' \
+ --sample '20200427' \
+ --sample '--date 27.1' \
+ --help "Generates version dependent values according to the file $versionfile or to the parameter handed over. Versions can be converted adequately
+
+--major prints only the major version
+--minor prints only the minor version
+--patch prints only the patch/patch version
+--date prints the date according to the version e.g. 20200427 if garden-version=27
+--datefull prints a full date deteministically usable by debootstrap
+--epoch prints the seconds sinc 19700101 till garden-version
+--git prints the version plus the last git-hash
+
+If no parameter is specified the full version . e.g. 27.5 is printed. The version is taken from $versionfile. On HEAD this should always evaluate to 'today', on branch versions this always should resolve to the next version that will be build e.g. 27.1. This implies there is no branch with a .0 in the $versionfile file.
+The version calculated expresses the days since $startdate. Calculation is always UTC based."
+
+# shellcheck disable=2154
+eval "${dgetopt}"
+typeout="default"
+while true; do
+ flag="$1"; shift
+ dgetopt-case "${flag}"
+ case "${flag}" in
+ --major|--minor|--patch|--date|--datefull|--epoch|--git)
+ typeout="${flag}" ;;
+ --) break ;;
+ *) eusage "unknown flag '${flag}'" ;;
+ esac
+done
+
+# Checks repo.gardenlinux.io for the highest available suite minor for the given major
+function get_minor_from_repo {
+ minor=0 # running index
+ limit=100 # hard limit the search in case of unexpected curl results
+ major=$1 # major to check the latest minor for
+ repo_url="https://packages.gardenlinux.io/gardenlinux/dists/$major.__MINOR__/InRelease"
+ while [ $minor -le $limit ]
+ do
+ check_url=${repo_url//__MINOR__/$minor}
+ if curl -s "$check_url" | grep -q "Error"; then
+ ((minor--))
+ echo $minor
+ return
+ fi
+ ((minor++))
+ done
+}
+
+function get_patch_from_repo {
+ # TODO: implement if we really expect that we'll ever have a nonzero micro/patch version
+ local major=$1
+ local minor=$2
+ if [ "$minor" -eq -1 ]; then
+ echo -1
+ return
+ fi
+ echo 0
+ return
+}
+
+function trim_when_old_version {
+ if [ "$1" == "today" ] || [ "$1" == "experimental" ]; then
+ echo "$1"
+ return
+ fi
+ # shellcheck disable=2046
+ if [ $(echo "$1" | cut -d. -f1) -lt 2015 ]; then
+ echo "$1" | cut -d. -f1-2
+ else
+ echo "$1"
+ fi
+}
+
+input="${1:-$($sed_gnu -e "s/#.*\$//" -e "/^$/d" "${versionfile}")}"; shift || true
+input=$($sed_gnu "s/^[[:space:]]*//;s/[[:space:]]*\$//" <<< "${input}")
+
+# no version / timestamp on versionfile
+[ -z "${input}" ] && input="today"
+
+minor=0
+patch=0
+# shellcheck disable=2046
+if [[ "${input}" =~ ^[0-9\.]*$ && $(cut -d. -f1 <<< "${input}") -lt 10000000 ]];
+then [ $(cut -d. -sf4 <<< "${input}") ] && eusage "invalid version format ${input}. should be [..]"
+
+ major="$(cut -d. -f1 <<< "${input}")"
+ # shellcheck disable=2046
+ if [ $(cut -d. -sf2 <<< "${input}") ]; then
+ minor="$(cut -d. -f2 <<< "${input}")"
+ else
+ minor=$(get_minor_from_repo "$major")
+ fi
+ # shellcheck disable=2046
+ if [ $(cut -d. -sf3 <<< "${input}") ]; then
+ patch="$(cut -d. -f3 <<< "${input}")"
+ else
+ patch=$(get_patch_from_repo "$major" "$minor")
+ fi
+ version="${major}.${minor}.${patch}"
+else
+ if [[ ${input} = today ]] || [[ ${input} = experimental ]];
+ then indate=$($date_gnu --date "today" +%s 2>/dev/null)
+ major="$(( ("${indate}" - $($date_gnu --date "${startdate}" +%s)) / (60*60*24) ))"
+ version=${input}
+ else indate=$($date_gnu --date "${input}" +%s 2>/dev/null) || eusage "invalid date ${input}"
+ major="$(( ("${indate}" - $($date_gnu --date "${startdate}" +%s)) / (60*60*24) ))"
+ version="${major}.${minor}.${patch}"
+ fi
+fi
+
+# shellcheck disable=2154
+case "${typeout}" in
+ --major) echo "${major}" ;;
+ --minor) echo "${minor}" ;;
+ --patch) echo "${patch}" ;;
+ --date) $date_gnu --date "${startdate} + ${major} days" +%Y%m%d ;;
+ --datefull) $date_gnu --date "${startdate} + ${major} days" +%Y%m%dT%H%M%SZ ;;
+ --epoch) $date_gnu --date "${startdate} + ${major} days" +%s ;;
+ --git) echo "$(trim_when_old_version "${version}")-$(git -C "${scriptsDir}" rev-parse --short 'HEAD^{commit}')" ;;
+ *) trim_when_old_version "${version}" ;;
+esac
diff --git a/build b/build
deleted file mode 120000
index 9a5480a..0000000
--- a/build
+++ /dev/null
@@ -1 +0,0 @@
-gardenlinux/build
\ No newline at end of file
diff --git a/build b/build
new file mode 100755
index 0000000..ded1dcd
--- /dev/null
+++ b/build
@@ -0,0 +1,182 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+shopt -s nullglob
+
+exec 3>&1
+exec 1>&2
+
+#container_image=ghcr.io/gardenlinux/builder:98ee0d480844b2d041524841bfdbbb4007d32248
+container_image=localhost/builder
+container_engine=podman
+target_dir=.build
+
+container_run_opts=(
+ --memory 4G
+ --security-opt seccomp=unconfined
+ --security-opt apparmor=unconfined
+ --security-opt label=disable
+ --read-only
+)
+
+container_cmd=()
+
+use_kms=0
+resolve_cname=0
+allow_frankenstein=0
+apparmor_profile=
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --allow-frankenstein) # https://xkcd.com/1589/
+ allow_frankenstein=1
+ shift
+ ;;
+ --container-image)
+ container_image="$2"
+ shift 2
+ ;;
+ --container-engine)
+ container_engine="$2"
+ shift 2
+ ;;
+ --container-run-opts)
+ declare -a "container_run_opts=($2)"
+ shift 2
+ ;;
+ --privileged)
+ container_run_opts+=(--privileged)
+ container_cmd=(--second-stage)
+ shift
+ ;;
+ --kms)
+ use_kms=1
+ shift
+ ;;
+ --print-container-image)
+ printf '%s\n' "$container_image" >&3
+ exit 0
+ ;;
+ --resolve-cname)
+ resolve_cname=1
+ shift
+ ;;
+ --target)
+ target_dir="$2"
+ shift 2
+ ;;
+ --apparmor-profile)
+ apparmor_profile="$2"
+ shift 2
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+[ -d "$target_dir" ] || mkdir "$target_dir"
+
+container_mount_opts=(
+ -v "$PWD/keyring.gpg:/builder/keyring.gpg:ro"
+ -v "$(realpath "$target_dir"):/builder/.build"
+)
+
+for feature in features/*; do
+ if [ -d "$feature" ]; then
+ container_mount_opts+=(-v "$(realpath -- "$feature"):/builder/$feature:ro")
+ fi
+done
+
+if [ "$container_image" = localhost/builder ]; then
+ dir="$(dirname -- "$(realpath -- "${BASH_SOURCE[0]}")")"
+ "$container_engine" build -t "$container_image" "$dir"
+fi
+
+repo="$(./get_repo)"
+commit="$(./get_commit)"
+timestamp="$(./get_timestamp)"
+default_version="$(./get_version)"
+
+
+if [ "$resolve_cname" = 1 ]; then
+ arch="$("$container_engine" run --rm "${container_run_opts[@]}" "${container_mount_opts[@]}" "$container_image" dpkg --print-architecture)"
+ cname="$("$container_engine" run --rm "${container_run_opts[@]}" "${container_mount_opts[@]}" "$container_image" /builder/parse_features --feature-dir /builder/features --default-arch "$arch" --default-version "$default_version" --cname "$1")"
+ short_commit="$(head -c 8 <<< "$commit")"
+ echo "$cname-$short_commit" >&3
+ exit 0
+fi
+
+make_opts=(
+ REPO="$repo"
+ COMMIT="$commit"
+ TIMESTAMP="$timestamp"
+ DEFAULT_VERSION="$default_version"
+ LOG_WITH_TIMESTAMP="${LOG_WITH_TIMESTAMP:-true}"
+)
+
+if [ "$allow_frankenstein" = 1 ]; then
+ make_opts+=("ALLOW_FRANKENSTEIN=1")
+fi
+
+if [ "$use_kms" = 1 ]; then
+ for e in AWS_DEFAULT_REGION AWS_REGION AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN; do
+ if [ -n "${!e-}" ]; then
+ make_opts+=("$e=${!e}")
+ fi
+ done
+fi
+
+# Default values which can be overriden via 'build.config' file
+tempfs_size=2G
+
+if [[ -f "$PWD"/build.config ]]; then
+ . "$PWD"/build.config
+fi
+
+make_opts+=("TEMPFS_SIZE=$tempfs_size")
+
+if [ -d cert ]; then
+ container_mount_opts+=(-v "$PWD/cert:/builder/cert:ro")
+fi
+
+# Check if builder apparmor profile has to be created or selected
+if [ "$container_engine" = "docker" ] \
+ && [ ! "$apparmor_profile" ] \
+ && out=$(sysctl kernel.apparmor_restrict_unprivileged_userns 2> /dev/null) \
+ && [[ $out = "kernel.apparmor_restrict_unprivileged_userns = 1" ]]; then
+ if [ ! -f /etc/apparmor.d/builder ]; then
+ echo "You are using Docker on a system restricting unprivileged user namespaces with apparmor, which prevents a successful build. For more information please refer to the #Usage section in the README."
+ read -r -p "Do you want to permanently create a new apparmor profile at /etc/apparmor.d/builder to solve the issue? [Y/n] " response
+ response=${response,,}
+ if [[ "$response" =~ ^(yes|y)$ ]]; then
+ if [ ! -f /etc/apparmor.d/builder ]; then
+ profile="abi , include profile builder flags=(unconfined) {userns, }"
+ echo "$profile" | sudo tee /etc/apparmor.d/builder > /dev/null
+ sudo apparmor_parser -r -W /etc/apparmor.d/builder
+ fi
+ echo "Created profile builder at /etc/apparmor.d/builder"
+ else
+ echo Abort.
+ exit 1
+ fi
+ fi
+ apparmor_profile=builder
+fi
+
+# Apply apparmor profile if seleceted
+if [ "$apparmor_profile" ]; then
+ replaced=false
+ for i in "${!container_run_opts[@]}"; do
+ if [ "${container_run_opts[$i]}" = "apparmor=unconfined" ]; then
+ container_run_opts["$i"]="apparmor=$apparmor_profile"
+ replaced=true
+ fi
+ done
+
+ if ! $replaced; then
+ container_run_opts+=(--security-opt "apparmor=$apparmor_profile")
+ fi
+fi
+
+"$container_engine" run --rm "${container_run_opts[@]}" "${container_mount_opts[@]}" "$container_image" ${container_cmd[@]+"${container_cmd[@]}"} fake_xattr make --no-print-directory -C /builder "${make_opts[@]}" "$@" >&3
diff --git a/features/_archgrouped b/features/_archgrouped
new file mode 120000
index 0000000..fdd2adc
--- /dev/null
+++ b/features/_archgrouped
@@ -0,0 +1 @@
+../gardenlinux/features/_archgrouped
\ No newline at end of file
diff --git a/features/_pxe/file.include/usr/lib/dracut/modules.d/98gardenlinux-live/live-get-squashfs.sh b/features/_pxe/file.include/usr/lib/dracut/modules.d/98gardenlinux-live/live-get-squashfs.sh
index 818d0f3..bc30d2c 100755
--- a/features/_pxe/file.include/usr/lib/dracut/modules.d/98gardenlinux-live/live-get-squashfs.sh
+++ b/features/_pxe/file.include/usr/lib/dracut/modules.d/98gardenlinux-live/live-get-squashfs.sh
@@ -27,7 +27,7 @@ if [ ! -f "${shaFile}" ]; then
exit 1
fi
-if ! echo "$(grep . ${shaFile}) ${squashFile}" | sha256sum --status --check; then
+if ! echo "$(grep . ${shaFile}) ${squashFile}" | sha256sum --status --check -; then
warn "the hash verification of the squashfs has failed - exiting"
exit 1
fi
diff --git a/features/_scicommon/exec.config b/features/_scicommon/exec.config
index 5efda44..d18e272 100755
--- a/features/_scicommon/exec.config
+++ b/features/_scicommon/exec.config
@@ -12,7 +12,7 @@ for feature in "${FEATURES[@]}"; do
done
# capi versions: https://github.com/kubernetes-sigs/cri-tools/releases
-CAPI_VERSION=v1.33.0
+CAPI_VERSION=v1.35.0
K8S_VERSION_REPO="${CAPI_VERSION%.*}"
# key can be downloaded liek e.g.
diff --git a/features/_scicommon/pkg.include b/features/_scicommon/pkg.include
index a8ef404..af58852 100644
--- a/features/_scicommon/pkg.include
+++ b/features/_scicommon/pkg.include
@@ -1 +1,2 @@
gnupg
+openssh-client
diff --git a/features/_scicommon/pkgs-k8s-io_v1.33_release.key b/features/_scicommon/pkgs-k8s-io_v1.35_release.key
similarity index 100%
rename from features/_scicommon/pkgs-k8s-io_v1.33_release.key
rename to features/_scicommon/pkgs-k8s-io_v1.35_release.key
diff --git a/features/_usi/initrd.include/usr/bin/persist b/features/_usi/initrd.include/usr/bin/persist
index 7a6ad93..26fcaca 100755
--- a/features/_usi/initrd.include/usr/bin/persist
+++ b/features/_usi/initrd.include/usr/bin/persist
@@ -75,14 +75,14 @@ export HOME=/root
# source optional config file
[ -f /sysroot/opt/persist/gl-oci.conf ] && . /sysroot/opt/persist/gl-oci.conf
-OCI_REPO="${OCI_REPO:-keppel.global.cloud.sap/ccloud-ghcr-io-mirror/gardenlinux/gardenlinux-ccloud}"
+OCI_REPO="${OCI_REPO:-keppel.global.cloud.sap/ccloud-ghcr-io-mirror/gardenlinux/gardenlinux-sci}"
DASHED_GARDENLINUX_VERSION=${GARDENLINUX_VERSION//./-}
# setup OCI_TAG, UKI_SHA and fetch UKI
OCI_TAG=${OCI_TAG:-"$GARDENLINUX_VERSION-$VARIANT_ID-${DASHED_GARDENLINUX_VERSION}-$GARDENLINUX_COMMIT_ID"}
OCI_TAG=${OCI_TAG//_/-} # replace underscores with dashes
UKI_SHA=$(oras manifest fetch "$OCI_REPO:${OCI_TAG}" | jq -r '.layers[] | select(.mediaType=="application/io.gardenlinux.uki") | .digest')
-oras blob fetch "$OCI_REPO@$UKI_SHA" -o "$esp_dir/EFI/Linux/uki.efi"
+oras blob fetch "$OCI_REPO@$UKI_SHA" -o "$esp_dir/EFI/Linux/${GARDENLINUX_CNAME}.efi"
if [ "$ENABLE_HUGEPAGE_SETUP" = "true" ]; then
echo "hugepagesz=2MB hugepages=$hugepages" > /tmp/cmdlinef
diff --git a/features/sci/exec.config b/features/sci/exec.config
index 3817f6d..5115bba 100755
--- a/features/sci/exec.config
+++ b/features/sci/exec.config
@@ -1,9 +1,34 @@
#!/usr/bin/env bash
+
set -Eeuo pipefail
+# Apply systemd presets
+systemctl preset-all
+
# Undo the gardener feature disablement
systemctl enable ssh
+# install custom packages
+# TODO : these all should go in the repo
+
+# all versions URL encoded
+EDK2_VERSION="20260221-0gl1+bp2150"
+LIBVIRT_VERSION="12.2.0+260825-1gl0+bp2150"
+CLOUD_HYPERVISOR_VERSION="52.1+260825-1gl0+bp2150"
+
+mkdir /tmp/custompackages
+for p in https://github.com/gardenlinux/package-edk2-cloud-hypervisor-gl/releases/download/$EDK2_VERSION/build.tar.xz.0000 https://github.com/gardenlinux/package-libvirt/releases/download/$LIBVIRT_VERSION/build.tar.xz.0000 https://github.com/gardenlinux/package-cloud-hypervisor-gl/releases/download/$CLOUD_HYPERVISOR_VERSION/build.tar.xz.0000; do
+ echo "Downloading and extracting package from $p"
+ wget -q "$p" -O - | xz -d | tar xf - -C /tmp/custompackages
+done
+
+pushd /tmp/custompackages > /dev/null
+rm -f -- *dbgsym* *arm64* || true
+ls -1
+dpkg -i cloud-hypervisor-gl*_amd64.deb edk2-cloud-hypervisor-gl*_amd64.deb libvirt-clients_*_amd64.deb libvirt-common_*_amd64.deb libvirt-daemon_*_amd64.deb libvirt-daemon-common_*_amd64.deb libvirt-daemon-config-network_*_all.deb libvirt-daemon-config-nwfilter_*_all.deb libvirt-daemon-driver-ch-gl_*_amd64.deb libvirt-daemon-driver-network_*_amd64.deb libvirt-daemon-driver-nodedev_*_amd64.deb libvirt-daemon-driver-nwfilter_*_amd64.deb libvirt-daemon-driver-qemu_*_amd64.deb libvirt-daemon-driver-secret_*_amd64.deb libvirt-daemon-driver-storage_*_amd64.deb libvirt-daemon-log_*_amd64.deb libvirt-daemon-system_*_amd64.deb libvirt0_*_amd64.deb
+popd > /dev/null
+rm -rf /tmp/custompackages
+
# UID taken from sles 15, looks like it runs as root in debian/gardenlinux
adduser --uid 476 openvswitch \
--system --group --no-create-home --disabled-password --disabled-login
@@ -15,11 +40,11 @@ function create() {
shift
ID=$1
shift
- adduser --uid $ID --home /var/lib/$NAME $NAME \
+ adduser --uid "$ID" --home "/var/lib/$NAME" "$NAME" \
--system --group --disabled-password --disabled-login
echo "$@"
for group in "$@"; do
- adduser $NAME $group
+ adduser "$NAME" "$group"
done
}
diff --git a/features/sci/pkg.exclude b/features/sci/pkg.exclude
index 1794447..5c0fd1a 100644
--- a/features/sci/pkg.exclude
+++ b/features/sci/pkg.exclude
@@ -1,2 +1,4 @@
frr
-
+libvirt-daemon-system
+libvirt-clients
+libvirt0
diff --git a/features/sci/pkg.include b/features/sci/pkg.include
index 71c8ba3..c7711e0 100644
--- a/features/sci/pkg.include
+++ b/features/sci/pkg.include
@@ -1,6 +1,10 @@
-cloud-hypervisor-gl
-edk2-cloud-hypervisor-gl
-libvirt-daemon-driver-ch-gl
+gettext-base
+libpciaccess0
+libxml2-utils
+mdevctl
multipath-tools
open-iscsi
openvswitch-switch
+systemd-container
+wget
+xz-utils
diff --git a/flavors.yaml b/flavors.yaml
index 6edc213..10617ee 100644
--- a/flavors.yaml
+++ b/flavors.yaml
@@ -2,6 +2,14 @@ targets:
- name: baremetal
category: baremetal
flavors:
+ - features:
+ - chost
+ - _pxe
+ arch: amd64
+ build: true
+ test: true
+ test-platform: false
+ publish: false
- features:
- sci
- _pxe
diff --git a/gardenlinux b/gardenlinux
index 36078a5..a6e35cf 160000
--- a/gardenlinux
+++ b/gardenlinux
@@ -1 +1 @@
-Subproject commit 36078a576d0767433423289f2fa217b96cd951c9
+Subproject commit a6e35cf0c955dde584c67163a3a8dff6d60e9d56
diff --git a/renovate.json b/renovate.json
new file mode 100644
index 0000000..43d8e2a
--- /dev/null
+++ b/renovate.json
@@ -0,0 +1,44 @@
+{
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
+ "customManagers": [
+ {
+ "customType": "regex",
+ "description": "Update libvirt package version for rel-2150-dev",
+ "managerFilePatterns": ["/features/sci/exec\\.config$/"],
+ "matchStrings": [
+ "LIBVIRT_VERSION=\"(?.+)\\+bp2150\""
+ ],
+ "depNameTemplate": "gardenlinux/package-libvirt",
+ "datasourceTemplate": "github-releases",
+ "extractVersionTemplate": "^(?.+)\\+bp2150$",
+ "versioningTemplate": "loose",
+ "autoReplaceStringTemplate": "LIBVIRT_VERSION=\"{{{newValue}}}+bp2150\""
+ },
+ {
+ "customType": "regex",
+ "description": "Update cloud-hypervisor-gl package version for rel-2150-dev",
+ "managerFilePatterns": ["/features/sci/exec\\.config$/"],
+ "matchStrings": [
+ "CLOUD_HYPERVISOR_VERSION=\"(?.+)\\+bp2150\""
+ ],
+ "depNameTemplate": "gardenlinux/package-cloud-hypervisor-gl",
+ "datasourceTemplate": "github-releases",
+ "extractVersionTemplate": "^(?.+)\\+bp2150$",
+ "versioningTemplate": "loose",
+ "autoReplaceStringTemplate": "CLOUD_HYPERVISOR_VERSION=\"{{{newValue}}}+bp2150\""
+ },
+ {
+ "customType": "regex",
+ "description": "Update edk2-cloud-hypervisor-gl package version for rel-2150-dev",
+ "managerFilePatterns": ["/features/sci/exec\\.config$/"],
+ "matchStrings": [
+ "EDK2_VERSION=\"(?.+)\\+bp2150\""
+ ],
+ "depNameTemplate": "gardenlinux/package-edk2-cloud-hypervisor-gl",
+ "datasourceTemplate": "github-releases",
+ "extractVersionTemplate": "^(?.+)\\+bp2150$",
+ "versioningTemplate": "loose",
+ "autoReplaceStringTemplate": "EDK2_VERSION=\"{{{newValue}}}+bp2150\""
+ }
+ ]
+}