mirror of
https://github.com/outbackdingo/cozystack.git
synced 2026-01-27 10:18:39 +00:00
[tests] Introduce self destructing environments
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
This commit is contained in:
53
.github/workflows/pull-requests.yaml
vendored
53
.github/workflows/pull-requests.yaml
vendored
@@ -44,6 +44,17 @@ jobs:
|
||||
|
||||
- name: Build Talos image
|
||||
run: make -C packages/core/installer talos-nocloud
|
||||
|
||||
- name: Save git diff as patch
|
||||
if: "!contains(github.event.pull_request.labels.*.name, 'release')"
|
||||
run: git diff HEAD > _out/assets/pr.patch
|
||||
|
||||
- name: Upload git diff patch
|
||||
if: "!contains(github.event.pull_request.labels.*.name, 'release')"
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: pr-patch
|
||||
path: _out/assets/pr.patch
|
||||
|
||||
- name: Upload installer
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -126,6 +137,10 @@ jobs:
|
||||
if: ${{ always() && (needs.build.result == 'success' || needs.resolve_assets.result == 'success') }}
|
||||
|
||||
steps:
|
||||
# ▸ Checkout and prepare the codebase
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# ▸ Regular PR path – download artefacts produced by the *build* job
|
||||
- name: "Download Talos image (regular PR)"
|
||||
if: "!contains(github.event.pull_request.labels.*.name, 'release')"
|
||||
@@ -134,6 +149,17 @@ jobs:
|
||||
name: talos-image
|
||||
path: _out/assets
|
||||
|
||||
- name: Download PR patch
|
||||
if: "!contains(github.event.pull_request.labels.*.name, 'release')"
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: pr-patch
|
||||
path: _out/assets
|
||||
|
||||
- name: Apply patch
|
||||
if: "!contains(github.event.pull_request.labels.*.name, 'release')"
|
||||
run: |
|
||||
git apply _out/assets/pr.patch
|
||||
|
||||
# ▸ Release PR path – fetch artefacts from the corresponding draft release
|
||||
- name: Download assets from draft release (release PR)
|
||||
@@ -145,23 +171,15 @@ jobs:
|
||||
env:
|
||||
GH_PAT: ${{ secrets.GH_PAT }}
|
||||
|
||||
# ▸ Start actual job steps
|
||||
- name: Set sandbox ID
|
||||
run: echo "SANDBOX_NAME=cozy-e2e-sandbox-$(echo "${GITHUB_REPOSITORY}:${GITHUB_WORKFLOW}:${GITHUB_REF}" | sha256sum | cut -c1-10)" >> $GITHUB_ENV
|
||||
|
||||
# ▸ Start actual job steps
|
||||
- name: Prepare workspace
|
||||
run: |
|
||||
cd ..
|
||||
rm -rf /tmp/$SANDBOX_NAME
|
||||
cp -r cozystack /tmp/$SANDBOX_NAME
|
||||
sudo systemctl stop "rm-workspace-$SANDBOX_NAME.timer" "rm-workspace-$SANDBOX_NAME.service" 2>/dev/null || true
|
||||
sudo systemctl reset-failed "rm-workspace-$SANDBOX_NAME.timer" "rm-workspace-$SANDBOX_NAME.service" 2>/dev/null || true
|
||||
sudo systemctl daemon-reexec
|
||||
sudo systemd-run \
|
||||
--on-calendar="$(date -d 'now + 24 hours' '+%Y-%m-%d %H:%M:%S')" \
|
||||
--unit=rm-workspace-$SANDBOX_NAME \
|
||||
rm -rf /tmp/$SANDBOX_NAME
|
||||
|
||||
cp -r ${{ github.workspace }} /tmp/$SANDBOX_NAME
|
||||
|
||||
- name: Prepare environment
|
||||
run: |
|
||||
cd /tmp/$SANDBOX_NAME
|
||||
@@ -202,6 +220,11 @@ jobs:
|
||||
- name: Set sandbox ID
|
||||
run: echo "SANDBOX_NAME=cozy-e2e-sandbox-$(echo "${GITHUB_REPOSITORY}:${GITHUB_WORKFLOW}:${GITHUB_REF}" | sha256sum | cut -c1-10)" >> $GITHUB_ENV
|
||||
|
||||
- name: Sync _out/assets directory
|
||||
run: |
|
||||
mkdir -p /tmp/$SANDBOX_NAME/_out/assets
|
||||
mv _out/assets/* /tmp/$SANDBOX_NAME/_out/assets/
|
||||
|
||||
- name: Install Cozystack into sandbox
|
||||
run: |
|
||||
cd /tmp/$SANDBOX_NAME
|
||||
@@ -259,11 +282,3 @@ jobs:
|
||||
|
||||
- name: Remove workspace
|
||||
run: rm -rf /tmp/$SANDBOX_NAME
|
||||
|
||||
- name: Tear down timers
|
||||
run: |
|
||||
sudo systemctl stop "rm-workspace-$SANDBOX_NAME.timer" "rm-workspace-$SANDBOX_NAME.service" 2>/dev/null || true
|
||||
sudo systemctl reset-failed "rm-workspace-$SANDBOX_NAME.timer" "rm-workspace-$SANDBOX_NAME.service" 2>/dev/null || true
|
||||
sudo systemctl stop "teardown-$SANDBOX_NAME.timer" "teardown-$SANDBOX_NAME.service" 2>/dev/null || true
|
||||
sudo systemctl reset-failed "teardown-$SANDBOX_NAME.timer" "teardown-$SANDBOX_NAME.service" 2>/dev/null || true
|
||||
sudo systemctl daemon-reexec
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
@test "Required installer assets exist" {
|
||||
if [ ! -f _out/assets/cozystack-installer.yaml ]; then
|
||||
echo "Missing: _out/assets/cozystack-installer.yaml" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
@test "Install Cozystack" {
|
||||
# Create namespace & configmap required by installer
|
||||
kubectl create namespace cozy-system --dry-run=client -o yaml | kubectl apply -f -
|
||||
|
||||
@@ -4,11 +4,6 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
@test "Required installer assets exist" {
|
||||
if [ ! -f _out/assets/cozystack-installer.yaml ]; then
|
||||
echo "Missing: _out/assets/cozystack-installer.yaml" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f _out/assets/nocloud-amd64.raw.xz ]; then
|
||||
echo "Missing: _out/assets/nocloud-amd64.raw.xz" >&2
|
||||
exit 1
|
||||
|
||||
@@ -15,7 +15,7 @@ help: ## Show this help.
|
||||
image: image-e2e-sandbox
|
||||
|
||||
image-e2e-sandbox:
|
||||
docker buildx build -f images/e2e-sandbox/Dockerfile ../../.. \
|
||||
docker buildx build -f images/e2e-sandbox/Dockerfile images/e2e-sandbox \
|
||||
--provenance false \
|
||||
--builder=$(BUILDER) \
|
||||
--platform=$(PLATFORM) \
|
||||
@@ -62,5 +62,5 @@ apply: delete
|
||||
-e TALOSCONFIG=/workspace/talosconfig \
|
||||
-e KUBECONFIG=/workspace/kubeconfig \
|
||||
"$$(yq .e2e.image values.yaml)" \
|
||||
sleep infinity
|
||||
--timeout 30m
|
||||
docker cp "${ROOT_DIR}" "${SANDBOX_NAME}":/workspace
|
||||
|
||||
@@ -19,3 +19,6 @@ RUN curl -sSL "https://github.com/mikefarah/yq/releases/download/v4.44.3/yq_${TA
|
||||
&& chmod +x /usr/local/bin/yq
|
||||
RUN curl -sSL "https://fluxcd.io/install.sh" | bash
|
||||
RUN curl -sSL "https://github.com/cozystack/cozypkg/raw/refs/heads/main/hack/install.sh" | sh -s -- -v "${COZYPKG_VERSION}"
|
||||
|
||||
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||
|
||||
80
packages/core/testing/images/e2e-sandbox/entrypoint.sh
Executable file
80
packages/core/testing/images/e2e-sandbox/entrypoint.sh
Executable file
@@ -0,0 +1,80 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
SELF_PID="$$"
|
||||
INTERVAL=30m
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--timeout)
|
||||
INTERVAL="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 [--timeout SECONDS]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
ALL_PROCS=$(ps -eo pid=,ppid=,comm=)
|
||||
|
||||
get_descendants() {
|
||||
PARENT="$1"
|
||||
echo "$PARENT"
|
||||
echo "$ALL_PROCS" | while read -r PID PPID CMD; do
|
||||
PID=$(echo "$PID" | tr -d ' ')
|
||||
PPID=$(echo "$PPID" | tr -d ' ')
|
||||
if [ "$PPID" = "$PARENT" ]; then
|
||||
echo "$PID"
|
||||
get_descendants "$PID"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
is_own_tree() {
|
||||
PID="$1"
|
||||
echo "$DESCENDANTS" | grep -q -x "$PID"
|
||||
}
|
||||
|
||||
check_once() {
|
||||
DESCENDANTS="$(get_descendants "$SELF_PID" | sort -u)"
|
||||
EXTERNAL_PIDS=$(
|
||||
echo "$ALL_PROCS" | while read -r PID PPID CMD; do
|
||||
PID=$(echo "$PID" | tr -d ' ')
|
||||
CMD=$(echo "$CMD" | tr -d ' ')
|
||||
|
||||
if is_own_tree "$PID"; then
|
||||
continue
|
||||
fi
|
||||
|
||||
case "$CMD" in
|
||||
*qemu*) continue ;;
|
||||
esac
|
||||
|
||||
echo "PID=$PID CMD=$CMD"
|
||||
done
|
||||
)
|
||||
|
||||
COUNT=$(echo "$EXTERNAL_PIDS" | wc -w)
|
||||
echo "$EXTERNAL_PIDS"
|
||||
[ "$COUNT" -eq 0 ]
|
||||
}
|
||||
|
||||
check_loop() {
|
||||
while :; do
|
||||
ALL_PROCS=$(ps -eo pid=,ppid=,comm=)
|
||||
|
||||
if check_once; then
|
||||
echo "No external processes, exiting..."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "External processes still running, next check in ${INTERVAL}..."
|
||||
sleep "$INTERVAL"
|
||||
done
|
||||
}
|
||||
|
||||
echo "Waiting for external processes to be started, next check in ${INTERVAL}..."
|
||||
sleep "$INTERVAL"
|
||||
check_loop
|
||||
@@ -1,2 +1,2 @@
|
||||
e2e:
|
||||
image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.32.1@sha256:b15f85e58be54529d74ab7056d5d47960944abde28f14611e88156989a19c789
|
||||
image: ghcr.io/cozystack/cozystack/e2e-sandbox:latest@sha256:df79b508c45ab11f728dfb12b5b984c04f64ea5c26cf239095913aa7fc9f73aa
|
||||
|
||||
Reference in New Issue
Block a user