From 0ee1ea325f9c2ad67fb2cfb96354d898e1ff7957 Mon Sep 17 00:00:00 2001 From: Mark Yen Date: Wed, 22 Jan 2025 10:51:16 -0800 Subject: [PATCH] WIP: AppImage Smoke --- .github/actions/setup-environment/action.yaml | 17 +- .github/workflows/smoke-test.yaml | 179 ++++++++++++++++++ .github/workflows/smoke-test/smoke-test.sh | 4 +- pkg/rancher-desktop/utils/logging.ts | 2 +- 4 files changed, 197 insertions(+), 5 deletions(-) diff --git a/.github/actions/setup-environment/action.yaml b/.github/actions/setup-environment/action.yaml index c0728d34f44..22cb0a4e2f1 100644 --- a/.github/actions/setup-environment/action.yaml +++ b/.github/actions/setup-environment/action.yaml @@ -56,8 +56,21 @@ runs: if: runner.os == 'Linux' shell: bash run: | - sudo apt-get update - sudo apt-get install pass + source /etc/os-release + for id in $ID $ID_LIKE; do + case $id in + suse|opensuse) + sudo zypper --non-interactive install password-store + break;; + rocky|rhel|centos) + sudo dnf install --assumeyes pass + break;; + debian|ubuntu) + sudo apt-get update + sudo apt-get install pass + break;; + esac + done # Configure the agent to allow default passwords HOMEDIR="$(gpgconf --list-dirs homedir)" # spellcheck-ignore-line diff --git a/.github/workflows/smoke-test.yaml b/.github/workflows/smoke-test.yaml index b7dc56ebb01..d9f81e9653d 100644 --- a/.github/workflows/smoke-test.yaml +++ b/.github/workflows/smoke-test.yaml @@ -24,6 +24,8 @@ jobs: contents: write # Needed to list draft releases env: RELEASE_TAG: ${{ inputs.tag }} + outputs: + release-tag: ${{ steps.find-release.outputs.RELEASE_TAG }} steps: - name: Find release if: inputs.tag == '' @@ -34,6 +36,9 @@ jobs: --jq 'map(select(.draft))[0].tag_name')" env: GH_TOKEN: ${{ github.token }} + - name: Set output + id: find-release + run: echo "RELEASE_TAG=$RELEASE_TAG" >> "$GITHUB_OUTPUT" - name: Download artifacts run: | if [[ -z "$RELEASE_TAG" ]]; then @@ -51,6 +56,18 @@ jobs: env: GH_TOKEN: ${{ github.token }} + - name: Download AppImage + run: | + RELEASE_BRANCH=$(cut -d. -f1,2 <<< "${RELEASE_TAG#v}") + read -r ARTIFACT_NAME < <( + curl "${OBS_DOWNLOAD_URL}?jsontable" \ + | jq --raw-output ".data[].name | select(endswith(\".AppImage\")) | select(contains(\".release${RELEASE_BRANCH}.\"))" + ) + curl -L -o rancher-desktop.AppImage "${OBS_DOWNLOAD_URL}${ARTIFACT_NAME}" + chmod a+x rancher-desktop.AppImage + env: + OBS_DOWNLOAD_URL: https://download.opensuse.org/download/repositories/isv:/Rancher:/dev/AppImage/ + - name: Upload macOS aarch-64 artifacts uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: @@ -83,6 +100,12 @@ jobs: path: | rancher-desktop-linux-*.zip rancher-desktop-linux-*.zip.sha512sum + - name: Upload Linux AppImage + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + with: + name: application-linux.AppImage + if-no-files-found: error + path: rancher-desktop.AppImage smoke-test: name: Smoke test @@ -133,3 +156,159 @@ jobs: name: logs-${{ matrix.platform }}.zip path: ${{ github.workspace }}/logs if-no-files-found: warn + + appimage-smoke-test: + name: Smoke test AppImage + needs: download-artifacts + strategy: + fail-fast: false + matrix: + include: + - { id: opensuse, image: "registry.opensuse.org/opensuse/tumbleweed:latest" } + - { id: rocky, image: "rockylinux/rockylinux:9" } + runs-on: ubuntu-latest + container: + image: ${{ matrix.image }} + options: --privileged + env: + RELEASE_TAG: ${{ needs.download-artifacts.outputs.release-tag }} + steps: + - name: Install dependencies + run: | + source /etc/os-release + for id in $ID $ID_LIKE; do + case $id in + suse|opensuse) + zypper --non-interactive install --recommends \ + fuse gawk git GraphicsMagick gtk3-tools jq mozilla-nss sudo xvfb-run + break;; + rocky|rhel|centos) + dnf install --assumeyes \ + https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm + /usr/bin/crb enable + dnf install --assumeyes \ + at-spi2-atk cups-libs git GraphicsMagick gtk3 jq \ + libva nss procps-ng sudo xorg-x11-server-Xvfb + esac + done + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + - name: Set up environment + uses: ./.github/actions/setup-environment + + - name: Set up user + run: | + set -o xtrace + useradd --create-home --user-group ci-user + export LOGS_DIR=$PWD/logs + export RD_LOGS_DIR=$LOGS_DIR/rd + echo "LOGS_DIR=$LOGS_DIR" >> "$GITHUB_ENV" + echo "RD_LOGS_DIR=$RD_LOGS_DIR" >> "$GITHUB_ENV" + mkdir -p $LOGS_DIR + chown ci-user "$LOGS_DIR" + sudo --user=ci-user mkdir "$RD_LOGS_DIR" + + - name: Download AppImage + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + with: + name: application-linux.AppImage + + - name: Start Rancher Desktop + id: start-rancher-desktop + run: | + set -o xtrace + chmod a+x rancher-desktop.AppImage + INNER_COMMAND=( + xvfb-run + --auto-servernum + --server-args='-screen 0 1280x960x24' + ./rancher-desktop.AppImage + --no-sandbox + --enable-logging=stderr + --v=1 + --no-modal-dialogs + --kubernetes.enabled + ) + sudo --user=ci-user \ + RD_DEBUG_ENABLED=1 RD_LOGS_DIR=$RD_LOGS_DIR RD_TEST=smoke \ + script \ + --log-out $LOGS_DIR/appimage-${{ matrix.id }}.log \ + --command "${INNER_COMMAND[*]@Q}" \ + & + echo "TARGET_PID=$!" >> "$GITHUB_ENV" + - name: Wait for backend + shell: sudo --user=ci-user bash --noprofile --norc -eo pipefail {0} + run: | + set -o xtrace + deadline=$(( $(date +%s) + 10 * 60 )) + state=UNKNOWN + while [[ $(date +%s) -lt $deadline ]]; do + printf "Waiting for backend: (%s) %s/%s\n" "$state" "$(date)" \ + "$({ date --date="@$deadline" || date -j -f %s "$deadline"; } 2>/dev/null)" + + if [[ ! -d /proc/$TARGET_PID ]]; then + echo "Process $TARGET_PID exited" >&2 + exit 1 + fi + RD_PID=$(pidof --separator $'\n' rancher-desktop | sort -n | head -n 1 || echo missing) + if [[ ! -e /proc/$RD_PID/exe ]]; then + state=NOT_RUNNING + sleep 10 + continue + fi + printf "Checking pid %s\n" "$RD_PID" + if [[ ! -e $HOME/.local/share/rancher-desktop/rd-engine.json ]]; then + state=NO_SERVER_CONFIG + sleep 10 + continue + fi + RD_EXE=$(readlink /proc/$RD_PID/exe) + RD_DIR=$(dirname "$RD_EXE") + RDCTL=${RD_DIR}/resources/resources/linux/bin/rdctl + state=$("$RDCTL" api /v1/backend_state || echo '{"vmState": "NO_RESPONSE"}') + state=$(jq --raw-output .vmState <<< "$state") + case "$state" in + ERROR) + echo "Backend reached error state." >&2 + exit 1;; + STARTED|DISABLED) + exit 0;; + *) + printf "Backend state: %s\n" "$state";; + esac + sleep 10 + done + + echo "Timed out waiting for backend to stabilize." >&2 + printf "Current time: %s\n" "$(date)" >&2 + printf "Deadline: %s\n" >&2 \ + "$({ date --date="@$deadline" || date -j -f %s "$deadline"; } 2>/dev/null)" + exit 1 + + - name: Take screenshot + if: failure() && steps.start-rancher-desktop.outcome == 'success' + continue-on-error: true + shell: >- + sudo --user=ci-user LOGS_DIR=$LOGS_DIR + bash --noprofile --norc -eo pipefail {0} + run: | + set -o xtrace -o errexit + PID=$(pidof rancher-desktop.AppImage || echo missing) + if [[ ! -r /proc/$PID/environ ]]; then + echo "Rancher Desktop is not running" >&2 + exit 0 + fi + export $(gawk 'BEGIN { RS="\0"; FS="=" } ($1 == "DISPLAY" || $1 == "XAUTHORITY") { print }' \ + < /proc/$PID/environ) + env + export MAGICK_DEBUG=All + gm import -window root -verbose $LOGS_DIR/screenshot-${{ matrix.id }}.png + + - name: Upload logs + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + if: always() + with: + name: logs-appimage-${{ matrix.id }}.zip + path: ${{ github.workspace }}/logs + if-no-files-found: warn diff --git a/.github/workflows/smoke-test/smoke-test.sh b/.github/workflows/smoke-test/smoke-test.sh index adc87793ea8..90d72b5d277 100755 --- a/.github/workflows/smoke-test/smoke-test.sh +++ b/.github/workflows/smoke-test/smoke-test.sh @@ -202,7 +202,7 @@ wait_for_backend() { deadline=$(( $(date +%s) + 10 * 60 )) while [[ $(date +%s) -lt $deadline ]]; do - state=$("$RDCTL" api /v1/backend_state || echo '{"vmState": "UNREADY"}') + state=$("$RDCTL" api /v1/backend_state || echo '{"vmState": "NO_RESPONSE"}') state=$(jq --raw-output .vmState <<< "$state") case "$state" in ERROR) @@ -215,7 +215,7 @@ wait_for_backend() { esac # if we get here, either we failed to get state or it's starting. - printf "Waiting for backend: %s/%s\n" "$(date)" \ + printf "Waiting for backend: (%s) %s/%s\n" "$state" "$(date)" \ "$({ date --date="@$deadline" || date -j -f %s "$deadline"; } 2>/dev/null)" sleep 10 done diff --git a/pkg/rancher-desktop/utils/logging.ts b/pkg/rancher-desktop/utils/logging.ts index 8c369e331ac..ed3b968572d 100644 --- a/pkg/rancher-desktop/utils/logging.ts +++ b/pkg/rancher-desktop/utils/logging.ts @@ -197,7 +197,7 @@ export default new Proxy({}, { * the system, so that logs from another instance are not deleted. */ export function clearLoggingDirectory(): void { - if (process.env.RD_TEST === 'e2e' || process.type !== 'browser') { + if (process.env.RD_TEST || process.type !== 'browser') { return; }