diff --git a/.dockerignore b/.dockerignore new file mode 100755 index 000000000..6b9aac938 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +node_modules/ +.vite/ +out/ diff --git a/.github/workflows/e2e-test-linux-distros.yml b/.github/workflows/e2e-test-linux-distros.yml index 741728645..44fe5515e 100644 --- a/.github/workflows/e2e-test-linux-distros.yml +++ b/.github/workflows/e2e-test-linux-distros.yml @@ -1,9 +1,7 @@ name: e2e-tests-linux-distros +# Currently does not work as running podman within a container is not straighforward on: - pull_request: - branches: - - main workflow_dispatch: jobs: diff --git a/.github/workflows/e2e-test-specs.yml b/.github/workflows/e2e-test-specs.yml new file mode 100644 index 000000000..5d652b056 --- /dev/null +++ b/.github/workflows/e2e-test-specs.yml @@ -0,0 +1,42 @@ +name: e2e-tests-specs + +on: + pull_request: + branches: + - main + workflow_dispatch: + +jobs: + e2e-build-n-test: + environment: staging + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + + steps: + - uses: actions/checkout@v4 + - name: 🧱 Install Dependencies + run: | + sudo apt-get update + sudo apt-get install --no-install-recommends -y podman + + - name: 📦 Bundle Application + env: + DEBUG: "*electron*" + SENTRY_DSN: fake-token + MP_PROJECT_TOKEN: fake-token + MP_PROJECT_ENV: dev + NICENODE_ENV: test + NO_CODE_SIGNING: true + run: | + ls -al + podman build -t podman-fedora-wdio -f ./test/podman-fedora-wdio.dockerfile . + + - name: 🧪 Run Tests + run: | + ls -al + chmod -R 777 . + ls -al + podman run --rm -v ./:/home/podman/nice-node -u podman podman-fedora-wdio + diff --git a/.github/workflows/e2e-test-ubuntu.yml b/.github/workflows/e2e-test-ubuntu.yml index 70b5434cb..9ac88fb36 100644 --- a/.github/workflows/e2e-test-ubuntu.yml +++ b/.github/workflows/e2e-test-ubuntu.yml @@ -12,7 +12,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest] + os: [ubuntu-24.04] node-version: [20.x] steps: @@ -25,7 +25,7 @@ jobs: - name: 🧱 Install Dependencies run: | sudo apt-get update - sudo apt-get install --no-install-recommends -y rpm libarchive-tools + sudo apt-get install --no-install-recommends -y podman npm ci - name: 📦 Bundle Application @@ -37,7 +37,7 @@ jobs: NICENODE_ENV: ${{ vars.NICENODE_ENV }} NO_CODE_SIGNING: true run: | - npm run make + npm run package -- --arch=x64 - name: 🧪 Run Tests uses: coactions/setup-xvfb@6b00cf1889f4e1d5a48635647013c0508128ee1a diff --git a/src/main/ports.ts b/src/main/ports.ts index 0c5817c4b..3562c4cdb 100644 --- a/src/main/ports.ts +++ b/src/main/ports.ts @@ -4,9 +4,9 @@ import type { ConfigValue } from '../common/nodeConfig'; import { NOTIFICATIONS } from './consts/notifications'; import { httpGet } from './httpReq'; import { getNodePackageByServiceNodeId } from './state/nodePackages'; +import { getNodePackages } from './state/nodePackages'; import { getNode, getNodes, getSetPortHasChanged } from './state/nodes'; import { addNotification } from './state/notifications'; -import { getNodePackages } from './state/nodePackages'; export const getPodmanPortsForNode = ( node: Node, diff --git a/test/containers.conf b/test/containers.conf new file mode 100755 index 000000000..220c1f850 --- /dev/null +++ b/test/containers.conf @@ -0,0 +1,12 @@ +[containers] +netns="host" +userns="host" +ipcns="host" +utsns="host" +cgroupns="host" +cgroups="disabled" +log_driver = "k8s-file" +[engine] +cgroup_manager = "cgroupfs" +events_logger="file" +runtime="crun" diff --git a/test/debian12.dockerfile b/test/debian12.dockerfile new file mode 100755 index 000000000..b5b6d22f5 --- /dev/null +++ b/test/debian12.dockerfile @@ -0,0 +1,19 @@ +FROM debian:12 + +RUN apt-get update -qq + +RUN apt-get install --no-install-recommends -y nodejs npm git zip dpkg fakeroot rpm libarchive-tools +RUN apt-get install -y \ + xvfb \ + zip \ + wget \ + ca-certificates \ + libnss3-dev \ + libasound2t64 \ + libxss1 \ + libappindicator3-1 \ + libindicator7 \ + xdg-utils \ + fonts-liberation \ + libgbm1 + diff --git a/test/fedora40.dockerfile b/test/fedora40.dockerfile new file mode 100755 index 000000000..abed809eb --- /dev/null +++ b/test/fedora40.dockerfile @@ -0,0 +1,46 @@ +FROM fedora:40 + +RUN dnf update -y + +RUN dnf install podman -y + +# RUN apt-get install --no-install-recommends -y nodejs npm git zip dpkg fakeroot rpm libarchive-tools +# RUN apt-get install -y \ +# xvfb \ +# zip \ +# wget \ +# ca-certificates \ +# libnss3-dev \ +# libasound2t64 \ +# libxss1 \ +# libappindicator3-1 \ +# libindicator7 \ +# xdg-utils \ +# fonts-liberation \ +# libgbm1 + +# Create a new user and set its password +# RUN useradd -ms /bin/bash -g root -u 1000 myuser \ +# && echo "myuser:password" | chpasswd + +# Create a new group for Podman +RUN groupadd --system podman + +# Create a new user and group for running Podman within the container +ARG USERNAME=podman-user +ARG USER_UID=1000 +ARG GROUP_GID=1000 +RUN groupadd -g ${GROUP_GID} ${USERNAME} && \ + useradd -u ${USER_UID} -g ${GROUP_GID} -m ${USERNAME} + +# Add the user to the 'podman' group +RUN usermod -aG podman ${USERNAME} + +# Switch to the new user +USER ${USERNAME} + +# Set the working directory to the user's home directory +WORKDIR /home/${USERNAME} + +# Example command to run when the container starts +CMD ["/bin/bash"] diff --git a/test/podman-containers.conf b/test/podman-containers.conf new file mode 100755 index 000000000..2bdd95a3b --- /dev/null +++ b/test/podman-containers.conf @@ -0,0 +1,5 @@ +[containers] +volumes = [ + "/proc:/proc", +] +default_sysctls = [] diff --git a/test/podman-fedora-wdio.dockerfile b/test/podman-fedora-wdio.dockerfile new file mode 100755 index 000000000..601364828 --- /dev/null +++ b/test/podman-fedora-wdio.dockerfile @@ -0,0 +1,126 @@ +# podman/Containerfile +# +# Build a Podman container image from the latest +# stable version of Podman on the Fedoras Updates System. +# https://bodhi.fedoraproject.org/updates/?search=podman +# This image can be used to create a secured container +# that runs safely with privileges within the container. +# +# FLAVOR defaults to stable if unset +# +# FLAVOR=stable acquires a stable version of Podman +# from the Fedoras Updates System. +# FLAVOR=testing acquires a testing version of Podman +# from the Fedoras Updates System. +# FLAVOR=upstream acquires a testing version of Podman +# from the Fedora Copr Buildsystem. +# https://copr.fedorainfracloud.org/coprs/rhcontainerbot/podman-next/ +# +# https://bodhi.fedoraproject.org/updates/?search=podman + +FROM registry.fedoraproject.org/fedora:latest +ARG FLAVOR=stable + +# When building for multiple-architectures in parallel using emulation +# it's really easy for one/more dnf processes to timeout or mis-count +# the minimum download rates. Bump both to be extremely forgiving of +# an overworked host. +RUN echo -e "\n\n# Added during image build" >> /etc/dnf/dnf.conf && \ + echo -e "minrate=100\ntimeout=60\n" >> /etc/dnf/dnf.conf + +# Don't include container-selinux and remove +# directories used by dnf that are just taking +# up space. +# TODO: rpm --setcaps... needed due to Fedora (base) image builds +# being (maybe still?) affected by +# https://bugzilla.redhat.com/show_bug.cgi?id=1995337#c3 +RUN dnf -y makecache && \ + dnf -y update && \ + rpm --setcaps shadow-utils 2>/dev/null && \ + case "${FLAVOR}" in \ + stable) \ + dnf -y install podman fuse-overlayfs openssh-clients --exclude container-selinux \ + ;; \ + testing) \ + dnf -y install podman fuse-overlayfs openssh-clients --exclude container-selinux \ + --enablerepo updates-testing \ + ;; \ + upstream) \ + dnf -y install 'dnf-command(copr)' --enablerepo=updates-testing && \ + dnf -y copr enable rhcontainerbot/podman-next && \ + dnf -y install podman fuse-overlayfs openssh-clients \ + --exclude container-selinux \ + --enablerepo=updates-testing \ + ;; \ + *) \ + printf "\\nFLAVOR argument must be set and valid, currently: '${FLAVOR}'\\n\\n" 1>&2 && \ + exit 1 \ + ;; \ + esac && \ + dnf clean all && \ + rm -rf /var/cache /var/log/dnf* /var/log/yum.* + +RUN useradd podman; \ +echo -e "podman:1:999\npodman:1001:64535" > /etc/subuid; \ +echo -e "podman:1:999\npodman:1001:64535" > /etc/subgid; + +ADD /test/containers.conf /etc/containers/containers.conf +ADD /test/podman-containers.conf /home/podman/.config/containers/containers.conf + +RUN mkdir -p /home/podman/.local/share/containers && \ + chown podman:podman -R /home/podman && \ + chmod 644 /etc/containers/containers.conf + +# Copy & modify the defaults to provide reference if runtime changes needed. +# Changes here are required for running with fuse-overlay storage inside container. +RUN sed -e 's|^#mount_program|mount_program|g' \ + -e '/additionalimage.*/a "/var/lib/shared",' \ + -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' \ + /usr/share/containers/storage.conf \ + > /etc/containers/storage.conf + +# Setup internal Podman to pass subscriptions down from host to internal container +RUN printf '/run/secrets/etc-pki-entitlement:/run/secrets/etc-pki-entitlement\n/run/secrets/rhsm:/run/secrets/rhsm\n' > /etc/containers/mounts.conf + +# Note VOLUME options must always happen after the chown call above +# RUN commands can not modify existing volumes +VOLUME /var/lib/containers +VOLUME /home/podman/.local/share/containers + +RUN mkdir -p /var/lib/shared/overlay-images \ + /var/lib/shared/overlay-layers \ + /var/lib/shared/vfs-images \ + /var/lib/shared/vfs-layers && \ + touch /var/lib/shared/overlay-images/images.lock && \ + touch /var/lib/shared/overlay-layers/layers.lock && \ + touch /var/lib/shared/vfs-images/images.lock && \ + touch /var/lib/shared/vfs-layers/layers.lock + +ENV _CONTAINERS_USERNS_CONFIGURED="" \ + BUILDAH_ISOLATION=chroot + + +# My additions to the podman official podman-in-podman image +# can be built and run with: +# podman build -t podman-fedora-wdio -f ./test/podman-fedora-wdio.dockerfile . +# podman run --rm -v ./:/home/podman/nice-node -u podman podman-fedora-wdio + +RUN dnf install -y nodejs npm git zip dpkg fakeroot rpmdevtools sudo +RUN dnf install -y nss nss-tools libxcb xorg-x11-server-Xvfb dbus-devel atk-devel at-spi2-atk cups-libs gtk3-devel + +RUN mkdir /home/podman/nice-node +WORKDIR /home/podman/nice-node + + +# Allow 'podman' user to run sudo without password (useful for manually installing packages) +RUN echo "podman ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/podman +RUN echo "podman:password" | chpasswd + +CMD ["bash", "-c", "npm install --loglevel=info && npm run package -- --arch=x64 && xvfb-run npm run wdio"] + +# # Start the Xvfb server Is currently not needed +# export DISPLAY=':99.0' +# xvfb-run :99 -screen 0 1024x768x24 > /dev/null 2>&1 & + + + diff --git a/test/specs/test.e2e.ts b/test/specs/test.e2e.ts index 3bc7f8edc..48d070427 100644 --- a/test/specs/test.e2e.ts +++ b/test/specs/test.e2e.ts @@ -78,65 +78,66 @@ describe('Splash screen tests', () => { // todo: fix these tests so they can successfully run within a container // uncomment to run locally // process.env.CI = 'true'; - // if(os.platform() === 'linux' || (os.platform() === 'darwin' && process.env.CI === 'true')) { - // // from splash screen, we always show podman screen - // it('clicking continue btn should add and start the node', async () => { - // await browser.pause(2000); - // if(!isPodmanIsInstalled) { - // // click install and or start podman button - // try { - // if($('#downloadAndInstallPodmanBtn').isDisplayed()) { - // await $('#downloadAndInstallPodmanBtn').click(); - // const startNodeBtn = await $('#stepperNextButton'); - // await browser.pause(30000); // pauses 30 seconds before checking if podman installed - // // biome-ignore lint/complexity/useArrowFunction: - // await browser.waitUntil(async function () { - // const elPodmanInstallCompleteTitle = await $("#podmanInstallCompleteTitle"); - // return elPodmanInstallCompleteTitle.isDisplayed(); - // }, { timeout: 300000 }); // allow 5 min for podman install - // // start podman may not be shown, should be done automatically, and it is now that NN tries to start on startup - // // await browser.waitUntil(async () => { - // // return (await startNodeBtn.getAttribute('disabled') !== 'true') - // // }) - // // await browser.pause(50000); - // } - // } catch(e) { - // console.log("no download and install button, moving on to start podman") - // } - - // // if((await $('#startPodmanBtn')).isDisplayed()) { - // // await $('#startPodmanBtn').click(); - // // // await browser.pause(50000); - // // } - // // todo: wait for next button to be enabled? - // } - // await $('#stepperNextButton').click(); - // await browser.pause(2000); - // }).timeout(120000); // wait 3 minutes for the podman to download (& start) - - // it('Ethereum Node screen should be displayed with syncing and stop btn', async () => { - // await expect(await $('div*=Ethereum Node')).toBeDisplayed(); - // await expect(await $('div*=Syncing')).toBeDisplayed(); - // await expect(await $('span*=Stop')).toBeDisplayed(); - // // after docker containers are downloaded and the node is started, the node should be online - // // await expect(await $('div*=Online')).toBeDisplayed(); - // }).timeout(120000); // wait 3 minutes for the node to download & start - - // it('clicking stop node btn should stop the node and show resume button', async () => { - // const stopBtn = (await $('span*=Stop')).parentElement(); - // (await stopBtn).click(); - // // await browser.pause(15000); - // // await expect(await $('div*=Stopping')).toBeDisplayed(); - // // ... - // await expect(await $('div*=Stopped')).toBeDisplayed(); - // await expect(await $('span*=Resume')).toBeDisplayed(); - // // await browser.pause(15000); - // // await browser.pause(2000); - // // after docker containers are downloaded and the node is started, the node should be online - // // await expect(await $('div*=Online')).toBeDisplayed(); - // // await expect(await $('div*=')).toBeDisplayed(); - // }).timeout(120000); // wait 3 minutes for the node to download & start - // } + // || (os.platform() === 'darwin' && process.env.CI === 'true') + if(os.platform() === 'linux') { + // from splash screen, we always show podman screen + it('clicking continue btn should add and start the node', async () => { + await browser.pause(2000); + if(!isPodmanIsInstalled) { + // click install and or start podman button + try { + if($('#downloadAndInstallPodmanBtn').isDisplayed()) { + await $('#downloadAndInstallPodmanBtn').click(); + const startNodeBtn = await $('#stepperNextButton'); + await browser.pause(30000); // pauses 30 seconds before checking if podman installed + // biome-ignore lint/complexity/useArrowFunction: + await browser.waitUntil(async function () { + const elPodmanInstallCompleteTitle = await $("#podmanInstallCompleteTitle"); + return elPodmanInstallCompleteTitle.isDisplayed(); + }, { timeout: 300000 }); // allow 5 min for podman install + // start podman may not be shown, should be done automatically, and it is now that NN tries to start on startup + // await browser.waitUntil(async () => { + // return (await startNodeBtn.getAttribute('disabled') !== 'true') + // }) + // await browser.pause(50000); + } + } catch(e) { + console.log("no download and install button, moving on to start podman") + } + + // if((await $('#startPodmanBtn')).isDisplayed()) { + // await $('#startPodmanBtn').click(); + // // await browser.pause(50000); + // } + // todo: wait for next button to be enabled? + } + await $('#stepperNextButton').click(); + await browser.pause(2000); + }).timeout(120000); // wait 3 minutes for the podman to download (& start) + + it('Ethereum Node screen should be displayed with syncing and stop btn', async () => { + await expect(await $('div*=Ethereum Node')).toBeDisplayed(); + await expect(await $('div*=Syncing')).toBeDisplayed(); + await expect(await $('span*=Stop')).toBeDisplayed(); + // after docker containers are downloaded and the node is started, the node should be online + // await expect(await $('div*=Online')).toBeDisplayed(); + }).timeout(120000); // wait 3 minutes for the node to download & start + + it('clicking stop node btn should stop the node and show resume button', async () => { + const stopBtn = (await $('span*=Stop')).parentElement(); + (await stopBtn).click(); + // await browser.pause(15000); + // await expect(await $('div*=Stopping')).toBeDisplayed(); + // ... + await expect(await $('div*=Stopped')).toBeDisplayed(); + await expect(await $('span*=Resume')).toBeDisplayed(); + // await browser.pause(15000); + // await browser.pause(2000); + // after docker containers are downloaded and the node is started, the node should be online + // await expect(await $('div*=Online')).toBeDisplayed(); + // await expect(await $('div*=')).toBeDisplayed(); + }).timeout(120000); // wait 3 minutes for the node to download & start + } }); diff --git a/test/ubuntu24.dockerfile b/test/ubuntu24.dockerfile new file mode 100755 index 000000000..b483bdcad --- /dev/null +++ b/test/ubuntu24.dockerfile @@ -0,0 +1,19 @@ +FROM ubuntu:24.04 + +RUN apt-get update -qq + +RUN apt-get install --no-install-recommends -y nodejs npm git zip dpkg fakeroot rpm libarchive-tools +RUN apt-get install -y \ + xvfb \ + zip \ + wget \ + ca-certificates \ + libnss3-dev \ + libasound2t64 \ + libxss1 \ + libappindicator3-1 \ + libindicator7 \ + xdg-utils \ + fonts-liberation \ + libgbm1 +