diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index ada8e271b1..20f98a2ffb 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -54,8 +54,16 @@ body: - type: input id: version attributes: - label: Docker Selenium version (tag or chart version) + label: Docker Selenium version (image tag) description: What version of Docker Selenium are you using? - placeholder: 4.16.0-20231206? Please use the full tag, avoid "latest" + placeholder: 4.16.1-20231219? Please use the full tag, avoid "latest" validations: required: true + - type: input + id: chart-version + attributes: + label: Selenium Grid chart version (chart version) + description: What version of Selenium Grid chart are you using? + placeholder: 0.26.2? + validations: + required: false diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index de0ac5db98..21d0b60a7e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -80,7 +80,7 @@ jobs: git config --local user.name "Selenium CI Bot" git commit -m "Update tag in docs and files" -a - name: Push changes - uses: ad-m/github-push-action@d91a481090679876dfc4178fef17f286781251df # master + uses: ad-m/github-push-action@master with: github_token: ${{ secrets.SELENIUM_CI_TOKEN }} branch: trunk diff --git a/.github/workflows/helm-chart-test.yml b/.github/workflows/helm-chart-test.yml index 7c34c5eb91..6740317956 100644 --- a/.github/workflows/helm-chart-test.yml +++ b/.github/workflows/helm-chart-test.yml @@ -63,14 +63,14 @@ jobs: run: make chart_cluster_cleanup - name: Upload Helm chart package if: always() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: ${{ env.CHART_FILE_NAME }} + name: ${{ matrix.test-strategy }}_${{ env.CHART_FILE_NAME }} path: ${{ env.CHART_PACKAGE_PATH }} - - name: Upload Helm chart template rendered + - name: Upload chart test artifacts if: always() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: chart_template_rendered.yaml - path: ./tests/tests/output_deployment.yaml + name: ${{ matrix.test-strategy }}-artifacts + path: ./tests/tests/ if-no-files-found: ignore diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml index 8a7b86c644..7abaecd807 100644 --- a/.github/workflows/lock.yml +++ b/.github/workflows/lock.yml @@ -14,12 +14,12 @@ jobs: action: runs-on: ubuntu-latest steps: - - uses: dessant/lock-threads@1bf7ec25051fe7c00bdd17e6a7cf3d7bfb7dc771 # v3 + - uses: dessant/lock-threads@v5 with: process-only: 'issues' - issue-lock-inactive-days: '30' + issue-inactive-days: '30' issue-lock-reason: '' - issue-lock-comment: > + issue-comment: > This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. diff --git a/.github/workflows/scan-dockerfile.yml b/.github/workflows/scan-dockerfile.yml new file mode 100644 index 0000000000..259a900dd9 --- /dev/null +++ b/.github/workflows/scan-dockerfile.yml @@ -0,0 +1,53 @@ +name: Scan Dockerfile vulnerabilities + +on: + push: + paths: + - '**/Dockerfile' + pull_request: + paths: + - '**/Dockerfile' + workflow_dispatch: + schedule: + - cron: '0 0 * * *' + +jobs: + build-and-scan: + name: Scan Dockerfile vulnerabilities + permissions: write-all + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set severity for PRs + if: github.event_name == 'pull_request' || github.event_name == 'push' + run: | + echo "SEVERITY=HIGH,CRITICAL" >> $GITHUB_ENV + echo "EXIT_CODE=1" >> $GITHUB_ENV + - name: Set severity for others + if: github.event_name != 'pull_request' && github.event_name != 'push' + run: | + echo "SEVERITY=LOW,MEDIUM,HIGH,CRITICAL" >> $GITHUB_ENV + echo "EXIT_CODE=0" >> $GITHUB_ENV + - name: Scan source code + uses: aquasecurity/trivy-action@master + with: + scan-type: 'fs' + scan-ref: '.' + format: 'sarif' + output: 'source-results.sarif' + scanners: 'vuln,secret,misconfig' + skip-dirs: 'tests,Video' + exit-code: '${{ env.EXIT_CODE }}' + severity: '${{ env.SEVERITY }}' + limit-severities-for-sarif: true + - name: Upload source scan results to annotations + if: always() + uses: Ayrx/sarif_to_github_annotations@master + with: + sarif_file: 'source-results.sarif' + - name: Upload source scan results to GitHub Security tab + if: github.event_name != 'pull_request' + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: 'source-results.sarif' + category: source-results diff --git a/.github/workflows/test-video.yml b/.github/workflows/test-video.yml index 65b2241f29..02aa7f7c46 100644 --- a/.github/workflows/test-video.yml +++ b/.github/workflows/test-video.yml @@ -37,17 +37,17 @@ jobs: - name: Run Docker Compose to record video run: USE_RANDOM_USER_ID=${USE_RANDOM_USER} VERSION=${BRANCH} BUILD_DATE=${BUILD_DATE} make test_video - name: Upload recorded Chrome video - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: chrome_video path: ./tests/videos/chrome_video.mp4 - name: Upload recorded Edge video - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: edge_video path: ./tests/videos/edge_video.mp4 - name: Upload recorded Firefox video - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: firefox_video path: ./tests/videos/firefox_video.mp4 diff --git a/.github/workflows/update-chart-changelog.yaml b/.github/workflows/update-chart-changelog.yaml new file mode 100644 index 0000000000..3ac45a214e --- /dev/null +++ b/.github/workflows/update-chart-changelog.yaml @@ -0,0 +1,33 @@ +name: Update Chart CHANGELOG + +on: + release: + types: [published] + workflow_dispatch: + +jobs: + release: + runs-on: ubuntu-latest + permissions: write-all + if: ${{ contains(github.event.release.tag_name, 'selenium-grid') || github.event_name == 'workflow_dispatch' }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + persist-credentials: false + fetch-depth: 0 + + - name: Update chart CHANGELOG + run: ./generate_chart_changelog.sh + + - name: Commit files + run: | + git config --local user.email "selenium-ci@users.noreply.github.com" + git config --local user.name "Selenium CI Bot" + git commit -m "Update chart CHANGELOG [skip ci]" -a + + - name: Push changes + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.SELENIUM_CI_TOKEN }} + branch: trunk diff --git a/.github/workflows/update-dev-beta-browser-images.yml b/.github/workflows/update-dev-beta-browser-images.yml index 6349a71a0d..4bcef2c5b3 100644 --- a/.github/workflows/update-dev-beta-browser-images.yml +++ b/.github/workflows/update-dev-beta-browser-images.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup environment variables run: | - export SELENIUM_VERSION=$(grep selenium-server Base/Dockerfile | sed 's/.*-\([^-]*\)\.jar \\/\1/' | head -n 1) + export SELENIUM_VERSION=$(grep BASE_VERSION Makefile | sed 's/.*,\([^)]*\))/\1/p' | head -n 1) echo "SELENIUM_VERSION="$SELENIUM_VERSION >> $GITHUB_ENV export BUILD_DATE=$(date '+%Y%m%d') echo "BUILD_DATE="$BUILD_DATE >> $GITHUB_ENV diff --git a/Base/Dockerfile b/Base/Dockerfile index ef79b22bcb..e08efd9fac 100644 --- a/Base/Dockerfile +++ b/Base/Dockerfile @@ -5,11 +5,26 @@ #FROM ubuntu:focal-20220415 #FROM ubuntu:focal-20220531 #FROM ubuntu:focal-20230301 +#FROM ubuntu:jammy-20231128 FROM debian:bookworm + LABEL authors="Selenium " +# Arguments to define the version of dependencies to download ARG VERSION ARG RELEASE=selenium-${VERSION} +# Default value should be aligned with upstream Selenium (https://github.com/SeleniumHQ/selenium/blob/trunk/java/maven_deps.bzl) +ARG OPENTELEMETRY_VERSION=1.28.0 +ARG GRPC_VERSION=1.57.1 + +#Arguments to define the user running Selenium +ARG SEL_USER=seluser +ARG SEL_GROUP=${SEL_USER} +ARG SEL_PASSWD=secret +ARG UID=1200 +ARG GID=1201 + +USER root #================================================ # Customize sources for apt-get #================================================ @@ -42,6 +57,7 @@ RUN apt-get -qqy update \ curl \ supervisor \ gnupg2 \ + libnss3-tools \ && mkdir -p /etc/apt/keyrings \ && wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | tee /etc/apt/keyrings/adoptium.asc \ && echo "deb [signed-by=/etc/apt/keyrings/adoptium.asc] https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" | tee /etc/apt/sources.list.d/adoptium.list \ @@ -58,7 +74,6 @@ RUN if [ $TARGETARCH = "arm" ] && [ $TARGETVARIANT = "v7" ]; then \ fi \ && sed -i 's/securerandom\.source=file:\/dev\/random/securerandom\.source=file:\/dev\/urandom/' ./usr/lib/jvm/temurin-11-jre-$ARCH/conf/security/java.security - #=================== # Timezone settings # Possible alternative: https://github.com/docker/docker/issues/3359#issuecomment-32150214 @@ -68,25 +83,33 @@ RUN ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime && \ dpkg-reconfigure -f noninteractive tzdata && \ cat /etc/timezone +#====================================== +# Configure environement +#====================================== +ENV SEL_USER=${SEL_USER} +ENV SEL_UID=${UID} +ENV SEL_GID=${GID} +ENV HOME=/home/${SEL_USER} +ENV SEL_DOWNLOAD_DIR=${HOME}/Downloads + #======================================== # Add normal user and group with passwordless sudo #======================================== -RUN groupadd seluser \ - --gid 1201 \ - && useradd seluser \ +RUN groupadd ${SEL_GROUP} \ + --gid ${SEL_GID} \ + && useradd ${SEL_USER} \ --create-home \ - --gid 1201 \ + --gid ${SEL_GID} \ --shell /bin/bash \ - --uid 1200 \ - && usermod -a -G sudo seluser \ + --uid ${SEL_UID} \ + && usermod -a -G sudo ${SEL_USER} \ && echo 'ALL ALL = (ALL) NOPASSWD: ALL' >> /etc/sudoers \ - && echo 'seluser:secret' | chpasswd -ENV HOME=/home/seluser + && echo "${SEL_USER}:${SEL_PASSWD}" | chpasswd #====================================== # Add Grid check script #====================================== -COPY check-grid.sh entry_point.sh /opt/bin/ +COPY --chown="${SEL_UID}:${SEL_GID}" check-grid.sh entry_point.sh /opt/bin/ #====================================== # Add Supervisor configuration file @@ -96,14 +119,17 @@ COPY supervisord.conf /etc #========== # Selenium & relaxing permissions for OpenShift and other non-sudo environments #========== -RUN mkdir -p /opt/selenium /opt/selenium/assets /var/run/supervisor /var/log/supervisor \ +RUN mkdir -p /opt/selenium /opt/selenium/assets /var/run/supervisor /var/log/supervisor ${SEL_DOWNLOAD_DIR} ${HOME}/.mozilla ${HOME}/.vnc \ && touch /opt/selenium/config.toml \ - && chmod -R 777 /opt/selenium /opt/selenium/assets /var/run/supervisor /var/log/supervisor /etc/passwd \ + && chown -R ${SEL_USER}:${SEL_GROUP} /opt/selenium /var/run/supervisor /var/log/supervisor /etc/passwd ${HOME} \ + && chmod -R 775 /opt/selenium /var/run/supervisor /var/log/supervisor /etc/passwd ${HOME} \ && wget --no-verbose https://github.com/SeleniumHQ/selenium/releases/download/${RELEASE}/selenium-server-${VERSION}.jar \ -O /opt/selenium/selenium-server.jar \ + && echo "${SEL_PASSWD}" > /opt/selenium/initialPasswd \ && chgrp -R 0 /opt/selenium ${HOME} /opt/selenium/assets /var/run/supervisor /var/log/supervisor \ && chmod -R g=u /opt/selenium ${HOME} /opt/selenium/assets /var/run/supervisor /var/log/supervisor \ - && setfacl -Rm u:seluser:rwx /opt /opt/selenium ${HOME} /opt/selenium/assets /var/run/supervisor /var/log/supervisor + && setfacl -Rm u:${SEL_USER}:rwx /opt /opt/selenium ${HOME} /opt/selenium/assets /var/run/supervisor /var/log/supervisor \ + && setfacl -Rm g:${SEL_GROUP}:rwx /opt /opt/selenium ${HOME} /opt/selenium/assets /var/run/supervisor /var/log/supervisor #===== # Download observability related jaegar jars and make them available in a separate directory @@ -120,9 +146,9 @@ RUN if [ `arch` = "aarch64" ]; then \ RUN if [ -f "/tmp/cs" ]; then \ /tmp/cs fetch --classpath --cache /external_jars \ - io.opentelemetry:opentelemetry-exporter-otlp:1.31.0 \ - io.opentelemetry:opentelemetry-exporter-jaeger:1.31.0 \ - io.grpc:grpc-netty:1.59.0 > /external_jars/.classpath.txt ; \ + io.opentelemetry:opentelemetry-exporter-otlp:${OPENTELEMETRY_VERSION} \ + io.opentelemetry:opentelemetry-exporter-jaeger:${OPENTELEMETRY_VERSION} \ + io.grpc:grpc-netty:${GRPC_VERSION} > /external_jars/.classpath.txt ; \ fi RUN if [ -f "/tmp/cs" ]; then chmod 664 /external_jars/.classpath.txt ; fi @@ -131,9 +157,19 @@ RUN rm -fr /root/.cache/* #=================================================== # Run the following commands as non-privileged user #=================================================== -USER 1200:1201 +USER ${SEL_UID}:${SEL_GID} +VOLUME ${SEL_DOWNLOAD_DIR} # Boolean value, maps "--bind-host" ENV SE_BIND_HOST false +# A too high maximum number of file descriptors (with the default value +# inherited from the docker host) can cause issues with some of our tools: +# - sanitizers hanging: https://github.com/google/sanitizers/issues/1662 +# - valgrind crashing: https://stackoverflow.com/a/75293014 +# This is not be a problem on our CI hosts, but developers who run the image +# on their machines may run into this (e.g., on Arch Linux), so warn them. +# (Note that .bashrc is only executed in interactive bash shells.) +RUN echo 'if [[ $(ulimit -n) -gt 200000 ]]; then echo "WARNING: Very high value reported by \"ulimit -n\". Consider passing \"--ulimit nofile=32768\" to \"docker run\"."; fi' >> ${HOME}/.bashrc + CMD ["/opt/bin/entry_point.sh"] diff --git a/Distributor/Dockerfile b/Distributor/Dockerfile index 75e75468a6..ce901ceeb9 100644 --- a/Distributor/Dockerfile +++ b/Distributor/Dockerfile @@ -4,7 +4,7 @@ ARG AUTHORS FROM ${NAMESPACE}/base:${VERSION} LABEL authors=${AUTHORS} -USER 1200 +USER ${SEL_UID} #======================== # Selenium Distributor Configuration @@ -12,7 +12,7 @@ USER 1200 EXPOSE 5553 -COPY start-selenium-grid-distributor.sh \ +COPY --chown="${SEL_UID}:${SEL_GID}" start-selenium-grid-distributor.sh \ /opt/bin/ COPY selenium-grid-distributor.conf /etc/supervisor/conf.d/ diff --git a/Distributor/start-selenium-grid-distributor.sh b/Distributor/start-selenium-grid-distributor.sh index b51340c911..b0782c3c31 100755 --- a/Distributor/start-selenium-grid-distributor.sh +++ b/Distributor/start-selenium-grid-distributor.sh @@ -54,6 +54,11 @@ if [ ! -z "$SE_DISTRIBUTOR_PORT" ]; then PORT_CONFIG="--port ${SE_DISTRIBUTOR_PORT}" fi +if [ ! -z "$SE_LOG_LEVEL" ]; then + echo "Appending Selenium options: --log-level ${SE_LOG_LEVEL}" + SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" +fi + EXTRA_LIBS="" if [ ! -z "$SE_ENABLE_TRACING" ]; then diff --git a/EventBus/Dockerfile b/EventBus/Dockerfile index 16985e7b2b..6864aead40 100644 --- a/EventBus/Dockerfile +++ b/EventBus/Dockerfile @@ -4,7 +4,7 @@ ARG AUTHORS FROM ${NAMESPACE}/base:${VERSION} LABEL authors=${AUTHORS} -USER 1200 +USER ${SEL_UID} #================================= # Selenium Event Bus Configuration @@ -17,7 +17,7 @@ EXPOSE 4443 # Event Bus port EXPOSE 5557 -COPY start-selenium-grid-eventbus.sh \ +COPY --chown="${SEL_UID}:${SEL_GID}" start-selenium-grid-eventbus.sh \ /opt/bin/ COPY selenium-grid-eventbus.conf /etc/supervisor/conf.d/ diff --git a/EventBus/start-selenium-grid-eventbus.sh b/EventBus/start-selenium-grid-eventbus.sh index d3413a968d..a8af2c040a 100755 --- a/EventBus/start-selenium-grid-eventbus.sh +++ b/EventBus/start-selenium-grid-eventbus.sh @@ -19,6 +19,11 @@ if [ ! -z "$SE_OPTS" ]; then echo "Appending Selenium options: ${SE_OPTS}" fi +if [ ! -z "$SE_LOG_LEVEL" ]; then + echo "Appending Selenium options: --log-level ${SE_LOG_LEVEL}" + SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" +fi + EXTRA_LIBS="" if [ ! -z "$SE_ENABLE_TRACING" ]; then diff --git a/Hub/Dockerfile b/Hub/Dockerfile index 56348d8ba8..e467971646 100644 --- a/Hub/Dockerfile +++ b/Hub/Dockerfile @@ -4,7 +4,7 @@ ARG AUTHORS FROM ${NAMESPACE}/base:${VERSION} LABEL authors=${AUTHORS} -USER 1200 +USER ${SEL_UID} #======================== # Selenium Hub Configuration @@ -21,7 +21,7 @@ ENV SE_SESSION_RETRY_INTERVAL 15 # Boolean value, maps "--relax-checks" ENV SE_RELAX_CHECKS true -COPY start-selenium-grid-hub.sh \ +COPY --chown="${SEL_UID}:${SEL_GID}" start-selenium-grid-hub.sh \ /opt/bin/ COPY selenium-grid-hub.conf /etc/supervisor/conf.d/ diff --git a/Hub/start-selenium-grid-hub.sh b/Hub/start-selenium-grid-hub.sh index 98b9758f7f..e25fe16d4c 100755 --- a/Hub/start-selenium-grid-hub.sh +++ b/Hub/start-selenium-grid-hub.sh @@ -22,6 +22,11 @@ if [ ! -z "$SE_SUB_PATH" ]; then SUB_PATH_CONFIG="--sub-path ${SE_SUB_PATH}" fi +if [ ! -z "$SE_LOG_LEVEL" ]; then + echo "Appending Selenium options: --log-level ${SE_LOG_LEVEL}" + SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" +fi + EXTRA_LIBS="" if [ ! -z "$SE_ENABLE_TRACING" ]; then diff --git a/Makefile b/Makefile index 14a3458409..50969e1c86 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,9 @@ NAME := $(or $(NAME),$(NAME),selenium) CURRENT_DATE := $(shell date '+%Y%m%d') BUILD_DATE := $(or $(BUILD_DATE),$(BUILD_DATE),$(CURRENT_DATE)) -VERSION := $(or $(VERSION),$(VERSION),4.16.0) -BASE_VERSION := $(or $(BASE_VERSION),$(BASE_VERSION),4.16.0) -BASE_RELEASE := $(or $(BASE_RELEASE),$(BASE_RELEASE),selenium-$(BASE_VERSION)) +VERSION := $(or $(VERSION),$(VERSION),4.16.1) +BASE_VERSION := $(or $(BASE_VERSION),$(BASE_VERSION),4.16.1) +BASE_RELEASE := $(or $(BASE_RELEASE),$(BASE_RELEASE),selenium-4.16.0) TAG_VERSION := $(VERSION)-$(BUILD_DATE) NAMESPACE := $(or $(NAMESPACE),$(NAMESPACE),$(NAME)) AUTHORS := $(or $(AUTHORS),$(AUTHORS),SeleniumHQ) @@ -536,7 +536,7 @@ chart_test_edge: VERSION=$(TAG_VERSION) NAMESPACE=$(NAMESPACE) ./tests/charts/make/chart_test.sh NodeEdge chart_test_parallel_autoscaling: - VERSION=$(TAG_VERSION) NAMESPACE=$(NAMESPACE) ./tests/charts/make/chart_test.sh ParallelAutoscaling + VERSION=$(TAG_VERSION) NAMESPACE=$(NAMESPACE) ./tests/charts/make/chart_test.sh JobAutoscaling .PHONY: \ all \ diff --git a/NodeBase/Dockerfile b/NodeBase/Dockerfile index 4ca8345fc8..21afac5bae 100644 --- a/NodeBase/Dockerfile +++ b/NodeBase/Dockerfile @@ -4,13 +4,16 @@ ARG AUTHORS FROM ${NAMESPACE}/base:${VERSION} LABEL authors=${AUTHORS} +ARG NOVNC_VERSION="1.4.0" +ARG WEBSOCKIFY_VERSION="0.11.0" + USER root #============== # Xvfb #============== RUN apt-get update -qqy \ - && apt-get -qqy install \ + && apt-get -qqy --no-install-recommends install \ xvfb \ pulseaudio \ && rm -rf /var/lib/apt/lists/* /var/cache/apt/* @@ -40,7 +43,7 @@ RUN apt-get -qqy update \ # VNC #===== RUN apt-get update -qqy \ - && apt-get -qqy install \ + && apt-get -qqy --no-install-recommends install \ x11vnc \ && rm -rf /var/lib/apt/lists/* /var/cache/apt/* @@ -49,7 +52,7 @@ RUN apt-get update -qqy \ # A fast, lightweight and responsive window manager #========= RUN apt-get update -qqy \ - && apt-get -qqy install \ + && apt-get -qqy --no-install-recommends install \ fluxbox \ && rm -rf /var/lib/apt/lists/* /var/cache/apt/* @@ -93,8 +96,6 @@ RUN apt-get -qqy update \ ######################################## # noVNC exposes VNC through a web page # ######################################## -ENV NOVNC_VERSION="1.4.0" \ - WEBSOCKIFY_VERSION="0.11.0" RUN wget -nv -O noVNC.zip \ "https://github.com/novnc/noVNC/archive/refs/tags/v${NOVNC_VERSION}.zip" \ && unzip -x noVNC.zip \ @@ -105,24 +106,43 @@ RUN wget -nv -O noVNC.zip \ "https://github.com/novnc/websockify/archive/refs/tags/v${WEBSOCKIFY_VERSION}.zip" \ && unzip -x websockify.zip \ && rm websockify.zip \ - && rm -rf websockify-${WEBSOCKIFY_VERSION}/tests \ - && mv websockify-${WEBSOCKIFY_VERSION} /opt/bin/noVNC/utils/websockify + && mv websockify-${WEBSOCKIFY_VERSION} /opt/bin/noVNC/utils/websockify \ + && rm -rf /opt/bin/noVNC/utils/websockify/docker /opt/bin/noVNC/utils/websockify/tests #========================================================================================================================================= # Run this command for executable file permissions for /dev/shm when this is a "child" container running in Docker Desktop and WSL2 distro #========================================================================================================================================= RUN chmod +x /dev/shm +# Creating base directory for Xvfb +RUN mkdir -p /tmp/.X11-unix + +#============================== +# Generating the VNC password using initial password in Base image +# Changing ownership to ${SEL_USER}, so the service can be started +#============================== + +RUN mkdir -p ${HOME}/.vnc \ + && x11vnc -storepasswd $(cat /opt/selenium/initialPasswd) ${HOME}/.vnc/passwd \ + && chown -R "${SEL_USER}:${SEL_GROUP}" ${HOME}/.vnc + +#========== +# Relaxing permissions for OpenShift and other non-sudo environments +#========== +RUN chmod -R 775 ${HOME} /tmp/.X11-unix \ + && chgrp -R 0 ${HOME} /tmp/.X11-unix \ + && chmod -R g=u ${HOME} /tmp/.X11-unix + #=================================================== # Run the following commands as non-privileged user #=================================================== -USER 1200 +USER ${SEL_UID} #============================== # Scripts to run Selenium Node and XVFB #============================== -COPY start-selenium-node.sh \ +COPY --chown="${SEL_UID}:${SEL_GID}" start-selenium-node.sh \ start-xvfb.sh \ /opt/bin/ @@ -154,7 +174,7 @@ RUN sudo chmod -R 775 ${HOME} \ #============================== # Scripts to run fluxbox, x11vnc and noVNC #============================== -COPY start-vnc.sh \ +COPY --chown="${SEL_UID}:${SEL_GID}" start-vnc.sh \ start-novnc.sh \ /opt/bin/ @@ -186,8 +206,6 @@ ENV SE_DRAIN_AFTER_SESSION_COUNT 0 # Setting Selenium Manager to work offline ENV SE_OFFLINE true - - #======================== # Selenium Configuration #======================== @@ -211,6 +229,6 @@ RUN mkdir -p /tmp/.X11-unix && chmod 1777 /tmp/.X11-unix USER 1200 # Copying configuration script generator -COPY generate_config /opt/bin/generate_config +COPY --chown="${SEL_UID}:${SEL_GID}" generate_config /opt/bin/generate_config EXPOSE 5900 diff --git a/NodeBase/start-selenium-node.sh b/NodeBase/start-selenium-node.sh index 4b069c7dd0..21cd7b9463 100755 --- a/NodeBase/start-selenium-node.sh +++ b/NodeBase/start-selenium-node.sh @@ -36,6 +36,11 @@ if [ ! -z "$SE_NODE_SESSION_TIMEOUT" ]; then echo "Appending Selenium node session timeout via SE_OPTS: ${SE_OPTS}" fi +if [ ! -z "$SE_LOG_LEVEL" ]; then + echo "Appending Selenium options: --log-level ${SE_LOG_LEVEL}" + SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" +fi + if [ "$GENERATE_CONFIG" = true ]; then echo "Generating Selenium Config" /opt/bin/generate_config diff --git a/NodeBase/start-vnc.sh b/NodeBase/start-vnc.sh index 345ac94e9f..b5cfe34595 100755 --- a/NodeBase/start-vnc.sh +++ b/NodeBase/start-vnc.sh @@ -44,6 +44,17 @@ if [ "${START_XVFB:-$SE_START_XVFB}" = true ] ; then echo "Waiting for Xvfb..." done + # Guard against unreasonably high nofile limits. See https://github.com/SeleniumHQ/docker-selenium/issues/2045 + if [[ $(ulimit -n) -gt 200000 || ! -z "${SE_VNC_ULIMIT}" ]]; then + echo "Trying to update the open file descriptor limit from $(ulimit -n) to ${SE_VNC_ULIMIT:-65536}." + ulimit -n ${SE_VNC_ULIMIT:-65536} + if [ $? -eq 0 ]; then + echo "Successfully update the open file descriptor limit." + else + echo "The open file descriptor limit could not be updated." + fi + fi + x11vnc ${X11VNC_OPTS} -forever -shared -rfbport ${VNC_PORT:-$SE_VNC_PORT} -rfbportv6 ${VNC_PORT:-$SE_VNC_PORT} -display ${DISPLAY} else echo "VNC won't start because SE_START_VNC is false." diff --git a/NodeChrome/Dockerfile b/NodeChrome/Dockerfile index dfcc5bd61f..c4d1fdd268 100644 --- a/NodeChrome/Dockerfile +++ b/NodeChrome/Dockerfile @@ -18,7 +18,7 @@ ARG CHROME_VERSION="google-chrome-stable" RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor | tee /etc/apt/trusted.gpg.d/google.gpg >/dev/null \ && echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list \ && apt-get update -qqy \ - && apt-get -qqy install \ + && apt-get -qqy --no-install-recommends install \ ${CHROME_VERSION:-google-chrome-stable} \ && rm /etc/apt/sources.list.d/google-chrome.list \ && rm -rf /var/lib/apt/lists/* /var/cache/apt/* @@ -29,8 +29,6 @@ RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --d COPY wrap_chrome_binary /opt/bin/wrap_chrome_binary RUN /opt/bin/wrap_chrome_binary -USER 1200 - #============================================ # Chrome webdriver #============================================ @@ -53,7 +51,9 @@ RUN if [ ! -z "$CHROME_DRIVER_VERSION" ]; \ && rm /tmp/chromedriver_linux64.zip \ && mv /opt/selenium/chromedriver-linux64/chromedriver /opt/selenium/chromedriver-$CHROME_DRIVER_VERSION \ && chmod 755 /opt/selenium/chromedriver-$CHROME_DRIVER_VERSION \ - && sudo ln -fs /opt/selenium/chromedriver-$CHROME_DRIVER_VERSION /usr/bin/chromedriver + && ln -fs /opt/selenium/chromedriver-$CHROME_DRIVER_VERSION /usr/bin/chromedriver + +USER ${SEL_UID} #============================================ # Dumping Browser information for config diff --git a/NodeDocker/Dockerfile b/NodeDocker/Dockerfile index 249b91adc7..b65820cecc 100644 --- a/NodeDocker/Dockerfile +++ b/NodeDocker/Dockerfile @@ -10,10 +10,10 @@ USER root # Socat to proxy docker.sock when mounted #============== RUN apt-get update -qqy \ - && apt-get -qqy install socat \ + && apt-get -qqy --no-install-recommends install socat \ && rm -rf /var/lib/apt/lists/* /var/cache/apt/* -USER 1200 +USER ${SEL_UID} #======================== # Selenium Standalone Docker Configuration @@ -21,7 +21,7 @@ USER 1200 EXPOSE 4444 -COPY start-selenium-grid-docker.sh \ +COPY --chown="${SEL_UID}:${SEL_GID}" start-selenium-grid-docker.sh \ config.toml \ start-socat.sh \ /opt/bin/ diff --git a/NodeDocker/config.toml b/NodeDocker/config.toml index bfe4bd0713..f1916a4017 100644 --- a/NodeDocker/config.toml +++ b/NodeDocker/config.toml @@ -2,9 +2,9 @@ # Configs have a mapping between the Docker image to use and the capabilities that need to be matched to # start a container with the given image. configs = [ - "selenium/standalone-firefox:4.16.0-20231206", '{"browserName": "firefox", "platformName": "linux"}', - "selenium/standalone-chrome:4.16.0-20231206", '{"browserName": "chrome", "platformName": "linux"}', - "selenium/standalone-edge:4.16.0-20231206", '{"browserName": "MicrosoftEdge", "platformName": "linux"}' + "selenium/standalone-firefox:4.16.1-20231219", '{"browserName": "firefox", "platformName": "linux"}', + "selenium/standalone-chrome:4.16.1-20231219", '{"browserName": "chrome", "platformName": "linux"}', + "selenium/standalone-edge:4.16.1-20231219", '{"browserName": "MicrosoftEdge", "platformName": "linux"}' ] # URL for connecting to the docker daemon @@ -14,7 +14,7 @@ configs = [ # socat -4 TCP-LISTEN:2375,fork UNIX-CONNECT:/var/run/docker.sock url = "http://127.0.0.1:2375" # Docker image used for video recording -video-image = "selenium/video:ffmpeg-6.1-20231206" +video-image = "selenium/video:ffmpeg-6.1-20231219" # Uncomment the following section if you are running the node on a separate VM # Fill out the placeholders with appropriate values diff --git a/NodeDocker/start-selenium-grid-docker.sh b/NodeDocker/start-selenium-grid-docker.sh index 0220a1ec96..a811780e75 100755 --- a/NodeDocker/start-selenium-grid-docker.sh +++ b/NodeDocker/start-selenium-grid-docker.sh @@ -29,6 +29,11 @@ if [ ! -z "$SE_NODE_GRID_URL" ]; then SE_GRID_URL="--grid-url ${SE_NODE_GRID_URL}" fi +if [ ! -z "$SE_LOG_LEVEL" ]; then + echo "Appending Selenium options: --log-level ${SE_LOG_LEVEL}" + SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" +fi + EXTRA_LIBS="" if [ ! -z "$SE_ENABLE_TRACING" ]; then diff --git a/NodeEdge/Dockerfile b/NodeEdge/Dockerfile index 7f26504ba4..4c8ab84140 100644 --- a/NodeEdge/Dockerfile +++ b/NodeEdge/Dockerfile @@ -16,7 +16,7 @@ ARG EDGE_VERSION="microsoft-edge-stable" RUN wget -q -O - https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/microsoft.gpg >/dev/null \ && echo "deb https://packages.microsoft.com/repos/edge stable main" >> /etc/apt/sources.list.d/microsoft-edge.list \ && apt-get update -qqy \ - && apt-get -qqy install ${EDGE_VERSION} \ + && apt-get -qqy --no-install-recommends install ${EDGE_VERSION} \ && rm /etc/apt/sources.list.d/microsoft-edge.list \ && rm -rf /var/lib/apt/lists/* /var/cache/apt/* @@ -46,7 +46,7 @@ RUN if [ -z "$EDGE_DRIVER_VERSION" ]; \ && chmod 755 /opt/selenium/msedgedriver-$EDGE_DRIVER_VERSION \ && ln -fs /opt/selenium/msedgedriver-$EDGE_DRIVER_VERSION /usr/bin/msedgedriver -USER 1200 +USER ${SEL_UID} #============================================ # Dumping Browser information for config diff --git a/NodeFirefox/Dockerfile b/NodeFirefox/Dockerfile index e79f641be3..0150b61e34 100644 --- a/NodeFirefox/Dockerfile +++ b/NodeFirefox/Dockerfile @@ -36,17 +36,7 @@ RUN GK_VERSION=$(if [ ${GECKODRIVER_VERSION:-latest} = "latest" ]; then echo "0. && chmod 755 /opt/geckodriver-$GK_VERSION \ && ln -fs /opt/geckodriver-$GK_VERSION /usr/bin/geckodriver -# Workaround for issue launch Firefox Webdriver "Failed to read marionette port" -RUN mkdir -p /home/seluser/.cache /home/seluser/.mozilla /.cache \ - && chmod 777 /home/seluser/.cache /home/seluser/.mozilla /.cache - -USER 1200 - -RUN if ! whoami &> /dev/null; then \ - if [ -w /tmp/passwd ]; then \ - echo "${USER_NAME:-default}:x:$(id -u):0:${USER_NAME:-default} user:/home/seluser:/tmp:/bin/bash" >> /tmp/passwd; \ - fi \ -fi +USER ${SEL_UID} #============================================ # Dumping Browser information for config diff --git a/README.md b/README.md index ed3309820c..bac1eb1ed3 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ The project is made possible by volunteer contributors who have put in thousands and made the source code freely available under the [Apache License 2.0](LICENSE.md). These Docker images come with a handful of tags to simplify its usage, have a look at them in one of -our [releases](https://github.com/SeleniumHQ/docker-selenium/releases/tag/4.16.0-20231206). +our [releases](https://github.com/SeleniumHQ/docker-selenium/releases/tag/4.16.1-20231219). To get notifications of new releases, add yourself as a "Releases only" watcher. @@ -153,7 +153,7 @@ Talk to us at https://www.selenium.dev/support/ 1. Start a Docker container with Firefox ```bash -docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" selenium/standalone-firefox:4.16.0-20231206 +docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" selenium/standalone-firefox:4.16.1-20231219 ``` 2. Point your WebDriver tests to http://localhost:4444 @@ -340,17 +340,17 @@ For more information on the Dev and Beta channel container images, see the blog ![Firefox](https://raw.githubusercontent.com/alrra/browser-logos/main/src/firefox/firefox_24x24.png) Firefox ```bash -docker run -d -p 4444:4444 --shm-size="2g" selenium/standalone-firefox:4.16.0-20231206 +docker run -d -p 4444:4444 --shm-size="2g" selenium/standalone-firefox:4.16.1-20231219 ``` ![Chrome](https://raw.githubusercontent.com/alrra/browser-logos/main/src/chrome/chrome_24x24.png) Chrome ```bash -docker run -d -p 4444:4444 --shm-size="2g" selenium/standalone-chrome:4.16.0-20231206 +docker run -d -p 4444:4444 --shm-size="2g" selenium/standalone-chrome:4.16.1-20231219 ``` ![Edge](https://raw.githubusercontent.com/alrra/browser-logos/main/src/edge/edge_24x24.png) Edge ```bash -docker run -d -p 4444:4444 --shm-size="2g" selenium/standalone-edge:4.16.0-20231206 +docker run -d -p 4444:4444 --shm-size="2g" selenium/standalone-edge:4.16.1-20231219 ``` _Note: Only one Standalone container can run on port_ `4444` _at the same time._ @@ -369,44 +369,44 @@ A Docker [network](https://docs.docker.com/engine/reference/commandline/network_ ```bash $ docker network create grid -$ docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub selenium/hub:4.16.0-20231206 +$ docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub selenium/hub:4.16.1-20231219 $ docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub \ --shm-size="2g" \ -e SE_EVENT_BUS_PUBLISH_PORT=4442 \ -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \ - selenium/node-chrome:4.16.0-20231206 + selenium/node-chrome:4.16.1-20231219 $ docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub \ --shm-size="2g" \ -e SE_EVENT_BUS_PUBLISH_PORT=4442 \ -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \ - selenium/node-edge:4.16.0-20231206 + selenium/node-edge:4.16.1-20231219 $ docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub \ --shm-size="2g" \ -e SE_EVENT_BUS_PUBLISH_PORT=4442 \ -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \ - selenium/node-firefox:4.16.0-20231206 + selenium/node-firefox:4.16.1-20231219 ``` ##### Windows PowerShell ```powershell $ docker network create grid -$ docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub selenium/hub:4.16.0-20231206 +$ docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub selenium/hub:4.16.1-20231219 $ docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub ` --shm-size="2g" ` -e SE_EVENT_BUS_PUBLISH_PORT=4442 ` -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 ` - selenium/node-chrome:4.16.0-20231206 + selenium/node-chrome:4.16.1-20231219 $ docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub ` --shm-size="2g" ` -e SE_EVENT_BUS_PUBLISH_PORT=4442 ` -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 ` - selenium/node-edge:4.16.0-20231206 + selenium/node-edge:4.16.1-20231219 $ docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub ` --shm-size="2g" ` -e SE_EVENT_BUS_PUBLISH_PORT=4442 ` -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 ` - selenium/node-firefox:4.16.0-20231206 + selenium/node-firefox:4.16.1-20231219 ``` When you are done using the Grid, and the containers have exited, the network can be removed with the following command: @@ -423,7 +423,7 @@ configured to expose different ports. ##### Hub - Machine/VM 1 ```bash -$ docker run -d -p 4442-4444:4442-4444 --name selenium-hub selenium/hub:4.16.0-20231206 +$ docker run -d -p 4442-4444:4442-4444 --name selenium-hub selenium/hub:4.16.1-20231219 ``` ##### Node Chrome - Machine/VM 2 @@ -437,7 +437,7 @@ $ docker run -d -p 5555:5555 \ -e SE_EVENT_BUS_PUBLISH_PORT=4442 \ -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \ -e SE_NODE_HOST= \ - selenium/node-chrome:4.16.0-20231206 + selenium/node-chrome:4.16.1-20231219 ``` ###### Windows PowerShell @@ -449,7 +449,7 @@ $ docker run -d -p 5555:5555 ` -e SE_EVENT_BUS_PUBLISH_PORT=4442 ` -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 ` -e SE_NODE_HOST= ` - selenium/node-chrome:4.16.0-20231206 + selenium/node-chrome:4.16.1-20231219 ``` @@ -464,7 +464,7 @@ $ docker run -d -p 5555:5555 \ -e SE_EVENT_BUS_PUBLISH_PORT=4442 \ -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \ -e SE_NODE_HOST= \ - selenium/node-edge:4.16.0-20231206 + selenium/node-edge:4.16.1-20231219 ``` ###### Windows PowerShell @@ -476,7 +476,7 @@ $ docker run -d -p 5555:5555 ` -e SE_EVENT_BUS_PUBLISH_PORT=4442 ` -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 ` -e SE_NODE_HOST= ` - selenium/node-edge:4.16.0-20231206 + selenium/node-edge:4.16.1-20231219 ``` ##### Node Firefox - Machine/VM 4 @@ -490,7 +490,7 @@ $ docker run -d -p 5555:5555 \ -e SE_EVENT_BUS_PUBLISH_PORT=4442 \ -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \ -e SE_NODE_HOST= \ - selenium/node-firefox:4.16.0-20231206 + selenium/node-firefox:4.16.1-20231219 ``` ###### Windows PowerShell @@ -502,7 +502,7 @@ $ docker run -d -p 5555:5555 ` -e SE_EVENT_BUS_PUBLISH_PORT=4442 ` -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 ` -e SE_NODE_HOST= ` - selenium/node-firefox:4.16.0-20231206 + selenium/node-firefox:4.16.1-20231219 ``` ##### Node Chrome - Machine/VM 4 @@ -517,7 +517,7 @@ $ docker run -d -p 5556:5556 \ -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \ -e SE_NODE_HOST= \ -e SE_NODE_PORT=5556 \ - selenium/node-chrome:4.16.0-20231206 + selenium/node-chrome:4.16.1-20231219 ``` ###### Windows PowerShell @@ -530,7 +530,7 @@ $ docker run -d -p 5556:5556 ` -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 ` -e SE_NODE_HOST= ` -e SE_NODE_PORT=5556 ` - selenium/node-chrome:4.16.0-20231206 + selenium/node-chrome:4.16.1-20231219 ``` #### Docker Compose @@ -562,7 +562,7 @@ ___ ## Video recording -Tests execution can be recorded by using the `selenium/video:ffmpeg-6.1-20231206` +Tests execution can be recorded by using the `selenium/video:ffmpeg-6.1-20231219` Docker image. One container is needed per each container where a browser is running. This means if you are running 5 Nodes/Standalone containers, you will need 5 video containers, the mapping is 1-1. @@ -588,8 +588,8 @@ This example shows how to start the containers manually: ``` bash $ docker network create grid -$ docker run -d -p 4444:4444 -p 6900:5900 --net grid --name selenium --shm-size="2g" selenium/standalone-chrome:4.16.0-20231206 -$ docker run -d --net grid --name video -v /tmp/videos:/videos selenium/video:ffmpeg-6.1-20231206 +$ docker run -d -p 4444:4444 -p 6900:5900 --net grid --name selenium --shm-size="2g" selenium/standalone-chrome:4.16.1-20231219 +$ docker run -d --net grid --name video -v /tmp/videos:/videos selenium/video:ffmpeg-6.1-20231219 # Run your tests $ docker stop video && docker rm video $ docker stop selenium && docker rm selenium @@ -621,9 +621,9 @@ You can save this file locally and name it, for example, `config.toml`. # Configs have a mapping between the Docker image to use and the capabilities that need to be matched to # start a container with the given image. configs = [ - "selenium/standalone-firefox:4.16.0-20231206", '{"browserName": "firefox"}', - "selenium/standalone-chrome:4.16.0-20231206", '{"browserName": "chrome"}', - "selenium/standalone-edge:4.16.0-20231206", '{"browserName": "MicrosoftEdge"}' + "selenium/standalone-firefox:4.16.1-20231219", '{"browserName": "firefox"}', + "selenium/standalone-chrome:4.16.1-20231219", '{"browserName": "chrome"}', + "selenium/standalone-edge:4.16.1-20231219", '{"browserName": "MicrosoftEdge"}' ] # URL for connecting to the docker daemon @@ -636,7 +636,7 @@ configs = [ # Linux: varies from machine to machine, please mount /var/run/docker.sock. If this does not work, please create an issue. url = "http://127.0.0.1:2375" # Docker image used for video recording -video-image = "selenium/video:ffmpeg-6.1-20231206" +video-image = "selenium/video:ffmpeg-6.1-20231219" # Uncomment the following section if you are running the node on a separate VM # Fill out the placeholders with appropriate values @@ -655,28 +655,28 @@ virtual machines. ```bash $ docker network create grid -$ docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub selenium/hub:4.16.0-20231206 +$ docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub selenium/hub:4.16.1-20231219 $ docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub \ -e SE_EVENT_BUS_PUBLISH_PORT=4442 \ -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \ -v ${PWD}/config.toml:/opt/bin/config.toml \ -v ${PWD}/assets:/opt/selenium/assets \ -v /var/run/docker.sock:/var/run/docker.sock \ - selenium/node-docker:4.16.0-20231206 + selenium/node-docker:4.16.1-20231219 ``` #### Windows PowerShell ```powershell $ docker network create grid -$ docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub selenium/hub:4.16.0-20231206 +$ docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub selenium/hub:4.16.1-20231219 $ docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub ` -e SE_EVENT_BUS_PUBLISH_PORT=4442 ` -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 ` -v ${PWD}/config.toml:/opt/bin/config.toml ` -v ${PWD}/assets:/opt/selenium/assets ` -v /var/run/docker.sock:/var/run/docker.sock ` - selenium/node-docker:4.16.0-20231206 + selenium/node-docker:4.16.1-20231219 ``` To have the assets saved on your host, please mount your host path to `/opt/selenium/assets`. @@ -697,7 +697,7 @@ docker run --rm --name selenium-docker -p 4444:4444 \ -v ${PWD}/config.toml:/opt/bin/config.toml \ -v ${PWD}/assets:/opt/selenium/assets \ -v /var/run/docker.sock:/var/run/docker.sock \ - selenium/standalone-docker:4.16.0-20231206 + selenium/standalone-docker:4.16.1-20231219 ``` #### Windows PowerShell @@ -707,7 +707,7 @@ docker run --rm --name selenium-docker -p 4444:4444 ` -v ${PWD}/config.toml:/opt/bin/config.toml ` -v ${PWD}/assets:/opt/selenium/assets ` -v /var/run/docker.sock:/var/run/docker.sock ` - selenium/standalone-docker:4.16.0-20231206 + selenium/standalone-docker:4.16.1-20231219 ``` ### Using Dynamic Grid in different machines/VMs @@ -715,7 +715,7 @@ docker run --rm --name selenium-docker -p 4444:4444 ` #### Hub - Machine/VM 1 ```bash -$ docker run -d -p 4442-4444:4442-4444 --name selenium-hub selenium/hub:4.16.0-20231206 +$ docker run -d -p 4442-4444:4442-4444 --name selenium-hub selenium/hub:4.16.1-20231219 ``` #### Node Chrome - Machine/VM 2 @@ -730,7 +730,7 @@ $ docker run -d -p 5555:5555 \ -v ${PWD}/config.toml:/opt/bin/config.toml \ -v ${PWD}/assets:/opt/selenium/assets \ -v /var/run/docker.sock:/var/run/docker.sock \ - selenium/node-docker:4.16.0-20231206 + selenium/node-docker:4.16.1-20231219 ``` #### Windows PowerShell @@ -743,7 +743,7 @@ $ docker run -d -p 5555:5555 ` -v ${PWD}/config.toml:/opt/bin/config.toml ` -v ${PWD}/assets:/opt/selenium/assets ` -v /var/run/docker.sock:/var/run/docker.sock ` - selenium/node-docker:4.16.0-20231206 + selenium/node-docker:4.16.1-20231219 ``` Complete the `[server]` section in the `config.toml` file. @@ -752,9 +752,9 @@ Complete the `[server]` section in the `config.toml` file. # Configs have a mapping between the Docker image to use and the capabilities that need to be matched to # start a container with the given image. configs = [ - "selenium/standalone-firefox:4.16.0-20231206", "{\"browserName\": \"firefox\"}", - "selenium/standalone-chrome:4.16.0-20231206", "{\"browserName\": \"chrome\"}", - "selenium/standalone-edge:4.16.0-20231206", "{\"browserName\": \"MicrosoftEdge\"}" + "selenium/standalone-firefox:4.16.1-20231219", "{\"browserName\": \"firefox\"}", + "selenium/standalone-chrome:4.16.1-20231219", "{\"browserName\": \"chrome\"}", + "selenium/standalone-edge:4.16.1-20231219", "{\"browserName\": \"MicrosoftEdge\"}" ] # URL for connecting to the docker daemon @@ -767,7 +767,7 @@ configs = [ # Linux: varies from machine to machine, please mount /var/run/docker.sock. If this does not work, please create an issue. url = "http://127.0.0.1:2375" # Docker image used for video recording -video-image = "selenium/video:ffmpeg-6.1-20231206" +video-image = "selenium/video:ffmpeg-6.1-20231219" # Uncomment the following section if you are running the node on a separate VM # Fill out the placeholders with appropriate values @@ -801,7 +801,7 @@ docker run --rm --name selenium-docker -p 4444:4444 \ -v ${PWD}/config.toml:/opt/bin/config.toml \ -v ${PWD}/assets:/opt/selenium/assets \ -v /var/run/docker.sock:/var/run/docker.sock \ - selenium/standalone-docker:4.16.0-20231206 + selenium/standalone-docker:4.16.1-20231219 ``` #### Windows PowerShell @@ -812,7 +812,7 @@ docker run --rm --name selenium-docker -p 4444:4444 ` -v ${PWD}/config.toml:/opt/bin/config.toml ` -v ${PWD}/assets:/opt/selenium/assets ` -v /var/run/docker.sock:/var/run/docker.sock ` - selenium/standalone-docker:4.16.0-20231206 + selenium/standalone-docker:4.16.1-20231219 ``` @@ -850,7 +850,7 @@ ___ You can pass `SE_OPTS` variable with additional command line parameters for starting a hub or a node. ``` bash -$ docker run -d -p 4444:4444 -e SE_OPTS="--log-level FINE" --name selenium-hub selenium/hub:4.16.0-20231206 +$ docker run -d -p 4444:4444 -e SE_OPTS="--log-level FINE" --name selenium-hub selenium/hub:4.16.1-20231219 ``` ### SE_JAVA_OPTS Java Environment Options @@ -858,7 +858,7 @@ $ docker run -d -p 4444:4444 -e SE_OPTS="--log-level FINE" --name selenium-hub s You can pass `SE_JAVA_OPTS` environment variable to the Java process. ``` bash -$ docker run -d -p 4444:4444 -e SE_JAVA_OPTS=-Xmx512m --name selenium-hub selenium/hub:4.16.0-20231206 +$ docker run -d -p 4444:4444 -e SE_JAVA_OPTS=-Xmx512m --name selenium-hub selenium/hub:4.16.1-20231219 ``` ### Node configuration options @@ -880,7 +880,7 @@ $ docker run -d \ -e SE_EVENT_BUS_HOST= \ -e SE_EVENT_BUS_PUBLISH_PORT=4442 \ -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 -e SE_NODE_STEREOTYPE="{\"browserName\":\"${SE_NODE_BROWSER_NAME}\",\"browserVersion\":\"${SE_NODE_BROWSER_VERSION}\",\"platformName\": \"Linux\"}" \ - --shm-size="2g" selenium/node-chrome:4.16.0-20231206 + --shm-size="2g" selenium/node-chrome:4.16.1-20231219 ``` ### Setting Sub Path @@ -899,7 +899,7 @@ These settings can be adjusted by specifying `SE_SCREEN_WIDTH`, `SE_SCREEN_HEIGH environmental variables when starting the container. ``` bash -docker run -d -e SE_SCREEN_WIDTH=1366 -e SE_SCREEN_HEIGHT=768 -e SE_SCREEN_DEPTH=24 -e SE_SCREEN_DPI=74 selenium/standalone-firefox:4.16.0-20231206 +docker run -d -e SE_SCREEN_WIDTH=1366 -e SE_SCREEN_HEIGHT=768 -e SE_SCREEN_DEPTH=24 -e SE_SCREEN_DPI=74 selenium/standalone-firefox:4.16.1-20231219 ``` ### Grid Url and Session Timeout @@ -949,7 +949,7 @@ To avoid starting the server you can set the `START_XVFB` environment variable t ``` bash $ docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub -e SE_EVENT_BUS_PUBLISH_PORT=4442 \ - -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 -e START_XVFB=false --shm-size="2g" selenium/node-chrome:4.16.0-20231206 + -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 -e START_XVFB=false --shm-size="2g" selenium/node-chrome:4.16.1-20231219 ``` For more information, see this GitHub [issue](https://github.com/SeleniumHQ/docker-selenium/issues/567). @@ -962,7 +962,7 @@ pod and then scale a new one after N sessions. Set the environment variable `SE_ a value higher than zero to enable this behaviour. ``` bash -$ docker run -e SE_DRAIN_AFTER_SESSION_COUNT=5 --shm-size="2g" selenium/standalone-firefox:4.16.0-20231206 +$ docker run -e SE_DRAIN_AFTER_SESSION_COUNT=5 --shm-size="2g" selenium/standalone-firefox:4.16.1-20231219 ``` With the previous command, the Standalone container will shut down after 5 sessions have been executed. @@ -988,6 +988,17 @@ $ BUILD_ARGS="--build-arg http_proxy=http://acme:3128 --build-arg https_proxy=ht _Note: Omitting_ `VERSION=local` _will build the images with the released version but replacing the date for the current one._ +If you want to build the image with the host UID/GID, simply set an environment variable `BUILD_ARGS` + +``` bash +$ BUILD_ARGS="--build-arg UID=$(id -u) --build-arg GID=$(id -g)" make build +``` + +If you want to build the image with different default user/password, simply set an environment variable `BUILD_ARGS` + +``` bash +$ BUILD_ARGS="--build-arg SEL_USER=yourseluser --build-arg SEL_PASSWD=welcome" make build +``` ___ ## Waiting for the Grid to be ready @@ -1054,22 +1065,22 @@ $ docker network create grid $ docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub \ --health-cmd='/opt/bin/check-grid.sh --host 0.0.0.0 --port 4444' \ --health-interval=15s --health-timeout=30s --health-retries=5 \ - selenium/hub:4.16.0-20231206 + selenium/hub:4.16.1-20231219 $ docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub \ --shm-size="2g" \ -e SE_EVENT_BUS_PUBLISH_PORT=4442 \ -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \ - selenium/node-chrome:4.16.0-20231206 + selenium/node-chrome:4.16.1-20231219 $ docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub \ --shm-size="2g" \ -e SE_EVENT_BUS_PUBLISH_PORT=4442 \ -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \ - selenium/node-edge:4.16.0-20231206 + selenium/node-edge:4.16.1-20231219 $ docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub \ --shm-size="2g" \ -e SE_EVENT_BUS_PUBLISH_PORT=4442 \ -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \ - selenium/node-firefox:4.16.0-20231206 + selenium/node-firefox:4.16.1-20231219 ``` **Note:** The `\` line delimiter won't work on Windows-based terminals, try either `^` or a backtick. @@ -1202,7 +1213,7 @@ RUN mkdir -p -m755 /seluser/.pki/nssdb \ && chown -R 1200:1201 /seluser # Start from Selenium image and add relevant files from build image -FROM selenium/node-chrome:4.16.0-20231206 +FROM selenium/node-chrome:4.16.1-20231219 USER root COPY --from=build /seluser/ /home/seluser/ USER seluser @@ -1217,7 +1228,7 @@ RUN mkdir -p "/distribution" "/certs" && \ echo '{ "policies": { "Certificates": { "Install": ["/opt/firefox-latest/YOUR_CA.pem"] }} }' >"/distribution/policies.json" # Start from Selenium image and add relevant files from build image -FROM selenium/node-firefox:4.16.0-20231206 +FROM selenium/node-firefox:4.16.1-20231219 USER root COPY --from=build /certs /opt/firefox-latest COPY --from=build /distribution /opt/firefox-latest/distribution @@ -1240,9 +1251,9 @@ You can override it with the `SE_VNC_PORT` environment variable in case you want Here is an example with the standalone images, the same concept applies to the node images. ``` bash -$ docker run -d -p 4444:4444 -p 5900:5900 --shm-size="2g" selenium/standalone-chrome:4.16.0-20231206 -$ docker run -d -p 4445:4444 -p 5901:5900 --shm-size="2g" selenium/standalone-edge:4.16.0-20231206 -$ docker run -d -p 4446:4444 -p 5902:5900 --shm-size="2g" selenium/standalone-firefox:4.16.0-20231206 +$ docker run -d -p 4444:4444 -p 5900:5900 --shm-size="2g" selenium/standalone-chrome:4.16.1-20231219 +$ docker run -d -p 4445:4444 -p 5901:5900 --shm-size="2g" selenium/standalone-edge:4.16.1-20231219 +$ docker run -d -p 4446:4444 -p 5902:5900 --shm-size="2g" selenium/standalone-firefox:4.16.1-20231219 ``` Then, you would use in your VNC client: @@ -1257,6 +1268,8 @@ If you want to run VNC without password authentication you can set the environme If you want to run VNC in view-only mode you can set the environment variable `SE_VNC_VIEW_ONLY=1`. +If you want to modify the open file descriptor limit for the VNC server process you can set the environment variable `SE_VNC_ULIMIT=4096`. + ### Using your browser (no VNC client is needed) This project uses [noVNC](https://github.com/novnc/noVNC) to allow users to inspect visually container activity with @@ -1268,9 +1281,9 @@ You can also override it with the `SE_NO_VNC_PORT` environment variable in case Here is an example with the standalone images, the same concept applies to the node images. ``` bash -$ docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" selenium/standalone-chrome:4.16.0-20231206 -$ docker run -d -p 4445:4444 -p 7901:7900 --shm-size="2g" selenium/standalone-edge:4.16.0-20231206 -$ docker run -d -p 4446:4444 -p 7902:7900 --shm-size="2g" selenium/standalone-firefox:4.16.0-20231206 +$ docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" selenium/standalone-chrome:4.16.1-20231219 +$ docker run -d -p 4445:4444 -p 7901:7900 --shm-size="2g" selenium/standalone-edge:4.16.1-20231219 +$ docker run -d -p 4446:4444 -p 7902:7900 --shm-size="2g" selenium/standalone-firefox:4.16.1-20231219 ``` Then, you would use in your browser: @@ -1295,28 +1308,28 @@ In order to enable tracing in the Selenium Grid container, the following command ```bash docker network create grid docker run -d -p 16686:16686 -p 14250:14250 --net grid --name jaeger jaegertracing/all-in-one:1.17 -docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub selenium/hub:4.16.0-20231206 +docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub selenium/hub:4.16.1-20231219 docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub \ --shm-size="2g" \ -e SE_ENABLE_TRACING=true \ -e JAVA_OPTS="-Dotel.traces.exporter=jaeger -Dotel.exporter.jaeger.endpoint=http://jaegar:14250 -Dotel.resource.attributes=service.name=selenium-node-chrome" \ -e SE_EVENT_BUS_PUBLISH_PORT=4442 \ -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \ - selenium/node-chrome:4.16.0-20231206 + selenium/node-chrome:4.16.1-20231219 docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub \ --shm-size="2g" \ -e SE_ENABLE_TRACING=true \ -e JAVA_OPTS="-Dotel.traces.exporter=jaeger -Dotel.exporter.jaeger.endpoint=http://jaegar:14250 -Dotel.resource.attributes=service.name=selenium-node-edge" \ -e SE_EVENT_BUS_PUBLISH_PORT=4442 \ -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \ - selenium/node-edge:4.16.0-20231206 + selenium/node-edge:4.16.1-20231219 docker run -d --net grid -e SE_EVENT_BUS_HOST=selenium-hub \ --shm-size="2g" \ -e SE_ENABLE_TRACING=true \ -e JAVA_OPTS="-Dotel.traces.exporter=jaeger -Dotel.exporter.jaeger.endpoint=http://jaegar:14250 -Dotel.resource.attributes=service.name=selenium-node-firefox" \ -e SE_EVENT_BUS_PUBLISH_PORT=4442 \ -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \ - selenium/node-firefox:4.16.0-20231206 + selenium/node-firefox:4.16.1-20231219 ``` You can also refer to the below docker-compose yaml files to be able to start a simple grid (or) a dynamic grid. @@ -1375,12 +1388,13 @@ container in the following way: ```bash docker run -d -p 4444:4444 --shm-size="2g" \ - -v /home/ubuntu/files:/home/seluser/files \ - selenium/standalone-chrome:4.16.0-20231206 + -v /home/ubuntu/files:/home/seluser/Downloads \ + selenium/standalone-chrome:4.16.1-20231219 ``` That will mount the host `/home/ubuntu/files` directory -to the `/home/seluser/files` inside the container. The +to the `/home/seluser/Downloads` inside the container +(default browser's downloads directory). The problem happens because the volume will be mounted as `root`; therefore, the browser cannot write a file to that directory because it is running under the user @@ -1399,6 +1413,6 @@ chown 1200:1201 /home/ubuntu/files After doing this, you should be able to download files to the mounted directory. If you have a better workaround, -please send us a pull request! +please send us a pull request! diff --git a/Router/Dockerfile b/Router/Dockerfile index ccce7a2ff0..3410b932f8 100644 --- a/Router/Dockerfile +++ b/Router/Dockerfile @@ -4,7 +4,7 @@ ARG AUTHORS FROM ${NAMESPACE}/base:${VERSION} LABEL authors=${AUTHORS} -USER 1200 +USER ${SEL_UID} #======================== # Selenium Router Configuration @@ -17,7 +17,7 @@ ENV SE_SESSION_RETRY_INTERVAL 0 EXPOSE 4444 -COPY start-selenium-grid-router.sh \ +COPY --chown="${SEL_UID}:${SEL_GID}" start-selenium-grid-router.sh \ /opt/bin/ COPY selenium-grid-router.conf /etc/supervisor/conf.d/ diff --git a/Router/start-selenium-grid-router.sh b/Router/start-selenium-grid-router.sh index 1c3103dfc6..bb848a1c7e 100755 --- a/Router/start-selenium-grid-router.sh +++ b/Router/start-selenium-grid-router.sh @@ -54,6 +54,11 @@ if [ ! -z "$SE_ROUTER_PORT" ]; then PORT_CONFIG="--port ${SE_ROUTER_PORT}" fi +if [ ! -z "$SE_LOG_LEVEL" ]; then + echo "Appending Selenium options: --log-level ${SE_LOG_LEVEL}" + SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" +fi + EXTRA_LIBS="" if [ ! -z "$SE_ENABLE_TRACING" ]; then diff --git a/SessionQueue/Dockerfile b/SessionQueue/Dockerfile index bf62132796..bf4c7be89b 100644 --- a/SessionQueue/Dockerfile +++ b/SessionQueue/Dockerfile @@ -4,7 +4,7 @@ ARG AUTHORS FROM ${NAMESPACE}/base:${VERSION} LABEL authors=${AUTHORS} -USER 1200 +USER ${SEL_UID} #======================== # Selenium SessionQueue Configuration @@ -17,7 +17,7 @@ ENV SE_SESSION_RETRY_INTERVAL 15 EXPOSE 5559 -COPY start-selenium-grid-session-queue.sh \ +COPY --chown="${SEL_UID}:${SEL_GID}" start-selenium-grid-session-queue.sh \ /opt/bin/ COPY selenium-grid-session-queue.conf /etc/supervisor/conf.d/ diff --git a/SessionQueue/start-selenium-grid-session-queue.sh b/SessionQueue/start-selenium-grid-session-queue.sh index b92c116bd6..11074afb95 100755 --- a/SessionQueue/start-selenium-grid-session-queue.sh +++ b/SessionQueue/start-selenium-grid-session-queue.sh @@ -19,6 +19,11 @@ if [ ! -z "$SE_SESSION_QUEUE_PORT" ]; then PORT_CONFIG="--port ${SE_SESSION_QUEUE_PORT}" fi +if [ ! -z "$SE_LOG_LEVEL" ]; then + echo "Appending Selenium options: --log-level ${SE_LOG_LEVEL}" + SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" +fi + EXTRA_LIBS="" if [ ! -z "$SE_ENABLE_TRACING" ]; then diff --git a/Sessions/Dockerfile b/Sessions/Dockerfile index b069e84f75..99e89344b6 100644 --- a/Sessions/Dockerfile +++ b/Sessions/Dockerfile @@ -4,7 +4,7 @@ ARG AUTHORS FROM ${NAMESPACE}/base:${VERSION} LABEL authors=${AUTHORS} -USER 1200 +USER ${SEL_UID} #======================== # Selenium SessionMap Configuration @@ -12,7 +12,7 @@ USER 1200 EXPOSE 5556 -COPY start-selenium-grid-sessions.sh \ +COPY --chown="${SEL_UID}:${SEL_GID}" start-selenium-grid-sessions.sh \ /opt/bin/ COPY selenium-grid-sessions.conf /etc/supervisor/conf.d/ diff --git a/Sessions/start-selenium-grid-sessions.sh b/Sessions/start-selenium-grid-sessions.sh index 8dd9db1955..4d34a1a5bf 100755 --- a/Sessions/start-selenium-grid-sessions.sh +++ b/Sessions/start-selenium-grid-sessions.sh @@ -34,6 +34,11 @@ if [ ! -z "$SE_SESSIONS_PORT" ]; then PORT_CONFIG="--port ${SE_SESSIONS_PORT}" fi +if [ ! -z "$SE_LOG_LEVEL" ]; then + echo "Appending Selenium options: --log-level ${SE_LOG_LEVEL}" + SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" +fi + EXTRA_LIBS="" if [ ! -z "$SE_ENABLE_TRACING" ]; then diff --git a/Standalone/Dockerfile b/Standalone/Dockerfile index addb83f9cb..6907532223 100644 --- a/Standalone/Dockerfile +++ b/Standalone/Dockerfile @@ -5,12 +5,12 @@ ARG BASE FROM ${NAMESPACE}/${BASE}:${VERSION} LABEL authors=${AUTHORS} -USER 1200 +USER ${SEL_UID} #==================================== # Scripts to run Selenium Standalone #==================================== -COPY start-selenium-standalone.sh /opt/bin/start-selenium-standalone.sh +COPY --chown="${SEL_UID}:${SEL_GID}" start-selenium-standalone.sh /opt/bin/start-selenium-standalone.sh #============================== # Supervisor configuration file @@ -18,7 +18,7 @@ COPY start-selenium-standalone.sh /opt/bin/start-selenium-standalone.sh COPY selenium.conf /etc/supervisor/conf.d/ # Copying configuration script generator -COPY generate_config /opt/bin/generate_config +COPY --chown="${SEL_UID}:${SEL_GID}" generate_config /opt/bin/generate_config # Boolean value, maps "--relax-checks" ENV SE_RELAX_CHECKS true diff --git a/Standalone/start-selenium-standalone.sh b/Standalone/start-selenium-standalone.sh index cfde62d8eb..955cb15f4f 100755 --- a/Standalone/start-selenium-standalone.sh +++ b/Standalone/start-selenium-standalone.sh @@ -11,6 +11,11 @@ if [ ! -z "$SE_OPTS" ]; then echo "Appending Selenium options: ${SE_OPTS}" fi +if [ ! -z "$SE_LOG_LEVEL" ]; then + echo "Appending Selenium options: --log-level ${SE_LOG_LEVEL}" + SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" +fi + /opt/bin/generate_config echo "Selenium Grid Standalone configuration: " diff --git a/StandaloneDocker/Dockerfile b/StandaloneDocker/Dockerfile index 166d902ac9..e2d1f5de93 100644 --- a/StandaloneDocker/Dockerfile +++ b/StandaloneDocker/Dockerfile @@ -4,7 +4,7 @@ ARG AUTHORS FROM ${NAMESPACE}/node-docker:${VERSION} LABEL authors=${AUTHORS} -USER 1200 +USER ${SEL_UID} #======================== # Selenium Standalone Docker Configuration @@ -12,7 +12,7 @@ USER 1200 EXPOSE 4444 -COPY start-selenium-grid-docker.sh /opt/bin/ +COPY --chown="${SEL_UID}:${SEL_GID}" start-selenium-grid-docker.sh /opt/bin/ # Boolean value, maps "--relax-checks" ENV SE_RELAX_CHECKS true diff --git a/StandaloneDocker/start-selenium-grid-docker.sh b/StandaloneDocker/start-selenium-grid-docker.sh index 2f4ad1e134..8571abc7a8 100755 --- a/StandaloneDocker/start-selenium-grid-docker.sh +++ b/StandaloneDocker/start-selenium-grid-docker.sh @@ -14,6 +14,11 @@ if [ ! -z "$SE_NODE_GRID_URL" ]; then SE_GRID_URL="--grid-url ${SE_NODE_GRID_URL}" fi +if [ ! -z "$SE_LOG_LEVEL" ]; then + echo "Appending Selenium options: --log-level ${SE_LOG_LEVEL}" + SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" +fi + EXTRA_LIBS="" if [ ! -z "$SE_ENABLE_TRACING" ]; then diff --git a/charts/selenium-grid/CHANGELOG.md b/charts/selenium-grid/CHANGELOG.md index 4f3e5f4058..747eb3b22a 100644 --- a/charts/selenium-grid/CHANGELOG.md +++ b/charts/selenium-grid/CHANGELOG.md @@ -1,6 +1,65 @@ -# Change Log +## :heavy_check_mark: selenium-grid-0.26.4 -All notable changes to this helm chart will be documented in this file. +- Chart is using image tag 4.16.1-20231219 + +### Fixed +- fix(chart): Remove trailing slash from default subPath value (#2076) :: Viet Nguyen Duc + +### Changed +- Update chart CHANGELOG [skip ci] :: Selenium CI Bot + +## :heavy_check_mark: selenium-grid-0.26.3 + +- Chart is using image tag 4.16.1-20231219 + +### Added +- feat(chart): Simplify to access Selenium Grid from outside of Kubernetes (#2073) :: Viet Nguyen Duc +- feat(chart): Simplify to change log level in Kubernetes (#2072) :: Viet Nguyen Duc + +### Fixed +- bug: ENV variable SE_VNC_PASSWORD contains sensitive data (#2061) :: Viet Nguyen Duc + +### Changed +- Update tag in docs and files :: Selenium CI Bot +- Update chart CHANGELOG [skip ci] :: Selenium CI Bot + +## :heavy_check_mark: selenium-grid-0.26.2 + +- Chart is using image tag 4.16.1-20231212 + +### Changed +- Update tag in docs and files :: Selenium CI Bot +- Update chart CHANGELOG [skip ci] :: Selenium CI Bot + +## :heavy_check_mark: selenium-grid-0.26.1 + +- Chart is using image tag 4.16.1-20231208 + +### Added +- Add script to generate chart CHANGELOG after released (#2054) :: Viet Nguyen Duc +- feat(chart): Append subPath to ENV variable SE_NODE_GRID_URL (#2053) :: Viet Nguyen Duc + +### Changed +- Update tag in docs and files :: Selenium CI Bot + +## :heavy_check_mark: selenium-grid-0.26.0 + +- Chart is using image tag 4.16.0-20231206 + +### Added +- feat(chart): Add default annotations for ingress nginx controller (#2047) :: Viet Nguyen Duc +- feat: Video image with based FFmpeg-6.1 on Ubuntu-22.04 (#2042) :: Viet Nguyen Duc + +### Fixed +- bug(#1824): Container ENV SE_NODE_SESSION_TIMEOUT not take effect (#2044) :: Viet Nguyen Duc +- bug(#2038): Rollback io.opentelemetry 1.31.0 - add test tracing enabled (#2040) :: Viet Nguyen Duc + +### Changed +- Update tag in docs and files :: Selenium CI Bot +- Update chart CHANGELOG [skip ci] :: Viet Nguyen Duc +- test(chart): Parallel tests execution against autoscaling in Kubernetes (#2046) :: Viet Nguyen Duc +- test(chart): Chart template render and assert output (#2043) :: Viet Nguyen Duc +- test(chart): Add test for setting registry to pull images (#2036) :: Viet Nguyen Duc ## :heavy_check_mark: 0.25.3 diff --git a/charts/selenium-grid/Chart.yaml b/charts/selenium-grid/Chart.yaml index a3e55bf716..63dad9e7ba 100644 --- a/charts/selenium-grid/Chart.yaml +++ b/charts/selenium-grid/Chart.yaml @@ -2,14 +2,18 @@ apiVersion: v2 name: selenium-grid description: A Helm chart for creating a Selenium Grid Server in Kubernetes type: application -version: 0.26.0 -appVersion: 4.16.0-20231206 +version: 0.26.4 +appVersion: 4.16.1-20231219 icon: https://github.com/SeleniumHQ/docker-selenium/raw/trunk/logo.png dependencies: - repository: https://kedacore.github.io/charts - version: 2.12.0 + version: 2.12.1 name: keda condition: autoscaling.enabled +- repository: https://kubernetes.github.io/ingress-nginx + version: 4.8.3 + name: ingress-nginx + condition: ingress-nginx.enabled maintainers: - name: SeleniumHQ email: selenium-developers@googlegroups.com diff --git a/charts/selenium-grid/README.md b/charts/selenium-grid/README.md index 9fb0945079..3568d4cd5e 100644 --- a/charts/selenium-grid/README.md +++ b/charts/selenium-grid/README.md @@ -2,6 +2,39 @@ This chart enables the creation of a Selenium Grid Server in Kubernetes. +## Contents + +* [Selenium-Grid Helm Chart](#selenium-grid-helm-chart) + * [Contents](#contents) + * [Introduction](#introduction) + * [Installing the chart](#installing-the-chart) + * [Enable Selenium Grid Autoscaling](#enable-selenium-grid-autoscaling) + * [Settings common for both `job` and `deployment` scalingType](#settings-common-for-both-job-and-deployment-scalingtype) + * [Settings when scalingType with `deployment`](#settings-when-scalingtype-with-deployment-) + * [Settings when scalingType with `job`](#settings-when-scalingtype-with-job) + * [Updating Selenium-Grid release](#updating-selenium-grid-release) + * [Uninstalling Selenium Grid release](#uninstalling-selenium-grid-release) + * [Ingress Configuration](#ingress-configuration) + * [Configuration](#configuration) + * [Configuration global](#configuration-global) + * [Configuration `global.K8S_PUBLIC_IP`](#configuration-globalk8spublicip) + * [Configuration of Nodes](#configuration-of-nodes) + * [Container ports and Service ports](#container-ports-and-service-ports) + * [Probes](#probes) + * [Configuration of Selenium Grid chart](#configuration-of-selenium-grid-chart) + * [Configuration of KEDA](#configuration-of-keda) + * [Configuration of Ingress NGINX Controller](#configuration-of-ingress-nginx-controller) + * [Configuration for Selenium-Hub](#configuration-for-selenium-hub) + * [Configuration for isolated components](#configuration-for-isolated-components) + + +## Introduction + +We offer a Helm chart to simplify the deployment of Selenium Grid Docker images to Kubernetes. +- Chart changes are tracked in [CHANGELOG](CHANGELOG.md). +- Sanity/Regression tests for the chart features are tracked in [TESTING](TESTING.md). +- There are some reference values file that used to test and deploy Selenium Grid chart. You can find them in [tests/charts/refValues](../../tests/charts/refValues) and [tests/charts/ci](../../tests/charts/ci). + ## Installing the chart If you want to install the latest master version of Selenium Grid onto your cluster you can do that by using the helm charts repository located at https://www.selenium.dev/docker-selenium. @@ -46,14 +79,82 @@ or [jobs](https://keda.sh/docs/latest/concepts/scaling-jobs/) and the charts sup chart support both modes. It is controlled with `autoscaling.scalingType` that can be set to either job (default) or deployment. -### Settings when scaling with deployments +### Settings common for both `job` and `deployment` scalingType + +There are few settings that are common for both scaling types. These are grouped under `autoscaling.scaledOptions`. + +In case individual node should be scaled differently, you can override the upstream settings with `.scaledOptions` for each node type. For example: + +```yaml +autoscaling: + scaledOptions: + minReplicaCount: 0 + maxReplicaCount: 8 + pollingInterval: 20 + +chromeNode: + scaledOptions: + minReplicaCount: 1 + maxReplicaCount: 16 + pollingInterval: 10 +``` + +### Settings when scalingType with `deployment` + +By default, `autoscaling.terminationGracePeriodSeconds` is set to 3600 seconds. This is used when scalingType is set to `deployment`. You can adjust this value, it will affect to all nodes. + +In case individual node which needs to set different period, you can override the upstream settings with `.terminationGracePeriodSeconds` for each node type. Note that override value must be greater than upstream setting to take effect. For example: + +```yaml +autoscaling: + terminationGracePeriodSeconds: 3600 #default +chromeNode: + terminationGracePeriodSeconds: 7200 #override +firefoxNode: + terminationGracePeriodSeconds: 1800 #not override +``` + +When scaling using deployments the HPA choose pods to terminate randomly. If the chosen pod is currently executing a test rather +than being idle, then there is `terminationGracePeriodSeconds` seconds before the test is expected to complete. If your test is +still executing after `terminationGracePeriodSeconds` seconds, it would result in failure as the pod will be killed. -The `terminationGracePeriodSeconds` is set to 30 seconds by default. When scaling using deployments -the HPA choose pods to terminate randomly. If the chosen pod is currently executing a test rather -than being idle, then there is 30 seconds before the test is expected to complete. If your test is -still executing after 30 seconds, it would result in failure as the pod will be killed. If you want -to give more time for your tests to complete, you may set `terminationGracePeriodSeconds` to value -upto 3600 seconds. +During `terminationGracePeriodSeconds` period, there is `preStop` hook to execute command to wait for the pod can be shut down gracefully which can be defined in `.deregisterLifecycle` +- There is a `_helpers` template with name `seleniumGrid.node.deregisterLifecycle` render value for pod `lifecycle.preStop`. By default, hook to execute the script to drain node and wait for current session to complete if any. The script is stored in node ConfigMap, more details can be seen in config `nodeConfigMap.` +- You can define your custom `preStop` hook which is applied for all nodes via `autoscaling.deregisterLifecycle` +- In case individual node which needs different hook, you can override the upstream settings with `.deregisterLifecycle` for each node type. If you want to disable upstream hook in a node, pass the value as `false` +- If an individual node has settings `.lifecycle` itself, it would take the highest precedence to override the above use cases. + +```yaml +autoscaling: + deregisterLifecycle: + preStop: + exec: + command: ["bash", "-c", "echo 'Your custom preStop hook applied for all nodes'"] +chromeNode: + deregisterLifecycle: false #disable upstream hook in chrome node +firefoxNode: + deregisterLifecycle: + preStop: + exec: + command: ["bash", "-c", "echo 'Your custom preStop hook specific for firefox node'"] +edgeNode: + lifecycle: + preStop: + exec: + command: ["bash", "-c", "echo 'preStop hook is defined in edge node lifecycle itself'"] +``` + +For other settings that KEDA [ScaledObject spec](https://keda.sh/docs/latest/concepts/scaling-deployments/#scaledobject-spec) supports, you can set them via `autoscaling.scaledObjectOptions`. For example: + +```yaml +autoscaling: + scaledObjectOptions: + cooldownPeriod: 60 +``` + +### Settings when scalingType with `job` + +Settings that KEDA [ScaledJob spec](https://keda.sh/docs/latest/concepts/scaling-jobs/#scaledjob-spec) supports can be set via `autoscaling.scaledJobOptions`. ## Updating Selenium-Grid release @@ -81,7 +182,7 @@ helm uninstall selenium-grid ## Ingress Configuration -By default, ingress is enabled without annotations set. If NGINX ingress controller is used, you need to set few annotations to override the default timeout values to avoid 504 errors (see #1808). Since in Selenium Grid the default of `SE_NODE_SESSION_TIMEOUT` and `SE_SESSION_REQUEST_TIMEOUT` is `300` seconds. +By default, ingress is enabled without annotations set. If NGINX ingress controller is used, you need to set few annotations to override the default timeout values to avoid 504 errors (see [#1808](https://github.com/SeleniumHQ/docker-selenium/issues/1808)). Since in Selenium Grid the default of `SE_NODE_SESSION_TIMEOUT` and `SE_SESSION_REQUEST_TIMEOUT` is `300` seconds. In order to make user experience better, there are few annotations will be set by default if NGINX ingress controller is used. Mostly relates to timeouts and buffer sizes. @@ -129,18 +230,119 @@ nginx.ingress.kubernetes.io/proxy-buffers-number ## Configuration +### Configuration global For now, global configuration supported is: -| Parameter | Default | Description | -|---------------------------------------|-----------------------|---------------------------------------| -| `global.seleniumGrid.imageRegistry` | `selenium` | Distribution registry to pull images | -| `global.seleniumGrid.imageTag` | `4.16.0-20231206` | Image tag for all selenium components | -| `global.seleniumGrid.nodesImageTag` | `4.16.0-20231206` | Image tag for browser's nodes | -| `global.seleniumGrid.videoImageTag` | `ffmpeg-6.1-20231206` | Image tag for browser's video recoder | -| `global.seleniumGrid.imagePullSecret` | `""` | Pull secret to be used for all images | -| `global.seleniumGrid.imagePullSecret` | `""` | Pull secret to be used for all images | -| `global.seleniumGrid.affinity` | `{}` | Affinity assigned globally | +| Parameter | Default | Description | +|---------------------------------------|-----------------------|----------------------------------------| +| `global.K8S_PUBLIC_IP` | `""` | Public IP of the host running K8s | +| `global.seleniumGrid.imageRegistry` | `selenium` | Distribution registry to pull images | +| `global.seleniumGrid.imageTag` | `4.16.1-20231219` | Image tag for all selenium components | +| `global.seleniumGrid.nodesImageTag` | `4.16.1-20231219` | Image tag for browser's nodes | +| `global.seleniumGrid.videoImageTag` | `ffmpeg-6.1-20231219` | Image tag for browser's video recorder | +| `global.seleniumGrid.imagePullSecret` | `""` | Pull secret to be used for all images | +| `global.seleniumGrid.imagePullSecret` | `""` | Pull secret to be used for all images | +| `global.seleniumGrid.affinity` | `{}` | Affinity assigned globally | +| `global.seleniumGrid.logLevel` | `INFO` | Set log level for all components | + +#### Configuration `global.K8S_PUBLIC_IP` + +This is the public IP of the host running Kubernetes cluster. Mainly, it is used to construct the URL for the Selenium Grid (Hub or Router) can be accessed from the outside of the cluster for Node register, Grid UI, RemoteWebDriver, etc. +- Ingress is enabled without setting `ingress.hostname`. All the services will be exposed via the public IP is set in `K8S_PUBLIC_IP`. +- Using NodePort to expose the services. All the services will be exposed via the public IP is set in `K8S_PUBLIC_IP`. +- Using LoadBalancer to expose the services. All the services will be exposed via the LB External IP is set in `K8S_PUBLIC_IP`. + +For example: +```yaml +global: + K8S_PUBLIC_IP: "10.10.10.10" +ingress: + enabled: true + hostname: "" +hub: + subPath: "/selenium" + serviceType: NodePort +``` +``` +# Source: selenium-grid/templates/node-configmap.yaml + +SE_NODE_GRID_URL: 'http://admin:admin@10.10.10.10/selenium' +``` +Besides that, from the outside of the cluster, you can access via NodePort http://10.10.10.10:30444/selenium + +### Configuration of Nodes + +#### Container ports and Service ports + +By default, Node will use port `5555` to listen on container (following [this](https://www.selenium.dev/documentation/grid/configuration/cli_options/#server)) and expose via Service. You can update this value via `.port` in respective node type. This will be used to set `SE_NODE_PORT` environment variable to pass to option `--port` when starting the node and update in Service accordingly. + +By default, if httpGet probes are enabled, it will use `.port` value in respective node type unless you override it via e.g. `.startupProbe.port` `.readinessProbe.port` or `.livenessProbe.port` in respective node type. + +In a node container, there are other running services can be exposed. For example: VNC, NoVNC, SSH, etc. You can easily expose them on container via `.ports` and on Service `service.ports` in respective node type. + +```yaml +chromeNode: + port: 6666 # Update `SE_NODE_PORT` to 6666 + nodePort: 30666 # Specify a NodePort to expose `SE_NODE_PORT` to outside traffic + ports: + - 5900 # You can give port number alone, default protocol is TCP + - 7900 + service: + type: NodePort # Expose entire ports on Service via NodePort + ports: + - name: vnc-port + protocol: TCP + port: 5900 + targetPort: 5900 + nodePort: 30590 # Specify a NodePort to expose VNC port + - name: novnc-port + protocol: TCP + port: 7900 + targetPort: 7900 + # NodePort will be assigned randomly if not set +edgeNode: + ports: # You also can give object following manifest of container ports + - containerPort: 5900 + name: vnc + protocol: TCP + - containerPort: 7900 + name: novnc + protocol: TCP +``` + +#### Probes +By default, `startupProbe` is enabled and `readinessProbe` and `livenessProbe` are disabled. You can enable/disable them via `.startupProbe.enabled` `.readinessProbe.enabled` `.livenessProbe.enabled` in respective node type. + +By default, probes are using `httpGet` method to check the node state. It will use `.port` value in respective node type unless you override it via e.g. `.startupProbe.port` `.readinessProbe.port` or `.livenessProbe.port` in respective node type. + +Other settings of probe support to override under `.startupProbe` `.readinessProbe` `.livenessProbe` in respective node type. + +```markdown + schema + path + port + initialDelaySeconds + failureThreshold + timeoutSeconds + periodSeconds + successThreshold +``` + +You can easily configure the probes (as Kubernetes [supports](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/)) to override the default settings. For example: + +```yaml +edgeNode: + port: 5555 + startupProbe: + enabled: true + tcpSocket: + port: 5555 + failureThreshold: 10 + periodSeconds: 5 +``` + +### Configuration of Selenium Grid chart This table contains the configuration parameters of the chart and their default values: | Parameter | Default | Description | @@ -162,6 +364,8 @@ This table contains the configuration parameters of the chart and their default | `ingress.nginx.proxyTimeout` | `3600` | Value is used to set for NGINX ingress annotations related to proxy timeout | | `ingress.nginx.proxyBuffer.size` | `512M` | Value is used to set for NGINX ingress annotations on size of the buffer proxy_buffer_size used for reading | | `ingress.nginx.proxyBuffer.number` | `4` | Value is used to set for NGINX ingress annotations on number of the buffers in proxy_buffers used for reading | +| `ingress.ports.http` | `80` | Port to expose for HTTP | +| `ingress.ports.https` | `443` | Port to expose for HTTPS | | `ingress.hostname` | `` | Default host for the ingress resource | | `ingress.path` | `/` | Default host path for the ingress resource | | `ingress.pathType` | `Prefix` | Default path type for the ingress resource | @@ -182,12 +386,12 @@ This table contains the configuration parameters of the chart and their default | `chromeNode.replicas` | `1` | Number of chrome nodes. Disabled if autoscaling is enabled. | | `chromeNode.imageRegistry` | `nil` | Distribution registry to pull the image (this overwrites `.global.seleniumGrid.imageRegistry` value) | | `chromeNode.imageName` | `node-chrome` | Image of chrome nodes | -| `chromeNode.imageTag` | `4.16.0-20231206` | Image of chrome nodes | +| `chromeNode.imageTag` | `4.16.1-20231219` | Image of chrome nodes | | `chromeNode.imagePullPolicy` | `IfNotPresent` | Image pull policy (see https://kubernetes.io/docs/concepts/containers/images/#updating-images) | | `chromeNode.imagePullSecret` | `""` | Image pull secret (see https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry) | -| `chromeNode.ports` | `[5555]` | Port list to enable on container | -| `chromeNode.seleniumPort` | `5900` | Selenium port (spec.ports[0].targetPort in kubernetes service) | -| `chromeNode.seleniumServicePort` | `6900` | Selenium port exposed in service (spec.ports[0].port in kubernetes service) | +| `chromeNode.ports` | `[]` | Extra ports list to enable on container (e.g VNC, NoVNC, SSH if any) | +| `chromeNode.port` | `5555` | Port is used to set `SE_NODE_PORT` | +| `chromeNode.nodePort` | `nil` | NodePort where chrome-node exposed | | `chromeNode.annotations` | `{}` | Annotations for chrome-node pods | | `chromeNode.labels` | `{}` | Labels for chrome-node pods | | `chromeNode.resources` | `See values.yaml` | Resources for chrome-node pods | @@ -205,8 +409,9 @@ This table contains the configuration parameters of the chart and their default | `chromeNode.service.ports` | `[]` | Extra ports exposed in node service | | `chromeNode.service.annotations` | `{}` | Custom annotations for service | | `chromeNode.dshmVolumeSizeLimit` | `1Gi` | Size limit for DSH volume mounted in container (if not set, default is "1Gi") | -| `chromeNode.startupProbe` | `{}` | Probe to check pod is started successfully | -| `chromeNode.livenessProbe` | `{}` | Liveness probe settings | +| `chromeNode.startupProbe.enabled` | `true` | Enable Probe to check pod is started successfully (the following configs see `values.yaml`) | +| `chromeNode.readinessProbe.enabled` | `false` | Enable Readiness probe settings (the following configs see `values.yaml`) | +| `chromeNode.livenessProbe.enabled` | `false` | Enable Liveness probe settings (the following configs see `values.yaml`) | | `chromeNode.terminationGracePeriodSeconds` | `30` | Time to graceful terminate container (default: 30s) | | `chromeNode.lifecycle` | `{}` | hooks to make pod correctly shutdown or started | | `chromeNode.extraVolumeMounts` | `[]` | Extra mounts of declared ExtraVolumes into pod | @@ -222,12 +427,12 @@ This table contains the configuration parameters of the chart and their default | `firefoxNode.replicas` | `1` | Number of firefox nodes. Disabled if autoscaling is enabled. | | `firefoxNode.imageRegistry` | `nil` | Distribution registry to pull the image (this overwrites `.global.seleniumGrid.imageRegistry` value) | | `firefoxNode.imageName` | `node-firefox` | Image of firefox nodes | -| `firefoxNode.imageTag` | `4.16.0-20231206` | Image of firefox nodes | +| `firefoxNode.imageTag` | `4.16.1-20231219` | Image of firefox nodes | | `firefoxNode.imagePullPolicy` | `IfNotPresent` | Image pull policy (see https://kubernetes.io/docs/concepts/containers/images/#updating-images) | | `firefoxNode.imagePullSecret` | `""` | Image pull secret (see https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry) | -| `firefoxNode.ports` | `[5555]` | Port list to enable on container | -| `firefoxNode.seleniumPort` | `5900` | Selenium port (spec.ports[0].targetPort in kubernetes service) | -| `firefoxNode.seleniumServicePort` | `6900` | Selenium port exposed in service (spec.ports[0].port in kubernetes service) | +| `firefoxNode.ports` | `[]` | Extra ports list to enable on container (e.g VNC, NoVNC, SSH if any) | +| `firefoxNode.port` | `5555` | Port is used to set `SE_NODE_PORT` | +| `firefoxNode.nodePort` | `nil` | NodePort where firefox-node exposed | | `firefoxNode.annotations` | `{}` | Annotations for firefox-node pods | | `firefoxNode.labels` | `{}` | Labels for firefox-node pods | | `firefoxNode.resources` | `See values.yaml` | Resources for firefox-node pods | @@ -245,8 +450,9 @@ This table contains the configuration parameters of the chart and their default | `firefoxNode.service.ports` | `[]` | Extra ports exposed in node service | | `firefoxNode.service.annotations` | `{}` | Custom annotations for service | | `firefoxNode.dshmVolumeSizeLimit` | `1Gi` | Size limit for DSH volume mounted in container (if not set, default is "1Gi") | -| `firefoxNode.startupProbe` | `{}` | Probe to check pod is started successfully | -| `firefoxNode.livenessProbe` | `{}` | Liveness probe settings | +| `firefoxNode.startupProbe.enabled` | `true` | Enable Probe to check pod is started successfully (the following configs see `values.yaml`) | +| `firefoxNode.readinessProbe.enabled` | `false` | Enable Readiness probe settings (the following configs see `values.yaml`) | +| `firefoxNode.livenessProbe.enabled` | `false` | Enable Liveness probe settings (the following configs see `values.yaml`) | | `firefoxNode.terminationGracePeriodSeconds` | `30` | Time to graceful terminate container (default: 30s) | | `firefoxNode.lifecycle` | `{}` | hooks to make pod correctly shutdown or started | | `firefoxNode.extraVolumeMounts` | `[]` | Extra mounts of declared ExtraVolumes into pod | @@ -262,12 +468,12 @@ This table contains the configuration parameters of the chart and their default | `edgeNode.replicas` | `1` | Number of edge nodes. Disabled if autoscaling is enabled. | | `edgeNode.imageRegistry` | `nil` | Distribution registry to pull the image (this overwrites `.global.seleniumGrid.imageRegistry` value) | | `edgeNode.imageName` | `node-edge` | Image of edge nodes | -| `edgeNode.imageTag` | `4.16.0-20231206` | Image of edge nodes | +| `edgeNode.imageTag` | `4.16.1-20231219` | Image of edge nodes | | `edgeNode.imagePullPolicy` | `IfNotPresent` | Image pull policy (see https://kubernetes.io/docs/concepts/containers/images/#updating-images) | | `edgeNode.imagePullSecret` | `""` | Image pull secret (see https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry) | -| `edgeNode.ports` | `[5555]` | Port list to enable on container | -| `edgeNode.seleniumPort` | `5900` | Selenium port (spec.ports[0].targetPort in kubernetes service) | -| `edgeNode.seleniumServicePort` | `6900` | Selenium port exposed in service (spec.ports[0].port in kubernetes service) | +| `edgeNode.ports` | `[]` | Extra ports list to enable on container (e.g VNC, NoVNC, SSH if any) | +| `edgeNode.port` | `5555` | Port is used to set `SE_NODE_PORT` | +| `edgeNode.nodePort` | `nil` | NodePort where edge-node exposed | | `edgeNode.annotations` | `{}` | Annotations for edge-node pods | | `edgeNode.labels` | `{}` | Labels for edge-node pods | | `edgeNode.resources` | `See values.yaml` | Resources for edge-node pods | @@ -285,8 +491,9 @@ This table contains the configuration parameters of the chart and their default | `edgeNode.service.ports` | `[]` | Extra ports exposed in node service | | `edgeNode.service.annotations` | `{}` | Custom annotations for service | | `edgeNode.dshmVolumeSizeLimit` | `1Gi` | Size limit for DSH volume mounted in container (if not set, default is "1Gi") | -| `edgeNode.startupProbe` | `{}` | Probe to check pod is started successfully | -| `edgeNode.livenessProbe` | `{}` | Liveness probe settings | +| `edgeNode.startupProbe.enabled` | `true` | Enable Probe to check pod is started successfully (the following configs see `values.yaml`) | +| `edgeNode.readinessProbe.enabled` | `false` | Enable Readiness probe settings (the following configs see `values.yaml`) | +| `edgeNode.livenessProbe.enabled` | `false` | Enable Liveness probe settings (the following configs see `values.yaml`) | | `edgeNode.terminationGracePeriodSeconds` | `30` | Time to graceful terminate container (default: 30s) | | `edgeNode.lifecycle` | `{}` | hooks to make pod correctly shutdown or started | | `edgeNode.extraVolumeMounts` | `[]` | Extra mounts of declared ExtraVolumes into pod | @@ -299,8 +506,8 @@ This table contains the configuration parameters of the chart and their default | `edgeNode.scaledObjectOptions` | See `values.yaml` | Override the global `autoscaling.scaledObjectOptions` with specific scaled options for edge nodes | | `videoRecorder.enabled` | `false` | Enable video recorder for node | | `videoRecorder.imageRegistry` | `nil` | Distribution registry to pull the image (this overwrites `.global.seleniumGrid.imageRegistry` value) | -| `videoRecorder.imageName` | `video` | Selenium video recoder image name | -| `videoRecorder.imageTag` | `ffmpeg-6.1-20231206` | Image tag of video recorder | +| `videoRecorder.imageName` | `video` | Selenium video recorder image name | +| `videoRecorder.imageTag` | `ffmpeg-6.1-20231219` | Image tag of video recorder | | `videoRecorder.imagePullPolicy` | `IfNotPresent` | Image pull policy (see https://kubernetes.io/docs/concepts/containers/images/#updating-images) | | `videoRecorder.uploader` | `false` | Name of the uploader to use. The value `false` is used to disable uploader. Supported default `s3` | | `videoRecorder.uploadDestinationPrefix` | `false` | Destination URL for uploading video file. The value `false` is used to disable the uploading | @@ -321,15 +528,21 @@ This table contains the configuration parameters of the chart and their default | `videoRecorder.s3.extraEnvFrom` | `` | Custom environment taken from `configMap` or `secret` variables for video uploader | | `videoRecorder.s3.extraVolumeMounts` | `[]` | Extra mounts of declared ExtraVolumes into pod of video uploader | | `customLabels` | `{}` | Custom labels for k8s resources | +| `ingress-nginx.enabled` | `false` | Enable the dependency chart Ingress controller for Kubernetes (https://github.com/kubernetes/ingress-nginx) | ### Configuration of KEDA -If you are setting `autoscaling.enabled` to `true` KEDA is installed and can be configured with +If you are setting `autoscaling.enabled` to `true`, chart KEDA is installed and can be configured with values with the prefix `keda`. So you can for example set `keda.prometheus.metricServer.enabled` to `true` to enable the metrics server for KEDA. See https://github.com/kedacore/charts/blob/main/keda/README.md for more details. +### Configuration of Ingress NGINX Controller + +If you are setting `ingress-nginx.enabled` to `true`, chart Ingress NGINX Controller is installed and can be configured with +values with the prefix `ingress-nginx`. See https://github.com/kubernetes/ingress-nginx for more details. + ### Configuration for Selenium-Hub You can configure the Selenium Hub with these values: @@ -344,8 +557,11 @@ You can configure the Selenium Hub with these values: | `hub.annotations` | `{}` | Custom annotations for Selenium Hub pod | | `hub.labels` | `{}` | Custom labels for Selenium Hub pod | | `hub.publishPort` | `4442` | Port where events are published | +| `hub.publishNodePort` | `31442` | NodePort where events are published | | `hub.subscribePort` | `4443` | Port where to subscribe for events | +| `hub.subscribeNodePort` | `31443` | NodePort where to subscribe for events | | `hub.port` | `4444` | Selenium Hub port | +| `hub.nodePort` | `31444` | Selenium Hub NodePort | | `hub.livenessProbe` | `See values.yaml` | Liveness probe settings | | `hub.readinessProbe` | `See values.yaml` | Readiness probe settings | | `hub.tolerations` | `[]` | Tolerations for selenium-hub pods | @@ -377,6 +593,7 @@ If you implement selenium-grid with separate components (`isolateComponents: tru | `components.router.imagePullSecret` | `""` | Image pull secret (see https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry) | | `components.router.annotations` | `{}` | Custom annotations for router pod | | `components.router.port` | `4444` | Router port | +| `components.router.nodePort` | `30444` | Router NodePort | | `components.router.livenessProbe` | `See values.yaml` | Liveness probe settings | | `components.router.readinessProbe` | `See values.yaml` | Readiness probe settings | | `components.router.resources` | `{}` | Resources for router pod | @@ -395,6 +612,7 @@ If you implement selenium-grid with separate components (`isolateComponents: tru | `components.distributor.imagePullSecret` | `""` | Image pull secret (see https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry) | | `components.distributor.annotations` | `{}` | Custom annotations for Distributor pod | | `components.distributor.port` | `5553` | Distributor port | +| `components.distributor.nodePort` | `30553` | Distributor NodePort | | `components.distributor.resources` | `{}` | Resources for Distributor pod | | `components.distributor.securityContext` | `See values.yaml` | Security context for Distributor pod | | `components.distributor.serviceType` | `ClusterIP` | Kubernetes service type (see https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) | @@ -410,8 +628,11 @@ If you implement selenium-grid with separate components (`isolateComponents: tru | `components.eventBus.imagePullSecret` | `""` | Image pull secret (see https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry) | | `components.eventBus.annotations` | `{}` | Custom annotations for Event Bus pod | | `components.eventBus.port` | `5557` | Event Bus port | +| `components.eventBus.nodePort` | `30557` | Event Bus NodePort | | `components.eventBus.publishPort` | `4442` | Port where events are published | +| `components.eventBus.publishNodePort` | `30442` | NodePort where events are published | | `components.eventBus.subscribePort` | `4443` | Port where to subscribe for events | +| `components.eventBus.subscribeNodePort` | `30443` | NodePort where to subscribe for events | | `components.eventBus.resources` | `{}` | Resources for event-bus pod | | `components.eventBus.securityContext` | `See values.yaml` | Security context for event-bus pod | | `components.eventBus.serviceType` | `ClusterIP` | Kubernetes service type (see https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) | @@ -441,6 +662,7 @@ If you implement selenium-grid with separate components (`isolateComponents: tru | `components.sessionQueue.imagePullSecret` | `""` | Image pull secret (see https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry) | | `components.sessionQueue.annotations` | `{}` | Custom annotations for Session Queue pod | | `components.sessionQueue.port` | `5559` | Session Queue Port | +| `components.sessionQueue.nodePort` | `30559` | Session Queue NodePort | | `components.sessionQueue.resources` | `{}` | Resources for Session Queue pod | | `components.sessionQueue.securityContext` | `See values.yaml` | Security context for Session Queue pod | | `components.sessionQueue.serviceType` | `ClusterIP` | Kubernetes service type (see https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) | diff --git a/charts/selenium-grid/TESTING.md b/charts/selenium-grid/TESTING.md index 7e94f85e40..fd29f09c1c 100644 --- a/charts/selenium-grid/TESTING.md +++ b/charts/selenium-grid/TESTING.md @@ -10,7 +10,7 @@ All related testing to this helm chart will be documented in this file. | | Basic Auth is enabled | ✗ | | | Auto scaling | Auto scaling with `enableWithExistingKEDA` is `true` | ✓ | Cluster | | | Auto scaling with `scalingType` is `job` | ✓ | Cluster | -| | Auto scaling with `scalingType` is `deployment` | ✗ | | +| | Auto scaling with `scalingType` is `deployment` | ✓ | Cluster | | | Auto scaling with `autoscaling.scaledOptions.minReplicaCount` is `0` | ✓ | Cluster | | | Parallel tests execution against node autoscaling | ✓ | Cluster | | Ingress | Ingress is enabled without `hostname` | ✓ | Cluster | @@ -27,6 +27,10 @@ All related testing to this helm chart will be documented in this file. | | Components are able to set `.affinity` | ✓ | Template | | Tracing | Enable tracing via `SE_ENABLE_TRACING` | ✓ | Cluster | | | Disable tracing via `SE_ENABLE_TRACING` | ✓ | Cluster | +| `Node` component | `SE_NODE_PORT` can set a port different via `.port` | ✓ | Cluster | +| | Extra ports can be exposed on container via `.ports` | ✓ | Cluster | +| | Extra ports can be exposed on Service via `.service.ports` | ✓ | Cluster | +| | Service type change to `NodePort`, specific NodePort can be set | ✓ | Cluster | ## Test Chart Template - By using `helm template` command, the chart template is tested without installing it to Kubernetes cluster. diff --git a/charts/selenium-grid/templates/NOTES.txt b/charts/selenium-grid/templates/NOTES.txt index ce79f74b5a..949f854ec4 100644 --- a/charts/selenium-grid/templates/NOTES.txt +++ b/charts/selenium-grid/templates/NOTES.txt @@ -9,20 +9,27 @@ Selenium Grid Server deployed successfully. {{- if .Values.ingress.enabled }} {{- if .Values.ingress.hostname }} 1. Ingress is enabled, and it exposes the Grid Hub or Grid Router with the hostname you supplied. - To access Selenium from outside of Kubernetes, simply open http://{{ .Values.ingress.hostname }}. - {{- else}} + To access Selenium from outside of Kubernetes, simply open {{ include "seleniumGrid.url" .}}. + {{- else if and (empty .Values.ingress.hostname) .Values.global.K8S_PUBLIC_IP }} +1. Ingress is enabled, but hostname doesn't set, and it exposes the Grid Hub or Grid Router with the K8S_PUBLIC_IP you supplied. + To access Selenium from outside of Kubernetes, simply open {{ include "seleniumGrid.url" .}}. + {{- else }} 1. Ingress is enabled, but hostname doesn't set. All inbound HTTP traffic will be routed to the Grid by matching any host. Please keep in mind that it is rarely necessary, and in most cases, you shall provide `ingress.hostname` in values.yaml. To access Selenium from outside of Kubernetes: - - open IP of the any node with Ingress, or + - open the IP of any node with Ingress, or - any hostname pointing to the node with Ingress {{- end}} {{- else}} -1. Ingress is disabled. To access Selenium from outside of Kubernetes, simply run these commands: {{- if contains "NodePort" $serviceType }} - export NODE_PORT=$(kubectl get -n {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" svc {{ $svcName }}) + {{- if .Values.global.K8S_PUBLIC_IP }} +1. Ingress is disabled, and it exposes the Grid Hub or Grid Router with NodePort and the K8S_PUBLIC_IP you supplied + To access Selenium from outside of Kubernetes with NodePort and K8S_PUBLIC_IP you supplied, simply open {{ include "seleniumGrid.url" .}}. + {{- else }} +1. Ingress is disabled. To access Selenium from outside of Kubernetes, simply run these commands: export NODE_IP=$(kubectl get nodes -n {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo http://$NODE_IP:$NODE_PORT + echo http://$NODE_IP:{{ include "seleniumGrid.url.port" .}}{{ include "seleniumGrid.url.subPath" .}} + {{- end }} {{- else if contains "LoadBalancer" $serviceType }} NOTE: It may take a few minutes for the LoadBalancer IP to be available. You can watch the status of by running 'kubectl get -n {{ .Release.Namespace }} svc -w {{ $svcName }}' diff --git a/charts/selenium-grid/templates/_helpers.tpl b/charts/selenium-grid/templates/_helpers.tpl index 9e44267d95..baa2bc3beb 100644 --- a/charts/selenium-grid/templates/_helpers.tpl +++ b/charts/selenium-grid/templates/_helpers.tpl @@ -80,6 +80,56 @@ Ingress fullname {{- default "selenium-ingress" .Values.ingress.nameOverride | trunc 63 | trimSuffix "-" -}} {{- end -}} +{{/* +Probe httpGet schema +*/}} +{{- define "seleniumGrid.probe.httpGet.schema" -}} +{{- "HTTP" -}} +{{- end -}} + +{{/* +Check user define custom probe method +*/}} +{{- define "seleniumGrid.probe.fromUserDefine" -}} +{{- $overrideProbe := dict -}} +{{- with .exec -}} +{{- $overrideProbe = dict "exec" . -}} +{{- end }} +{{- with .httpGet -}} +{{- $overrideProbe = dict "httpGet" . -}} +{{- end }} +{{- with .tcpSocket -}} +{{- $overrideProbe = dict "tcpSocket" . -}} +{{- end }} +{{- with .grpc -}} +{{- $overrideProbe = dict "grpc" . -}} +{{- end -}} +{{- $overrideProbe | toYaml -}} +{{- end -}} + +{{/* +Get probe settings +*/}} +{{- define "seleniumGrid.probe.settings" -}} +{{- $settings := dict -}} +{{- with .initialDelaySeconds -}} + {{- $settings = set $settings "initialDelaySeconds" . -}} +{{- end }} +{{- with .periodSeconds -}} + {{- $settings = set $settings "periodSeconds" . -}} +{{- end }} +{{- with .timeoutSeconds -}} + {{- $settings = set $settings "timeoutSeconds" . -}} +{{- end }} +{{- with .successThreshold -}} + {{- $settings = set $settings "successThreshold" . -}} +{{- end }} +{{- with .failureThreshold -}} + {{- $settings = set $settings "failureThreshold" . -}} +{{- end -}} +{{- $settings | toYaml -}} +{{- end -}} + {{- define "seleniumGrid.ingress.nginx.annotations.default" -}} {{- with .Values.ingress.nginx }} {{- with .proxyTimeout }} @@ -199,27 +249,42 @@ template: {{- $imageRegistry := default .Values.global.seleniumGrid.imageRegistry .node.imageRegistry }} image: {{ printf "%s/%s:%s" $imageRegistry .node.imageName $imageTag }} imagePullPolicy: {{ .node.imagePullPolicy }} - {{- with .node.extraEnvironmentVariables }} - env: {{- tpl (toYaml .) $ | nindent 10 }} - {{- end }} + env: + - name: SE_NODE_PORT + value: {{ .node.port | quote }} + {{- with .node.extraEnvironmentVariables }} + {{- tpl (toYaml .) $ | nindent 10 }} + {{- end }} envFrom: - configMapRef: name: {{ .Values.busConfigMap.name }} - configMapRef: name: {{ .Values.nodeConfigMap.name }} + - configMapRef: + name: {{ .Values.loggingConfigMap.name }} {{- with .node.extraEnvFrom }} {{- tpl (toYaml .) $ | nindent 10 }} {{- end }} - {{- if gt (len .node.ports) 0 }} ports: - {{- range .node.ports }} - - containerPort: {{ . }} + - containerPort: {{ .node.port }} protocol: TCP + {{- if gt (len .node.ports) 0 }} + {{- $ports := .node.ports -}} + {{- if (regexMatch "[0-9]+$" (index $ports 0 | toString)) -}} + {{- range .node.ports }} + - containerPort: {{ . | int }} + protocol: TCP + {{- end }} + {{- else -}} + {{- tpl (toYaml .node.ports) $ | nindent 10 }} {{- end }} {{- end }} volumeMounts: - name: dshm mountPath: /dev/shm + - name: {{ .Values.nodeConfigMap.scriptVolumeMountName }} + mountPath: /opt/selenium/{{ .Values.nodeConfigMap.preStopScript }} + subPath: {{ .Values.nodeConfigMap.preStopScript }} {{- if .node.extraVolumeMounts }} {{- tpl (toYaml .node.extraVolumeMounts) $ | nindent 10 }} {{- end }} @@ -229,12 +294,54 @@ template: {{- with .node.securityContext }} securityContext: {{- toYaml . | nindent 10 }} {{- end }} - {{- include "seleniumGrid.lifecycle" . | nindent 8 -}} + {{- include "seleniumGrid.node.lifecycle" . | nindent 8 -}} + {{- if .node.startupProbe.enabled }} {{- with .node.startupProbe }} - startupProbe: {{- toYaml . | nindent 10 }} + startupProbe: + {{- if (ne (include "seleniumGrid.probe.fromUserDefine" .) "{}") }} + {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 10 }} + {{- else }} + httpGet: + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + path: {{ .path }} + port: {{ default ($.node.port) .port }} + {{- end }} + {{- if (ne (include "seleniumGrid.probe.settings" .) "{}") }} + {{- include "seleniumGrid.probe.settings" . | nindent 10 }} + {{- end }} + {{- end }} + {{- end }} + {{- if .node.readinessProbe.enabled }} + {{- with .node.readinessProbe }} + readinessProbe: + {{- if (ne (include "seleniumGrid.probe.fromUserDefine" .) "{}") }} + {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 12 }} + {{- else }} + httpGet: + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + path: {{ .path }} + port: {{ default ($.node.port) .port }} + {{- end }} + {{- if (ne (include "seleniumGrid.probe.settings" .) "{}") }} + {{- include "seleniumGrid.probe.settings" . | nindent 10 }} + {{- end }} {{- end }} + {{- end }} + {{- if .node.livenessProbe.enabled }} {{- with .node.livenessProbe }} - livenessProbe: {{- toYaml . | nindent 10 }} + livenessProbe: + {{- if (ne (include "seleniumGrid.probe.fromUserDefine" .) "{}") }} + {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 10 }} + {{- else }} + httpGet: + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + path: {{ .path }} + port: {{ default ($.node.port) .port }} + {{- end }} + {{- if (ne (include "seleniumGrid.probe.settings" .) "{}") }} + {{- include "seleniumGrid.probe.settings" . | nindent 10 }} + {{- end }} + {{- end }} {{- end }} {{- if .node.sidecars }} {{- toYaml .node.sidecars | nindent 6 }} @@ -323,6 +430,10 @@ template: {{- end }} terminationGracePeriodSeconds: {{ .node.terminationGracePeriodSeconds }} volumes: + - name: {{ .Values.nodeConfigMap.scriptVolumeMountName }} + configMap: + name: {{ .Values.nodeConfigMap.name }} + defaultMode: {{ .Values.nodeConfigMap.defaultMode }} - name: dshm emptyDir: medium: Memory @@ -339,34 +450,139 @@ template: Get the url of the grid. If the external url can be figured out from the ingress use that, otherwise the cluster internal url */}} {{- define "seleniumGrid.url" -}} -{{- if and .Values.ingress.enabled .Values.ingress.hostname (ne .Values.ingress.hostname "selenium-grid.local") -}} -http{{if .Values.ingress.tls}}s{{end}}://{{- if eq .Values.basicAuth.enabled true}}{{ .Values.basicAuth.username}}:{{ .Values.basicAuth.password}}@{{- end}}{{.Values.ingress.hostname}} +{{- $url := printf "%s://%s%s%s%s" (include "seleniumGrid.url.schema" .) (include "seleniumGrid.url.basicAuth" .) (include "seleniumGrid.url.host" .) (include "seleniumGrid.url.port" .) (include "seleniumGrid.url.subPath" .) -}} +{{- $url }} +{{- end -}} + +{{- define "seleniumGrid.url.schema" -}} +{{- $schema := "http" -}} +{{- if .Values.ingress.enabled -}} + {{- if .Values.ingress.tls -}} + {{- $schema = "https" -}} + {{- end -}} +{{- end -}} +{{- $schema }} +{{- end -}} + +{{- define "seleniumGrid.url.basicAuth" -}} +{{- $basicAuth := "" -}} +{{- if eq .Values.basicAuth.enabled true -}} + {{- $basicAuth = printf "%s:%s@" .Values.basicAuth.username (.Values.basicAuth.password | toString) -}} +{{- end -}} +{{- $basicAuth }} +{{- end -}} + +{{- define "seleniumGrid.url.host" -}} +{{- $host := printf "%s.%s" (include ($.Values.isolateComponents | ternary "seleniumGrid.router.fullname" "seleniumGrid.hub.fullname") $ ) (.Release.Namespace) -}} +{{- if .Values.ingress.enabled -}} + {{- if and ( empty .Values.ingress.hostname) (not (empty .Values.global.K8S_PUBLIC_IP)) -}} + {{- $host = .Values.global.K8S_PUBLIC_IP -}} + {{- else if and .Values.ingress.hostname (ne .Values.ingress.hostname "selenium-grid.local") -}} + {{- $host = .Values.ingress.hostname -}} + {{- end -}} +{{- else if not (empty .Values.global.K8S_PUBLIC_IP) -}} + {{- $host = .Values.global.K8S_PUBLIC_IP -}} +{{- end -}} +{{- $host }} +{{- end -}} + +{{- define "seleniumGrid.url.port" -}} +{{- $port := ":4444" -}} +{{- if .Values.ingress.enabled -}} + {{- if or (ne (.Values.ingress.ports.http | toString) "80") (ne (.Values.ingress.ports.https | toString) "443") -}} + {{- $port = printf ":%s" (ternary (.Values.ingress.ports.http | toString) (.Values.ingress.ports.https | toString) (eq (include "seleniumGrid.url.schema" .) "http")) -}} + {{- else -}} + {{- $port = "" -}} + {{- end -}} {{- else -}} -http://{{- if eq .Values.basicAuth.enabled true}}{{ .Values.basicAuth.username}}:{{ .Values.basicAuth.password}}@{{- end}}{{ include ($.Values.isolateComponents | ternary "seleniumGrid.router.fullname" "seleniumGrid.hub.fullname") $ }}.{{ .Release.Namespace }}:{{ $.Values.components.router.port }} -{{- end }} + {{- if .Values.isolateComponents -}} + {{- if and (eq .Values.components.router.serviceType "NodePort") .Values.components.router.nodePort -}} + {{- $port = printf ":%s" (.Values.components.router.nodePort | toString) -}} + {{- end -}} + {{- else -}} + {{- if and (eq .Values.hub.serviceType "NodePort") .Values.hub.nodePort -}} + {{- $port = printf ":%s" (.Values.hub.nodePort | toString) -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{- $port }} +{{- end -}} + +{{- define "seleniumGrid.url.subPath" -}} +{{- $subPath := "" -}} +{{- if $.Values.isolateComponents -}} + {{- $subPath = default $subPath $.Values.components.subPath -}} +{{- else -}} + {{- $subPath = default $subPath $.Values.hub.subPath -}} +{{- end -}} +{{- $subPath }} {{- end -}} {{/* Graphql Url of the hub or the router */}} {{- define "seleniumGrid.graphqlURL" -}} -http://{{- if eq .Values.basicAuth.enabled true}}{{ .Values.basicAuth.username}}:{{ .Values.basicAuth.password}}@{{- end}}{{ include ($.Values.isolateComponents | ternary "seleniumGrid.router.fullname" "seleniumGrid.hub.fullname") $ }}.{{ .Release.Namespace }}:{{ $.Values.components.router.port }}/graphql +{{- printf "http://%s%s%s/graphql" (include "seleniumGrid.url.basicAuth" .) (printf "%s.%s" (include ($.Values.isolateComponents | ternary "seleniumGrid.router.fullname" "seleniumGrid.hub.fullname") $) (.Release.Namespace)) (printf ":%s" ($.Values.isolateComponents | ternary ($.Values.components.router.port | toString) ($.Values.hub.port | toString))) -}} {{- end -}} {{/* -Get the lifecycle of the pod. When KEDA is activated and the lifecycle is used for a pod of a -deployment preStop hook to deregister from the selenium hub. +Graphql unsafeSsl of the hub or the router */}} -{{- define "seleniumGrid.lifecycle" }} -{{ $lifecycle := tpl (toYaml (default (dict) .node.lifecycle)) $ }} -{{- if and (eq .Values.autoscaling.scalingType "deployment") (eq (include "seleniumGrid.useKEDA" .) "true") -}} -{{ $lifecycle = merge ($lifecycle | fromYaml ) .Values.autoscaling.deregisterLifecycle | toYaml }} +{{- define "seleniumGrid.graphqlURL.unsafeSsl" -}} +{{- $unsafeSsl := printf "%s" (ternary "false" "true" (contains (include "seleniumGrid.graphqlURL" .) "https")) -}} +{{- $unsafeSsl }} +{{- end -}} + +{{/* +Define preStop hook for the node pod. Node preStop script is stored in a ConfigMap and mounted as a volume. +*/}} +{{- define "seleniumGrid.node.deregisterLifecycle" -}} +preStop: + exec: + command: ["bash", "-c", "/opt/selenium/{{ .Values.nodeConfigMap.preStopScript }}"] +{{- end -}} + +{{/* +Get the lifecycle of the pod is used for a Node to deregister from the Hub/Router. +1. IF KEDA is activated, scalingType is "deployment", and individual node deregisterLifecycle is not set, use autoscaling.deregisterLifecycle +2. ELSE (KEDA is not activated and node deregisterLifecycle is set), use .deregisterLifecycle in individual node +3. IF individual node with .lifecycle is set, it takes highest precedence to override the preStop in above use cases +*/}} +{{- define "seleniumGrid.node.lifecycle" }} +{{- $defaultDeregisterLifecycle := tpl (include "seleniumGrid.node.deregisterLifecycle" .) $ -}} +{{- $lifecycle := toYaml (dict) -}} +{{- if and (and (eq .Values.autoscaling.scalingType "deployment") (eq (include "seleniumGrid.useKEDA" .) "true")) (empty .node.deregisterLifecycle) -}} + {{- $lifecycle = merge ($lifecycle | fromYaml) (tpl (toYaml (default ($defaultDeregisterLifecycle | fromYaml) .Values.autoscaling.deregisterLifecycle)) $ | fromYaml) | toYaml -}} +{{- else -}} + {{- if eq (.node.deregisterLifecycle | toString | lower) "false" -}} + {{- $lifecycle = toYaml (dict) -}} + {{- else -}} + {{- $lifecycle = (tpl (toYaml (default ($defaultDeregisterLifecycle | fromYaml) .node.deregisterLifecycle) ) $ | fromYaml) | toYaml -}} + {{- end -}} +{{- end -}} +{{- if not (empty .node.lifecycle) -}} + {{- $lifecycle = mergeOverwrite ($lifecycle | fromYaml) (tpl (toYaml .node.lifecycle) $ | fromYaml) | toYaml -}} {{- end -}} {{ if and $lifecycle (ne $lifecycle "{}") -}} lifecycle: {{ $lifecycle | nindent 2 }} {{- end -}} {{- end -}} +{{/* +Define terminationGracePeriodSeconds of the node pod. +1. IF KEDA is activated, scalingType is "deployment", use autoscaling.terminationGracePeriodSeconds +2. IF node.terminationGracePeriodSeconds is greater than autoscaling.terminationGracePeriodSeconds, use node.terminationGracePeriodSeconds +*/}} +{{- define "seleniumGrid.node.terminationGracePeriodSeconds" -}} +{{- $autoscalingPeriod := default 0 .Values.autoscaling.terminationGracePeriodSeconds -}} +{{- $nodePeriod := default 0 .node.terminationGracePeriodSeconds -}} +{{- $period := $nodePeriod -}} +{{- if and (eq .Values.autoscaling.scalingType "deployment") (eq (include "seleniumGrid.useKEDA" .) "true") -}} + {{- $period = ternary $nodePeriod $autoscalingPeriod (gt $nodePeriod $autoscalingPeriod) -}} +{{- end -}} +{{- $period -}} +{{- end -}} + {{/* Default specs of VolumeMounts and Volumes for video recorder */}} diff --git a/charts/selenium-grid/templates/chrome-node-service.yaml b/charts/selenium-grid/templates/chrome-node-service.yaml index efe8f1873b..a6965c3d04 100644 --- a/charts/selenium-grid/templates/chrome-node-service.yaml +++ b/charts/selenium-grid/templates/chrome-node-service.yaml @@ -22,8 +22,11 @@ spec: ports: - name: tcp-chrome protocol: TCP - port: {{ .Values.chromeNode.seleniumServicePort }} - targetPort: {{ .Values.chromeNode.seleniumPort }} + port: {{ .Values.chromeNode.port }} + targetPort: {{ .Values.chromeNode.port }} + {{- if and (eq $.Values.chromeNode.service.type "NodePort") .Values.chromeNode.nodePort }} + nodePort: {{ .Values.chromeNode.nodePort }} + {{- end }} {{- with .Values.chromeNode.service.ports }} {{- range . }} - name: {{ .name }} diff --git a/charts/selenium-grid/templates/distributor-deployment.yaml b/charts/selenium-grid/templates/distributor-deployment.yaml index 07462f15ef..990e519fb8 100644 --- a/charts/selenium-grid/templates/distributor-deployment.yaml +++ b/charts/selenium-grid/templates/distributor-deployment.yaml @@ -47,6 +47,8 @@ spec: envFrom: - configMapRef: name: {{ .Values.busConfigMap.name }} + - configMapRef: + name: {{ .Values.loggingConfigMap.name }} {{- with .Values.components.extraEnvFrom }} {{- toYaml . | nindent 12 }} {{- end }} diff --git a/charts/selenium-grid/templates/distributor-service.yaml b/charts/selenium-grid/templates/distributor-service.yaml index 295407fac8..86b99e5b4e 100644 --- a/charts/selenium-grid/templates/distributor-service.yaml +++ b/charts/selenium-grid/templates/distributor-service.yaml @@ -23,4 +23,7 @@ spec: protocol: TCP port: {{ .Values.components.distributor.port }} targetPort: {{ .Values.components.distributor.port }} + {{- if and (eq .Values.components.distributor.serviceType "NodePort") .Values.components.distributor.nodePort }} + nodePort: {{ .Values.components.distributor.nodePort }} + {{- end }} {{- end }} diff --git a/charts/selenium-grid/templates/edge-node-service.yaml b/charts/selenium-grid/templates/edge-node-service.yaml index d54dd70a3b..896be0ac95 100644 --- a/charts/selenium-grid/templates/edge-node-service.yaml +++ b/charts/selenium-grid/templates/edge-node-service.yaml @@ -22,8 +22,11 @@ spec: ports: - name: tcp-edge protocol: TCP - port: {{ .Values.edgeNode.seleniumServicePort }} - targetPort: {{ .Values.edgeNode.seleniumPort }} + port: {{ .Values.edgeNode.port }} + targetPort: {{ .Values.edgeNode.port }} + {{- if and (eq $.Values.edgeNode.service.type "NodePort") .Values.edgeNode.nodePort }} + nodePort: {{ .Values.edgeNode.nodePort }} + {{- end }} {{- with .Values.edgeNode.service.ports }} {{- range . }} - name: {{ .name }} diff --git a/charts/selenium-grid/templates/event-bus-configmap.yaml b/charts/selenium-grid/templates/event-bus-configmap.yaml index 05f279bba5..ad2b337562 100644 --- a/charts/selenium-grid/templates/event-bus-configmap.yaml +++ b/charts/selenium-grid/templates/event-bus-configmap.yaml @@ -1,4 +1,4 @@ -{{- $eventBusHost := ternary (include "seleniumGrid.eventBus.fullname" .) (include "seleniumGrid.hub.fullname" .) .Values.isolateComponents -}} +{{- $eventBusHost := printf "%s.%s" (ternary (include "seleniumGrid.eventBus.fullname" .) (include "seleniumGrid.hub.fullname" .) .Values.isolateComponents) (.Release.Namespace) -}} {{- $eventBusPublishPort := ternary .Values.components.eventBus.publishPort .Values.hub.publishPort .Values.isolateComponents -}} {{- $eventBusSubscribePort := ternary .Values.components.eventBus.subscribePort .Values.hub.subscribePort .Values.isolateComponents -}} apiVersion: v1 diff --git a/charts/selenium-grid/templates/event-bus-deployment.yaml b/charts/selenium-grid/templates/event-bus-deployment.yaml index 8d894790b7..498570c9b8 100644 --- a/charts/selenium-grid/templates/event-bus-deployment.yaml +++ b/charts/selenium-grid/templates/event-bus-deployment.yaml @@ -42,10 +42,12 @@ spec: {{- with .Values.components.extraEnvironmentVariables }} env: {{- tpl (toYaml .) $ | nindent 12 }} {{- end }} - {{- with .Values.components.extraEnvFrom }} envFrom: + - configMapRef: + name: {{ .Values.loggingConfigMap.name }} + {{- with .Values.components.extraEnvFrom }} {{- toYaml . | nindent 12 }} - {{- end }} + {{- end }} {{- with .Values.components.eventBus.resources }} resources: {{- toYaml . | nindent 12 }} {{- end }} diff --git a/charts/selenium-grid/templates/event-bus-service.yaml b/charts/selenium-grid/templates/event-bus-service.yaml index c3a30bcc0e..c5c5b9052f 100644 --- a/charts/selenium-grid/templates/event-bus-service.yaml +++ b/charts/selenium-grid/templates/event-bus-service.yaml @@ -23,12 +23,21 @@ spec: protocol: TCP port: {{ .Values.components.eventBus.port }} targetPort: {{ .Values.components.eventBus.port }} + {{- if and (eq .Values.components.eventBus.serviceType "NodePort") .Values.components.eventBus.nodePort }} + nodePort: {{ .Values.components.eventBus.nodePort }} + {{- end }} - name: tcp-evtbus-pub protocol: TCP port: {{ .Values.components.eventBus.publishPort }} targetPort: {{ .Values.components.eventBus.publishPort }} + {{- if and (eq .Values.components.eventBus.serviceType "NodePort") .Values.components.eventBus.publishNodePort }} + nodePort: {{ .Values.components.eventBus.publishNodePort }} + {{- end }} - name: tcp-evtbus-sub protocol: TCP port: {{ .Values.components.eventBus.subscribePort }} targetPort: {{ .Values.components.eventBus.subscribePort }} + {{- if and (eq .Values.components.eventBus.serviceType "NodePort") .Values.components.eventBus.subscribeNodePort }} + nodePort: {{ .Values.components.eventBus.subscribeNodePort }} + {{- end }} {{- end }} diff --git a/charts/selenium-grid/templates/firefox-node-service.yaml b/charts/selenium-grid/templates/firefox-node-service.yaml index 43ba40380e..a0de36ca50 100644 --- a/charts/selenium-grid/templates/firefox-node-service.yaml +++ b/charts/selenium-grid/templates/firefox-node-service.yaml @@ -22,8 +22,11 @@ spec: ports: - name: tcp-firefox protocol: TCP - port: {{ .Values.firefoxNode.seleniumServicePort }} - targetPort: {{ .Values.firefoxNode.seleniumPort }} + port: {{ .Values.firefoxNode.port }} + targetPort: {{ .Values.firefoxNode.port }} + {{- if and (eq $.Values.firefoxNode.service.type "NodePort") .Values.firefoxNode.nodePort }} + nodePort: {{ .Values.firefoxNode.nodePort }} + {{- end }} {{- with .Values.firefoxNode.service.ports }} {{- range . }} - name: {{ .name }} diff --git a/charts/selenium-grid/templates/hub-deployment.yaml b/charts/selenium-grid/templates/hub-deployment.yaml index 8b322ecd59..71473b2097 100644 --- a/charts/selenium-grid/templates/hub-deployment.yaml +++ b/charts/selenium-grid/templates/hub-deployment.yaml @@ -42,31 +42,59 @@ spec: protocol: TCP - containerPort: {{ .Values.hub.subscribePort }} protocol: TCP - {{- if .Values.hub.livenessProbe.enabled }} - livenessProbe: + {{- if .Values.hub.startupProbe.enabled }} + {{- with .Values.hub.startupProbe }} + startupProbe: + {{- if (ne (include "seleniumGrid.probe.fromUserDefine" .) "{}") }} + {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 10 }} + {{- else }} httpGet: - path: {{ .Values.hub.livenessProbe.path }} - port: {{ .Values.hub.port }} - initialDelaySeconds: {{ .Values.hub.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.hub.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.hub.livenessProbe.timeoutSeconds }} - successThreshold: {{ .Values.hub.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.hub.livenessProbe.failureThreshold }} + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + path: {{ .path }} + port: {{ default ($.Values.hub.port) .port }} + {{- end }} + {{- if (ne (include "seleniumGrid.probe.settings" .) "{}") }} + {{- include "seleniumGrid.probe.settings" . | nindent 12 }} + {{- end }} + {{- end }} {{- end }} {{- if .Values.hub.readinessProbe.enabled }} + {{- with .Values.hub.readinessProbe }} readinessProbe: + {{- if (ne (include "seleniumGrid.probe.fromUserDefine" .) "{}") }} + {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 10 }} + {{- else }} + httpGet: + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + path: {{ .path }} + port: {{ default ($.Values.hub.port) .port }} + {{- end }} + {{- if (ne (include "seleniumGrid.probe.settings" .) "{}") }} + {{- include "seleniumGrid.probe.settings" . | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.hub.livenessProbe.enabled }} + {{- with .Values.hub.livenessProbe }} + livenessProbe: + {{- if (ne (include "seleniumGrid.probe.fromUserDefine" .) "{}") }} + {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 10 }} + {{- else }} httpGet: - path: {{ .Values.hub.readinessProbe.path }} - port: {{ .Values.hub.port }} - initialDelaySeconds: {{ .Values.hub.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.hub.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.hub.readinessProbe.timeoutSeconds }} - successThreshold: {{ .Values.hub.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.hub.readinessProbe.failureThreshold }} + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + path: {{ .path }} + port: {{ default ($.Values.hub.port) .port }} + {{- end }} + {{- if (ne (include "seleniumGrid.probe.settings" .) "{}") }} + {{- include "seleniumGrid.probe.settings" . | nindent 12 }} + {{- end }} + {{- end }} {{- end }} env: + {{- with .Values.hub.subPath }} - name: SE_SUB_PATH - value: {{ .Values.hub.subPath }} + value: {{ . | quote }} + {{- end }} {{- if eq .Values.basicAuth.enabled true}} - name: ROUTER_USERNAME value: {{ .Values.basicAuth.username }} @@ -76,10 +104,12 @@ spec: {{- with .Values.hub.extraEnvironmentVariables }} {{- tpl (toYaml .) $ | nindent 12 }} {{- end }} - {{- with .Values.hub.extraEnvFrom }} envFrom: + - configMapRef: + name: {{ .Values.loggingConfigMap.name }} + {{- with .Values.hub.extraEnvFrom }} {{- toYaml . | nindent 12 }} - {{- end }} + {{- end }} {{- with .Values.hub.extraVolumeMounts }} volumeMounts: {{- tpl (toYaml .) $ | nindent 12 }} diff --git a/charts/selenium-grid/templates/hub-service.yaml b/charts/selenium-grid/templates/hub-service.yaml index aa4daa34ca..0f394a6ebf 100644 --- a/charts/selenium-grid/templates/hub-service.yaml +++ b/charts/selenium-grid/templates/hub-service.yaml @@ -26,12 +26,21 @@ spec: protocol: TCP port: {{ .Values.hub.port }} targetPort: {{ .Values.hub.port }} + {{- if and (eq .Values.hub.serviceType "NodePort") .Values.hub.nodePort }} + nodePort: {{ .Values.hub.nodePort }} + {{- end }} - name: tcp-hub-pub protocol: TCP port: {{ .Values.hub.publishPort }} targetPort: {{ .Values.hub.publishPort }} + {{- if and (eq .Values.hub.serviceType "NodePort") .Values.hub.publishNodePort }} + nodePort: {{ .Values.hub.publishNodePort }} + {{- end }} - name: tcp-hub-sub protocol: TCP port: {{ .Values.hub.subscribePort }} targetPort: {{ .Values.hub.subscribePort }} + {{- if and (eq .Values.hub.serviceType "NodePort") .Values.hub.subscribeNodePort }} + nodePort: {{ .Values.hub.subscribeNodePort }} + {{- end }} {{- end }} diff --git a/charts/selenium-grid/templates/logging-configmap.yaml b/charts/selenium-grid/templates/logging-configmap.yaml new file mode 100644 index 0000000000..36acc3bded --- /dev/null +++ b/charts/selenium-grid/templates/logging-configmap.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Values.loggingConfigMap.name }} + namespace: {{ .Release.Namespace }} +{{- with .Values.loggingConfigMap.annotations }} + annotations: {{- toYaml . | nindent 4 }} +{{- end }} + labels: + {{- include "seleniumGrid.commonLabels" . | nindent 4 }} + {{- with .Values.customLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +data: + SE_LOG_LEVEL: "{{ default "INFO" .Values.global.seleniumGrid.logLevel }}" diff --git a/charts/selenium-grid/templates/node-configmap.yaml b/charts/selenium-grid/templates/node-configmap.yaml index da4edab401..807e2036cb 100644 --- a/charts/selenium-grid/templates/node-configmap.yaml +++ b/charts/selenium-grid/templates/node-configmap.yaml @@ -14,3 +14,11 @@ metadata: data: SE_DRAIN_AFTER_SESSION_COUNT: '{{- and (eq (include "seleniumGrid.useKEDA" .) "true") (eq .Values.autoscaling.scalingType "job") | ternary "1" "0" -}}' SE_NODE_GRID_URL: '{{ include "seleniumGrid.url" .}}' + {{ .Values.nodeConfigMap.preStopScript }}: | + #!/bin/bash + if curl -sf 127.0.0.1:${SE_NODE_PORT}/status; then + curl -X POST 127.0.0.1:${SE_NODE_PORT}/se/grid/node/drain --header 'X-REGISTRATION-SECRET;' + while curl -sf 127.0.0.1:${SE_NODE_PORT}/status; do sleep 1; done + else + echo "Node is already drained. Shutting down gracefully!" + fi diff --git a/charts/selenium-grid/templates/router-deployment.yaml b/charts/selenium-grid/templates/router-deployment.yaml index 33d98c65aa..e02829d464 100644 --- a/charts/selenium-grid/templates/router-deployment.yaml +++ b/charts/selenium-grid/templates/router-deployment.yaml @@ -45,8 +45,10 @@ spec: value: {{ template "seleniumGrid.sessionQueue.fullname" . }} - name: SE_SESSION_QUEUE_PORT value: {{ .Values.components.sessionQueue.port | quote }} + {{- with .Values.components.subPath }} - name: SE_SUB_PATH - value: {{ .Values.components.subPath }} + value: {{ . | quote }} + {{- end }} {{- if eq .Values.basicAuth.enabled true}} - name: ROUTER_USERNAME value: {{ .Values.basicAuth.username }} @@ -56,34 +58,63 @@ spec: {{- with .Values.components.extraEnvironmentVariables }} {{- tpl (toYaml .) $ | nindent 12 }} {{- end }} - {{- with .Values.components.extraEnvFrom }} envFrom: + - configMapRef: + name: {{ .Values.loggingConfigMap.name }} + {{- with .Values.components.extraEnvFrom }} {{- toYaml . | nindent 12 }} - {{- end }} + {{- end }} ports: - containerPort: {{ .Values.components.router.port }} protocol: TCP - {{- if .Values.components.router.livenessProbe.enabled }} - livenessProbe: + {{- if .Values.components.router.startupProbe.enabled }} + {{- with .Values.components.router.startupProbe }} + startupProbe: + {{- if (ne (include "seleniumGrid.probe.fromUserDefine" .) "{}") }} + {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 10 }} + {{- else }} httpGet: - path: {{ .Values.components.router.livenessProbe.path }} - port: {{ .Values.components.router.port }} - initialDelaySeconds: {{ .Values.components.router.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.components.router.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.components.router.livenessProbe.timeoutSeconds }} - successThreshold: {{ .Values.components.router.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.components.router.livenessProbe.failureThreshold }} + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + path: {{ .path }} + port: {{ default ($.Values.components.router.port) .port }} + {{- end }} + {{- if (ne (include "seleniumGrid.probe.settings" .) "{}") }} + {{- include "seleniumGrid.probe.settings" . | nindent 12 }} + {{- end }} + {{- end }} {{- end }} {{- if .Values.components.router.readinessProbe.enabled }} + {{- with .Values.components.router.readinessProbe }} readinessProbe: + {{- if (ne (include "seleniumGrid.probe.fromUserDefine" .) "{}") }} + {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 10 }} + {{- else }} httpGet: - path: {{ .Values.components.router.readinessProbe.path }} - port: {{ .Values.components.router.port }} - initialDelaySeconds: {{ .Values.components.router.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.components.router.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.components.router.readinessProbe.timeoutSeconds }} - successThreshold: {{ .Values.components.router.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.components.router.readinessProbe.failureThreshold }} + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + path: {{ .path }} + port: {{ default ($.Values.components.router.port) .port }} + {{- end }} + {{- if (ne (include "seleniumGrid.probe.settings" .) "{}") }} + {{- include "seleniumGrid.probe.settings" . | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.components.router.livenessProbe.enabled }} + livenessProbe: + {{- with .Values.components.router.livenessProbe }} + livenessProbe: + {{- if (ne (include "seleniumGrid.probe.fromUserDefine" .) "{}") }} + {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 10 }} + {{- else }} + httpGet: + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + path: {{ .path }} + port: {{ default ($.Values.components.router.port) .port }} + {{- end }} + {{- if (ne (include "seleniumGrid.probe.settings" .) "{}") }} + {{- include "seleniumGrid.probe.settings" . | nindent 12 }} + {{- end }} + {{- end }} {{- end }} {{- with .Values.components.router.resources }} resources: {{- toYaml . | nindent 12 }} diff --git a/charts/selenium-grid/templates/router-service.yaml b/charts/selenium-grid/templates/router-service.yaml index 9eaff79556..c93d04c119 100644 --- a/charts/selenium-grid/templates/router-service.yaml +++ b/charts/selenium-grid/templates/router-service.yaml @@ -26,4 +26,7 @@ spec: protocol: TCP port: {{ .Values.components.router.port }} targetPort: {{ .Values.components.router.port }} + {{- if and (eq $.Values.components.router.serviceType "NodePort") $.Values.components.router.nodePort }} + nodePort: {{ $.Values.components.router.nodePort }} + {{- end }} {{- end }} diff --git a/charts/selenium-grid/templates/session-map-deployment.yaml b/charts/selenium-grid/templates/session-map-deployment.yaml index 8aebdefb2c..2edd701e2e 100644 --- a/charts/selenium-grid/templates/session-map-deployment.yaml +++ b/charts/selenium-grid/templates/session-map-deployment.yaml @@ -36,6 +36,8 @@ spec: env: {{- tpl (toYaml .) $ | nindent 12 }} {{- end }} envFrom: + - configMapRef: + name: {{ .Values.loggingConfigMap.name }} - configMapRef: name: {{ .Values.busConfigMap.name }} {{- with .Values.components.extraEnvFrom }} diff --git a/charts/selenium-grid/templates/session-queuer-deployment.yaml b/charts/selenium-grid/templates/session-queuer-deployment.yaml index 557d6774e0..3792850381 100644 --- a/charts/selenium-grid/templates/session-queuer-deployment.yaml +++ b/charts/selenium-grid/templates/session-queuer-deployment.yaml @@ -35,10 +35,12 @@ spec: {{- with .Values.components.extraEnvironmentVariables }} env: {{- tpl (toYaml .) $ | nindent 12 }} {{- end }} - {{- with .Values.components.extraEnvFrom }} envFrom: + - configMapRef: + name: {{ .Values.loggingConfigMap.name }} + {{- with .Values.components.extraEnvFrom }} {{- toYaml . | nindent 12 }} - {{- end }} + {{- end }} ports: - containerPort: {{ .Values.components.sessionQueue.port }} protocol: TCP diff --git a/charts/selenium-grid/templates/session-queuer-service.yaml b/charts/selenium-grid/templates/session-queuer-service.yaml index 54e535f7b0..b0e0fe96d1 100644 --- a/charts/selenium-grid/templates/session-queuer-service.yaml +++ b/charts/selenium-grid/templates/session-queuer-service.yaml @@ -23,4 +23,7 @@ spec: protocol: TCP port: {{ .Values.components.sessionQueue.port }} targetPort: {{ .Values.components.sessionQueue.port }} + {{- if and (eq .Values.components.sessionQueue.serviceType "NodePort") .Values.components.sessionQueue.nodePort }} + nodePort: {{ .Values.components.sessionQueue.nodePort }} + {{- end }} {{- end }} diff --git a/charts/selenium-grid/values.yaml b/charts/selenium-grid/values.yaml index ae9840ce50..f4a094c16e 100644 --- a/charts/selenium-grid/values.yaml +++ b/charts/selenium-grid/values.yaml @@ -1,15 +1,21 @@ global: + # Public IP of the host running Kubernetes cluster. + # This is used to access the Selenium Grid from outside the cluster when ingress is disabled or enabled without a hostname is set. + # This is part of constructing SE_NODE_GRID_URL and rewrite URL of `se:vnc`, `se:cdp` in the capabilities when `ingress.hostname` is unset + K8S_PUBLIC_IP: "" seleniumGrid: # Image registry for all selenium components imageRegistry: selenium # Image tag for all selenium components - imageTag: 4.16.0-20231206 + imageTag: 4.16.1-20231219 # Image tag for browser's nodes - nodesImageTag: 4.16.0-20231206 + nodesImageTag: 4.16.1-20231219 # Image tag for browser's video recorder - videoImageTag: ffmpeg-6.1-20231206 + videoImageTag: ffmpeg-6.1-20231219 # Pull secret for all components, can be overridden individually imagePullSecret: "" + # Log level for all components. Possible values describe here: https://www.selenium.dev/documentation/grid/configuration/cli_options/#logging + logLevel: INFO # Basic auth settings for Selenium Grid basicAuth: @@ -42,6 +48,9 @@ ingress: proxyBuffer: size: 512M number: 4 + ports: + http: 80 + https: 443 # Custom annotations for ingress resource annotations: {} # Default host for the ingress resource @@ -65,6 +74,18 @@ busConfigMap: # ConfigMap that contains common environment variables for browser nodes nodeConfigMap: name: selenium-node-config + # Default mode for ConfigMap is mounted as file + defaultMode: 0755 + # File name of preStop script in ConfigMap + preStopScript: nodePreStop.sh + # Name of volume mount is used to mount scripts in the ConfigMap + scriptVolumeMountName: node-helper-scripts + # Custom annotations for configmap + annotations: {} + +# ConfigMap that contains common environment variables for Logging (https://www.selenium.dev/documentation/grid/configuration/cli_options/#logging) +loggingConfigMap: + name: selenium-logging-config # Custom annotations for configmap annotations: {} @@ -77,7 +98,7 @@ components: # Router image name imageName: router # Router image tag (this overwrites global.seleniumGrid.imageTag parameter) - # imageTag: 4.16.0-20231206 + # imageTag: 4.16.1-20231219 # Image pull policy (see https://kubernetes.io/docs/concepts/containers/images/#updating-images) imagePullPolicy: IfNotPresent @@ -88,11 +109,12 @@ components: annotations: {} # Router port port: 4444 - # Liveness probe settings - livenessProbe: + nodePort: 30444 + # Wait for pod startup + startupProbe: enabled: true path: /readyz - initialDelaySeconds: 10 + initialDelaySeconds: 5 failureThreshold: 10 timeoutSeconds: 10 periodSeconds: 10 @@ -106,6 +128,15 @@ components: timeoutSeconds: 10 periodSeconds: 10 successThreshold: 1 + # Liveness probe settings + livenessProbe: + enabled: true + path: /readyz + initialDelaySeconds: 10 + failureThreshold: 10 + timeoutSeconds: 10 + periodSeconds: 10 + successThreshold: 1 # Resources for router container resources: {} # SecurityContext for router container @@ -129,7 +160,7 @@ components: # Distributor image name imageName: distributor # Distributor image tag (this overwrites global.seleniumGrid.imageTag parameter) - # imageTag: 4.16.0-20231206 + # imageTag: 4.16.1-20231219 # Image pull policy (see https://kubernetes.io/docs/concepts/containers/images/#updating-images) imagePullPolicy: IfNotPresent @@ -140,6 +171,7 @@ components: annotations: {} # Distributor port port: 5553 + nodePort: 30553 # Resources for Distributor container resources: {} # SecurityContext for Distributor container @@ -161,7 +193,7 @@ components: # Event Bus image name imageName: event-bus # Event Bus image tag (this overwrites global.seleniumGrid.imageTag parameter) - # imageTag: 4.16.0-20231206 + # imageTag: 4.16.1-20231219 # Image pull policy (see https://kubernetes.io/docs/concepts/containers/images/#updating-images) imagePullPolicy: IfNotPresent @@ -172,10 +204,13 @@ components: annotations: {} # Event Bus port port: 5557 + nodePort: 30557 # Port where events are published publishPort: 4442 + publishNodePort: 30442 # Port where to subscribe for events subscribePort: 4443 + subscribeNodePort: 30443 # Resources for event-bus container resources: {} # SecurityContext for event-bus container @@ -197,7 +232,7 @@ components: # Session Map image name imageName: sessions # Session Map image tag (this overwrites global.seleniumGrid.imageTag parameter) - # imageTag: 4.16.0-20231206 + # imageTag: 4.16.1-20231219 # Image pull policy (see https://kubernetes.io/docs/concepts/containers/images/#updating-images) imagePullPolicy: IfNotPresent @@ -228,7 +263,7 @@ components: # Session Queue image name imageName: session-queue # Session Queue image tag (this overwrites global.seleniumGrid.imageTag parameter) - # imageTag: 4.16.0-20231206 + # imageTag: 4.16.1-20231219 # Image pull policy (see https://kubernetes.io/docs/concepts/containers/images/#updating-images) imagePullPolicy: IfNotPresent @@ -238,6 +273,7 @@ components: # Custom annotations for Session Queue pods annotations: {} port: 5559 + nodePort: 30559 # Resources for Session Queue container resources: {} # SecurityContext for Session Queue container @@ -254,7 +290,7 @@ components: priorityClassName: "" # Custom sub path for all components - subPath: / + subPath: "" # Custom environment variables for all components extraEnvironmentVariables: @@ -279,7 +315,7 @@ hub: # Selenium Hub image name imageName: hub # Selenium Hub image tag (this overwrites global.seleniumGrid.imageTag parameter) - # imageTag: 4.16.0-20231206 + # imageTag: 4.16.1-20231219 # Image pull policy (see https://kubernetes.io/docs/concepts/containers/images/#updating-images) imagePullPolicy: IfNotPresent # Image pull secret (see https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) @@ -291,15 +327,18 @@ hub: labels: {} # Port where events are published publishPort: 4442 + publishNodePort: 31442 # Port where to subscribe for events subscribePort: 4443 + subscribeNodePort: 31443 # Selenium Hub port port: 4444 - # Liveness probe settings - livenessProbe: + nodePort: 31444 + # Wait for pod startup + startupProbe: enabled: true path: /readyz - initialDelaySeconds: 10 + initialDelaySeconds: 5 failureThreshold: 10 timeoutSeconds: 10 periodSeconds: 10 @@ -313,8 +352,17 @@ hub: timeoutSeconds: 10 periodSeconds: 10 successThreshold: 1 + # Liveness probe settings + livenessProbe: + enabled: true + path: /readyz + initialDelaySeconds: 10 + failureThreshold: 10 + timeoutSeconds: 10 + periodSeconds: 10 + successThreshold: 1 # Custom sub path for the hub deployment - subPath: / + subPath: "" # Custom environment variables for selenium-hub extraEnvironmentVariables: # - name: SE_JAVA_OPTS @@ -379,7 +427,8 @@ autoscaling: # see https://keda.sh/docs/latest/concepts/scaling-jobs/#scaledjob-spec scaledJobOptions: scalingStrategy: - strategy: accurate + # Change this to "accurate" when the calculation problem is fixed + strategy: default # Number of Completed jobs should be kept successfulJobsHistoryLimit: 0 # Number of Failed jobs should be kept (for troubleshooting purposes) @@ -393,15 +442,13 @@ autoscaling: scaledObjectOptions: scaleTargetRef: kind: Deployment + # Define terminationGracePeriodSeconds for scalingType "deployment". Period for `deregisterLifecycle` to gracefully shut down the node before force killing it + terminationGracePeriodSeconds: 3600 + # Define preStop command to shuts down the node gracefully when scalingType is set to "deployment" deregisterLifecycle: - preStop: - exec: - command: - - bash - - -c - - | - curl -X POST 127.0.0.1:5555/se/grid/node/drain --header 'X-REGISTRATION-SECRET;' && \ - while curl 127.0.0.1:5555/status; do sleep 1; done; + # preStop: + # exec: + # command: [ "bash", "-c", "/opt/selenium/nodePreStop.sh" ] # Configuration for chrome nodes chromeNode: @@ -420,19 +467,19 @@ chromeNode: # Image of chrome nodes imageName: node-chrome # Image of chrome nodes (this overwrites global.seleniumGrid.nodesImageTag) - # imageTag: 4.16.0-20231206 + # imageTag: 4.16.1-20231219 # Image pull policy (see https://kubernetes.io/docs/concepts/containers/images/#updating-images) imagePullPolicy: IfNotPresent # Image pull secret (see https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) imagePullSecret: "" - # Port list to enable on container - ports: - - 5555 - # Selenium port (spec.ports[0].targetPort in kubernetes service) - seleniumPort: 5900 - # Selenium port exposed in service (spec.ports[0].port in kubernetes service) - seleniumServicePort: 6900 + # Extra ports list to enable on the node container (e.g. SSH, VNC, NoVNC, etc.) + ports: [] + # - 5900 + # - 7900 + # Node component port + port: 5555 + nodePort: # Annotations for chrome-node pods annotations: {} # Labels for chrome-node pods @@ -485,9 +532,9 @@ chromeNode: loadBalancerIP: "" # Extra ports exposed in node service ports: - # - name: node-port - # port: 5555 - # targetPort: 5555 + # - name: vnc-port + # port: 5900 + # targetPort: 5900 # Custom annotations for service annotations: {} # Size limit for DSH volume mounted in container (if not set, default is "1Gi") @@ -496,18 +543,40 @@ chromeNode: priorityClassName: "" # Wait for pod startup - startupProbe: {} - # httpGet: - # path: /status - # port: 5555 - # failureThreshold: 120 - # periodSeconds: 5 + startupProbe: + enabled: true + path: /status + initialDelaySeconds: 0 + failureThreshold: 10 + timeoutSeconds: 5 + periodSeconds: 5 + successThreshold: 1 + + # Readiness probe settings + readinessProbe: + enabled: false + path: /status + initialDelaySeconds: 10 + failureThreshold: 10 + timeoutSeconds: 10 + periodSeconds: 10 + successThreshold: 1 # Liveness probe settings - livenessProbe: {} + livenessProbe: + enabled: false + path: /status + initialDelaySeconds: 15 + failureThreshold: 10 + timeoutSeconds: 10 + periodSeconds: 10 + successThreshold: 1 # Time to wait for pod termination terminationGracePeriodSeconds: 30 + # Define preStop command to shuts down the chrome node gracefully. This overwrites autoscaling.deregisterLifecycle + deregisterLifecycle: + # Define postStart and preStop events. This overwrites the defined preStop in deregisterLifecycle if any lifecycle: {} extraVolumeMounts: [] # - name: my-extra-volume @@ -527,8 +596,9 @@ chromeNode: hpa: url: '{{ include "seleniumGrid.graphqlURL" . }}' browserName: chrome + sessionBrowserName: 'chrome' # browserVersion: '91.0' # Optional. Only required when supporting multiple versions of browser in your Selenium Grid. - unsafeSsl: 'true' # Optional + unsafeSsl: '{{ include "seleniumGrid.graphqlURL.unsafeSsl" . }}' # Optional # It is used to add a sidecars proxy in the same pod of the browser node. # It means it will add a new container to the deployment itself. @@ -553,19 +623,19 @@ firefoxNode: # Image of firefox nodes imageName: node-firefox # Image of firefox nodes (this overwrites global.seleniumGrid.nodesImageTag) - # imageTag: 4.16.0-20231206 + # imageTag: 4.16.1-20231219 # Image pull policy (see https://kubernetes.io/docs/concepts/containers/images/#updating-images) imagePullPolicy: IfNotPresent # Image pull secret (see https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) imagePullSecret: "" - # Port list to enable on container - ports: - - 5555 - # Selenium port (spec.ports[0].targetPort in kubernetes service) - seleniumPort: 5900 - # Selenium port exposed in service (spec.ports[0].port in kubernetes service) - seleniumServicePort: 6900 + # Extra ports list to enable on the node container (e.g. SSH, VNC, NoVNC, etc.) + ports: [] + # - 5900 + # - 7900 + # Node component port + port: 5555 + nodePort: # Annotations for firefox-node pods annotations: {} # Labels for firefox-node pods @@ -618,9 +688,9 @@ firefoxNode: loadBalancerIP: "" # Extra ports exposed in node service ports: - # - name: node-port - # port: 5555 - # targetPort: 5555 + # - name: vnc-port + # port: 5900 + # targetPort: 5900 # Custom annotations for service annotations: {} # Size limit for DSH volume mounted in container (if not set, default is "1Gi") @@ -629,18 +699,40 @@ firefoxNode: priorityClassName: "" # Wait for pod startup - startupProbe: {} - # httpGet: - # path: /status - # port: 5555 - # failureThreshold: 120 - # periodSeconds: 5 + startupProbe: + enabled: true + path: /status + initialDelaySeconds: 0 + failureThreshold: 10 + timeoutSeconds: 5 + periodSeconds: 5 + successThreshold: 1 + + # Readiness probe settings + readinessProbe: + enabled: false + path: /status + initialDelaySeconds: 10 + failureThreshold: 10 + timeoutSeconds: 10 + periodSeconds: 10 + successThreshold: 1 # Liveness probe settings - livenessProbe: {} + livenessProbe: + enabled: false + path: /status + initialDelaySeconds: 15 + failureThreshold: 10 + timeoutSeconds: 10 + periodSeconds: 10 + successThreshold: 1 # Time to wait for pod termination terminationGracePeriodSeconds: 30 + # Define preStop command to shuts down the chrome node gracefully. This overwrites autoscaling.deregisterLifecycle + deregisterLifecycle: + # Define postStart and preStop events. This overwrites the defined preStop in deregisterLifecycle if any lifecycle: {} extraVolumeMounts: [] # - name: my-extra-volume @@ -660,6 +752,8 @@ firefoxNode: hpa: url: '{{ include "seleniumGrid.graphqlURL" . }}' browserName: firefox + sessionBrowserName: 'firefox' + unsafeSsl: '{{ include "seleniumGrid.graphqlURL.unsafeSsl" . }}' # Optional # It is used to add a sidecars proxy in the same pod of the browser node. # It means it will add a new container to the deployment itself. @@ -683,18 +777,19 @@ edgeNode: # Image of edge nodes imageName: node-edge # Image of edge nodes (this overwrites global.seleniumGrid.nodesImageTag) - # imageTag: 4.16.0-20231206 + # imageTag: 4.16.1-20231219 # Image pull policy (see https://kubernetes.io/docs/concepts/containers/images/#updating-images) imagePullPolicy: IfNotPresent # Image pull secret (see https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) imagePullSecret: "" - ports: - - 5555 - # Selenium port (spec.ports[0].targetPort in kubernetes service) - seleniumPort: 5900 - # Selenium port exposed in service (spec.ports[0].port in kubernetes service) - seleniumServicePort: 6900 + # Extra ports list to enable on the node container (e.g. SSH, VNC, NoVNC, etc.) + ports: [] + # - 5900 + # - 7900 + # Node component port + port: 5555 + nodePort: # Annotations for edge-node pods annotations: {} # Labels for edge-node pods @@ -747,9 +842,9 @@ edgeNode: loadBalancerIP: "" # Extra ports exposed in node service ports: - # - name: node-port - # port: 5555 - # targetPort: 5555 + # - name: vnc-port + # port: 5900 + # targetPort: 5900 # Custom annotations for service annotations: {} # Size limit for DSH volume mounted in container (if not set, default is "1Gi") @@ -758,18 +853,40 @@ edgeNode: priorityClassName: "" # Wait for pod startup - startupProbe: {} - # httpGet: - # path: /status - # port: 5555 - # failureThreshold: 120 - # periodSeconds: 5 + startupProbe: + enabled: true + path: /status + initialDelaySeconds: 0 + failureThreshold: 10 + timeoutSeconds: 5 + periodSeconds: 5 + successThreshold: 1 + + # Readiness probe settings + readinessProbe: + enabled: false + path: /status + initialDelaySeconds: 10 + failureThreshold: 10 + timeoutSeconds: 10 + periodSeconds: 10 + successThreshold: 1 # Liveness probe settings - livenessProbe: {} + livenessProbe: + enabled: false + path: /status + initialDelaySeconds: 15 + failureThreshold: 10 + timeoutSeconds: 10 + periodSeconds: 10 + successThreshold: 1 # Time to wait for pod termination terminationGracePeriodSeconds: 30 + # Define preStop command to shuts down the chrome node gracefully. This overwrites autoscaling.deregisterLifecycle + deregisterLifecycle: + # Define postStart and preStop events. This overwrites the defined preStop in deregisterLifecycle if any lifecycle: {} extraVolumeMounts: [] # - name: my-extra-volume @@ -790,6 +907,7 @@ edgeNode: url: '{{ include "seleniumGrid.graphqlURL" . }}' browserName: MicrosoftEdge sessionBrowserName: 'msedge' + unsafeSsl: '{{ include "seleniumGrid.graphqlURL.unsafeSsl" . }}' # Optional # It is used to add a sidecars proxy in the same pod of the browser node. # It means it will add a new container to the deployment itself. @@ -802,7 +920,7 @@ videoRecorder: # Image of video recorder imageName: video # Image of video recorder - # imageTag: ffmpeg-6.1-20231206 + # imageTag: ffmpeg-6.1-20231219 # Image pull policy (see https://kubernetes.io/docs/concepts/containers/images/#updating-images) imagePullPolicy: IfNotPresent # Image pull secret (see https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) @@ -910,3 +1028,17 @@ videoRecorder: # Custom labels for k8s resources customLabels: {} + +# Configuration for dependency chart keda +keda: + http: + timeout: 60000 + webhooks: + enabled: false + +# Configuration for dependency chart ingress-nginx +ingress-nginx: + enabled: false + controller: + admissionWebhooks: + enabled: false diff --git a/docker-compose-v2-tracing.yml b/docker-compose-v2-tracing.yml index fe06e3880b..fc5469aa47 100644 --- a/docker-compose-v2-tracing.yml +++ b/docker-compose-v2-tracing.yml @@ -9,7 +9,7 @@ services: - "16686:16686" - "14250:14250" chrome: - image: selenium/node-chrome:4.16.0-20231206 + image: selenium/node-chrome:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -23,7 +23,7 @@ services: - "6900:5900" edge: - image: selenium/node-edge:4.16.0-20231206 + image: selenium/node-edge:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -37,7 +37,7 @@ services: - "6901:5900" firefox: - image: selenium/node-firefox:4.16.0-20231206 + image: selenium/node-firefox:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -51,7 +51,7 @@ services: - "6902:5900" selenium-hub: - image: selenium/hub:4.16.0-20231206 + image: selenium/hub:4.16.1-20231219 ports: - "4442:4442" - "4443:4443" diff --git a/docker-compose-v2.yml b/docker-compose-v2.yml index 7e2d9ecbfc..c0b92ae28d 100644 --- a/docker-compose-v2.yml +++ b/docker-compose-v2.yml @@ -4,7 +4,7 @@ version: '2' services: chrome: - image: selenium/node-chrome:4.16.0-20231206 + image: selenium/node-chrome:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -16,7 +16,7 @@ services: - "6900:5900" edge: - image: selenium/node-edge:4.16.0-20231206 + image: selenium/node-edge:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -28,7 +28,7 @@ services: - "6901:5900" firefox: - image: selenium/node-firefox:4.16.0-20231206 + image: selenium/node-firefox:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -40,7 +40,7 @@ services: - "6902:5900" selenium-hub: - image: selenium/hub:4.16.0-20231206 + image: selenium/hub:4.16.1-20231219 ports: - "4442:4442" - "4443:4443" diff --git a/docker-compose-v3-basicauth.yml b/docker-compose-v3-basicauth.yml index bed795e212..05b1e2f554 100644 --- a/docker-compose-v3-basicauth.yml +++ b/docker-compose-v3-basicauth.yml @@ -4,7 +4,7 @@ version: "3" services: chrome: - image: selenium/node-chrome:4.16.0-20231206 + image: selenium/node-chrome:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -14,7 +14,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 edge: - image: selenium/node-edge:4.16.0-20231206 + image: selenium/node-edge:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -24,7 +24,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 firefox: - image: selenium/node-firefox:4.16.0-20231206 + image: selenium/node-firefox:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -34,7 +34,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 selenium-hub: - image: selenium/hub:4.16.0-20231206 + image: selenium/hub:4.16.1-20231219 container_name: selenium-hub ports: - "4442:4442" diff --git a/docker-compose-v3-dev.yml b/docker-compose-v3-dev.yml index 029f4311ee..2a638496af 100644 --- a/docker-compose-v3-dev.yml +++ b/docker-compose-v3-dev.yml @@ -4,7 +4,7 @@ version: "3" services: chrome: - image: selenium/node-chrome:4.16.0-20231206 + image: selenium/node-chrome:4.16.1-20231219 shm_size: 2gb volumes: - ./selenium_server_deploy.jar:/opt/selenium/selenium-server.jar @@ -16,7 +16,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 edge: - image: selenium/node-edge:4.16.0-20231206 + image: selenium/node-edge:4.16.1-20231219 shm_size: 2gb volumes: - ./selenium_server_deploy.jar:/opt/selenium/selenium-server.jar @@ -28,7 +28,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 firefox: - image: selenium/node-firefox:4.16.0-20231206 + image: selenium/node-firefox:4.16.1-20231219 shm_size: 2gb volumes: - ./selenium_server_deploy.jar:/opt/selenium/selenium-server.jar @@ -40,7 +40,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 selenium-hub: - image: selenium/hub:4.16.0-20231206 + image: selenium/hub:4.16.1-20231219 container_name: selenium-hub volumes: - ./selenium_server_deploy.jar:/opt/selenium/selenium-server.jar diff --git a/docker-compose-v3-dynamic-grid.yml b/docker-compose-v3-dynamic-grid.yml index 6655e11661..83f6185c15 100644 --- a/docker-compose-v3-dynamic-grid.yml +++ b/docker-compose-v3-dynamic-grid.yml @@ -4,7 +4,7 @@ version: "3" services: node-docker: - image: selenium/node-docker:4.16.0-20231206 + image: selenium/node-docker:4.16.1-20231219 volumes: - ./assets:/opt/selenium/assets - ./NodeDocker/config.toml:/opt/bin/config.toml @@ -17,7 +17,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 selenium-hub: - image: selenium/hub:4.16.0-20231206 + image: selenium/hub:4.16.1-20231219 container_name: selenium-hub ports: - "4442:4442" diff --git a/docker-compose-v3-full-grid-dev.yml b/docker-compose-v3-full-grid-dev.yml index d7ceddceb7..4f4d131b68 100644 --- a/docker-compose-v3-full-grid-dev.yml +++ b/docker-compose-v3-full-grid-dev.yml @@ -4,7 +4,7 @@ version: "3" services: selenium-event-bus: - image: selenium/event-bus:4.16.0-20231206 + image: selenium/event-bus:4.16.1-20231219 volumes: - ./selenium_server_deploy.jar:/opt/selenium/selenium-server.jar container_name: selenium-event-bus @@ -14,7 +14,7 @@ services: - "5557:5557" selenium-sessions: - image: selenium/sessions:4.16.0-20231206 + image: selenium/sessions:4.16.1-20231219 volumes: - ./selenium_server_deploy.jar:/opt/selenium/selenium-server.jar container_name: selenium-sessions @@ -28,7 +28,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 selenium-session-queue: - image: selenium/session-queue:4.16.0-20231206 + image: selenium/session-queue:4.16.1-20231219 volumes: - ./selenium_server_deploy.jar:/opt/selenium/selenium-server.jar container_name: selenium-session-queue @@ -36,7 +36,7 @@ services: - "5559:5559" selenium-distributor: - image: selenium/distributor:4.16.0-20231206 + image: selenium/distributor:4.16.1-20231219 volumes: - ./selenium_server_deploy.jar:/opt/selenium/selenium-server.jar container_name: selenium-distributor @@ -56,7 +56,7 @@ services: - SE_SESSION_QUEUE_PORT=5559 selenium-router: - image: selenium/router:4.16.0-20231206 + image: selenium/router:4.16.1-20231219 volumes: - ./selenium_server_deploy.jar:/opt/selenium/selenium-server.jar container_name: selenium-router @@ -75,7 +75,7 @@ services: - SE_SESSION_QUEUE_PORT=5559 chrome: - image: selenium/node-chrome:4.16.0-20231206 + image: selenium/node-chrome:4.16.1-20231219 shm_size: 2gb volumes: - ./selenium_server_deploy.jar:/opt/selenium/selenium-server.jar @@ -87,7 +87,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 edge: - image: selenium/node-edge:4.16.0-20231206 + image: selenium/node-edge:4.16.1-20231219 shm_size: 2gb volumes: - ./selenium_server_deploy.jar:/opt/selenium/selenium-server.jar @@ -99,7 +99,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 firefox: - image: selenium/node-firefox:4.16.0-20231206 + image: selenium/node-firefox:4.16.1-20231219 shm_size: 2gb volumes: - ./selenium_server_deploy.jar:/opt/selenium/selenium-server.jar diff --git a/docker-compose-v3-full-grid-swarm.yml b/docker-compose-v3-full-grid-swarm.yml index 08175c05eb..636efd51b8 100644 --- a/docker-compose-v3-full-grid-swarm.yml +++ b/docker-compose-v3-full-grid-swarm.yml @@ -7,7 +7,7 @@ version: '3.7' services: chrome: - image: selenium/node-chrome:4.16.0-20231206 + image: selenium/node-chrome:4.16.1-20231219 shm_size: 2gb environment: - SE_EVENT_BUS_HOST=selenium-hub @@ -18,7 +18,7 @@ services: entrypoint: bash -c 'SE_OPTS="--host $$HOSTNAME" /opt/bin/entry_point.sh' edge: - image: selenium/node-edge:4.16.0-20231206 + image: selenium/node-edge:4.16.1-20231219 shm_size: 2gb environment: - SE_EVENT_BUS_HOST=selenium-hub @@ -29,7 +29,7 @@ services: entrypoint: bash -c 'SE_OPTS="--host $$HOSTNAME" /opt/bin/entry_point.sh' firefox: - image: selenium/node-firefox:4.16.0-20231206 + image: selenium/node-firefox:4.16.1-20231219 shm_size: 2gb environment: - SE_EVENT_BUS_HOST=selenium-hub @@ -40,7 +40,7 @@ services: entrypoint: bash -c 'SE_OPTS="--host $$HOSTNAME" /opt/bin/entry_point.sh' selenium-hub: - image: selenium/hub:4.16.0-20231206 + image: selenium/hub:4.16.1-20231219 ports: - "4442:4442" - "4443:4443" diff --git a/docker-compose-v3-full-grid-tracing.yml b/docker-compose-v3-full-grid-tracing.yml index 9596c563f1..781357aa49 100644 --- a/docker-compose-v3-full-grid-tracing.yml +++ b/docker-compose-v3-full-grid-tracing.yml @@ -9,7 +9,7 @@ services: - "16686:16686" - "14250:14250" selenium-event-bus: - image: selenium/event-bus:4.16.0-20231206 + image: selenium/event-bus:4.16.1-20231219 container_name: selenium-event-bus ports: - "4442:4442" @@ -21,7 +21,7 @@ services: - SE_ENABLE_TRACING=true - JAVA_OPTS=-Dotel.traces.exporter=jaeger -Dotel.exporter.jaeger.endpoint=http://jaegar:14250 -Dotel.resource.attributes=service.name=selenium-event-bus selenium-sessions: - image: selenium/sessions:4.16.0-20231206 + image: selenium/sessions:4.16.1-20231219 container_name: selenium-sessions ports: - "5556:5556" @@ -34,7 +34,7 @@ services: - SE_ENABLE_TRACING=true - JAVA_OPTS=-Dotel.traces.exporter=jaeger -Dotel.exporter.jaeger.endpoint=http://jaegar:14250 -Dotel.resource.attributes=service.name=selenium-sessions selenium-session-queue: - image: selenium/session-queue:4.16.0-20231206 + image: selenium/session-queue:4.16.1-20231219 container_name: selenium-session-queue ports: - "5559:5559" @@ -42,7 +42,7 @@ services: - SE_ENABLE_TRACING=true - JAVA_OPTS=-Dotel.traces.exporter=jaeger -Dotel.exporter.jaeger.endpoint=http://jaegar:14250 -Dotel.resource.attributes=service.name=selenium-session-queue selenium-distributor: - image: selenium/distributor:4.16.0-20231206 + image: selenium/distributor:4.16.1-20231219 container_name: selenium-distributor ports: - "5553:5553" @@ -61,7 +61,7 @@ services: - SE_ENABLE_TRACING=true - JAVA_OPTS=-Dotel.traces.exporter=jaeger -Dotel.exporter.jaeger.endpoint=http://jaegar:14250 -Dotel.resource.attributes=service.name=selenium-distributor selenium-router: - image: selenium/router:4.16.0-20231206 + image: selenium/router:4.16.1-20231219 container_name: selenium-router ports: - "4444:4444" @@ -79,7 +79,7 @@ services: - SE_ENABLE_TRACING=true - JAVA_OPTS=-Dotel.traces.exporter=jaeger -Dotel.exporter.jaeger.endpoint=http://jaegar:14250 -Dotel.resource.attributes=service.name=selenium-router chrome: - image: selenium/node-chrome:4.16.0-20231206 + image: selenium/node-chrome:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-event-bus @@ -90,7 +90,7 @@ services: - SE_ENABLE_TRACING=true - JAVA_OPTS=-Dotel.traces.exporter=jaeger -Dotel.exporter.jaeger.endpoint=http://jaegar:14250 -Dotel.resource.attributes=service.name=selenium-node-chrome edge: - image: selenium/node-edge:4.16.0-20231206 + image: selenium/node-edge:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-event-bus @@ -101,7 +101,7 @@ services: - SE_ENABLE_TRACING=true - JAVA_OPTS=-Dotel.traces.exporter=jaeger -Dotel.exporter.jaeger.endpoint=http://jaegar:14250 -Dotel.resource.attributes=service.name=selenium-node-edge firefox: - image: selenium/node-firefox:4.16.0-20231206 + image: selenium/node-firefox:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-event-bus diff --git a/docker-compose-v3-full-grid.yml b/docker-compose-v3-full-grid.yml index 6c3a08a1ca..af9266fefc 100644 --- a/docker-compose-v3-full-grid.yml +++ b/docker-compose-v3-full-grid.yml @@ -4,7 +4,7 @@ version: "3" services: selenium-event-bus: - image: selenium/event-bus:4.16.0-20231206 + image: selenium/event-bus:4.16.1-20231219 container_name: selenium-event-bus ports: - "4442:4442" @@ -12,7 +12,7 @@ services: - "5557:5557" selenium-sessions: - image: selenium/sessions:4.16.0-20231206 + image: selenium/sessions:4.16.1-20231219 container_name: selenium-sessions ports: - "5556:5556" @@ -24,13 +24,13 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 selenium-session-queue: - image: selenium/session-queue:4.16.0-20231206 + image: selenium/session-queue:4.16.1-20231219 container_name: selenium-session-queue ports: - "5559:5559" selenium-distributor: - image: selenium/distributor:4.16.0-20231206 + image: selenium/distributor:4.16.1-20231219 container_name: selenium-distributor ports: - "5553:5553" @@ -48,7 +48,7 @@ services: - SE_SESSION_QUEUE_PORT=5559 selenium-router: - image: selenium/router:4.16.0-20231206 + image: selenium/router:4.16.1-20231219 container_name: selenium-router ports: - "4444:4444" @@ -65,7 +65,7 @@ services: - SE_SESSION_QUEUE_PORT=5559 chrome: - image: selenium/node-chrome:4.16.0-20231206 + image: selenium/node-chrome:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-event-bus @@ -75,7 +75,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 edge: - image: selenium/node-edge:4.16.0-20231206 + image: selenium/node-edge:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-event-bus @@ -85,7 +85,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 firefox: - image: selenium/node-firefox:4.16.0-20231206 + image: selenium/node-firefox:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-event-bus diff --git a/docker-compose-v3-swarm.yml b/docker-compose-v3-swarm.yml index 08175c05eb..636efd51b8 100644 --- a/docker-compose-v3-swarm.yml +++ b/docker-compose-v3-swarm.yml @@ -7,7 +7,7 @@ version: '3.7' services: chrome: - image: selenium/node-chrome:4.16.0-20231206 + image: selenium/node-chrome:4.16.1-20231219 shm_size: 2gb environment: - SE_EVENT_BUS_HOST=selenium-hub @@ -18,7 +18,7 @@ services: entrypoint: bash -c 'SE_OPTS="--host $$HOSTNAME" /opt/bin/entry_point.sh' edge: - image: selenium/node-edge:4.16.0-20231206 + image: selenium/node-edge:4.16.1-20231219 shm_size: 2gb environment: - SE_EVENT_BUS_HOST=selenium-hub @@ -29,7 +29,7 @@ services: entrypoint: bash -c 'SE_OPTS="--host $$HOSTNAME" /opt/bin/entry_point.sh' firefox: - image: selenium/node-firefox:4.16.0-20231206 + image: selenium/node-firefox:4.16.1-20231219 shm_size: 2gb environment: - SE_EVENT_BUS_HOST=selenium-hub @@ -40,7 +40,7 @@ services: entrypoint: bash -c 'SE_OPTS="--host $$HOSTNAME" /opt/bin/entry_point.sh' selenium-hub: - image: selenium/hub:4.16.0-20231206 + image: selenium/hub:4.16.1-20231219 ports: - "4442:4442" - "4443:4443" diff --git a/docker-compose-v3-tracing.yml b/docker-compose-v3-tracing.yml index 1f81cc6b9a..a8c012ec3c 100644 --- a/docker-compose-v3-tracing.yml +++ b/docker-compose-v3-tracing.yml @@ -9,7 +9,7 @@ services: - "16686:16686" - "14250:14250" chrome: - image: selenium/node-chrome:4.16.0-20231206 + image: selenium/node-chrome:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -21,7 +21,7 @@ services: - JAVA_OPTS=-Dotel.traces.exporter=jaeger -Dotel.exporter.jaeger.endpoint=http://jaegar:14250 -Dotel.resource.attributes=service.name=selenium-node-chrome edge: - image: selenium/node-edge:4.16.0-20231206 + image: selenium/node-edge:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -33,7 +33,7 @@ services: - JAVA_OPTS=-Dotel.traces.exporter=jaeger -Dotel.exporter.jaeger.endpoint=http://jaegar:14250 -Dotel.resource.attributes=service.name=selenium-node-edge firefox: - image: selenium/node-firefox:4.16.0-20231206 + image: selenium/node-firefox:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -45,7 +45,7 @@ services: - JAVA_OPTS=-Dotel.traces.exporter=jaeger -Dotel.exporter.jaeger.endpoint=http://jaegar:14250 -Dotel.resource.attributes=service.name=selenium-node-firefox selenium-hub: - image: selenium/hub:4.16.0-20231206 + image: selenium/hub:4.16.1-20231219 container_name: selenium-hub ports: - "4442:4442" diff --git a/docker-compose-v3-video.yml b/docker-compose-v3-video.yml index 9ae22f29b0..484e55806b 100644 --- a/docker-compose-v3-video.yml +++ b/docker-compose-v3-video.yml @@ -4,7 +4,7 @@ version: "3" services: chrome: - image: selenium/node-chrome:4.16.0-20231206 + image: selenium/node-chrome:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -14,7 +14,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 edge: - image: selenium/node-edge:4.16.0-20231206 + image: selenium/node-edge:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -24,7 +24,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 firefox: - image: selenium/node-firefox:4.16.0-20231206 + image: selenium/node-firefox:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -34,7 +34,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 chrome_video: - image: selenium/video:ffmpeg-6.1-20231206 + image: selenium/video:ffmpeg-6.1-20231219 volumes: - /tmp/videos:/videos depends_on: @@ -44,7 +44,7 @@ services: - FILE_NAME=chrome_video.mp4 edge_video: - image: selenium/video:ffmpeg-6.1-20231206 + image: selenium/video:ffmpeg-6.1-20231219 volumes: - /tmp/videos:/videos depends_on: @@ -54,7 +54,7 @@ services: - FILE_NAME=edge_video.mp4 firefox_video: - image: selenium/video:ffmpeg-6.1-20231206 + image: selenium/video:ffmpeg-6.1-20231219 volumes: - /tmp/videos:/videos depends_on: @@ -64,7 +64,7 @@ services: - FILE_NAME=firefox_video.mp4 selenium-hub: - image: selenium/hub:4.16.0-20231206 + image: selenium/hub:4.16.1-20231219 container_name: selenium-hub ports: - "4442:4442" diff --git a/docker-compose-v3.yml b/docker-compose-v3.yml index e24d65ad84..e863abebf5 100644 --- a/docker-compose-v3.yml +++ b/docker-compose-v3.yml @@ -4,7 +4,7 @@ version: "3" services: chrome: - image: selenium/node-chrome:4.16.0-20231206 + image: selenium/node-chrome:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -14,7 +14,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 edge: - image: selenium/node-edge:4.16.0-20231206 + image: selenium/node-edge:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -24,7 +24,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 firefox: - image: selenium/node-firefox:4.16.0-20231206 + image: selenium/node-firefox:4.16.1-20231219 shm_size: 2gb depends_on: - selenium-hub @@ -34,7 +34,7 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 selenium-hub: - image: selenium/hub:4.16.0-20231206 + image: selenium/hub:4.16.1-20231219 container_name: selenium-hub ports: - "4442:4442" diff --git a/generate_chart_changelog.sh b/generate_chart_changelog.sh new file mode 100755 index 0000000000..4afaedfb6b --- /dev/null +++ b/generate_chart_changelog.sh @@ -0,0 +1,85 @@ +#!/bin/bash + +# Specify the output file for the CHANGELOG +CHART_DIR="./charts/selenium-grid" +CHANGELOG_FILE="./charts/selenium-grid/CHANGELOG.md" +TAG_PATTERN="selenium-grid" + +# Get current chart app version +CHART_APP_VERSION=$(find . \( -type d -name .git -prune \) -o -type f -name 'Chart.yaml' -print0 | xargs -0 cat | grep ^appVersion | cut -d ':' -f 2 | tr -d '[:space:]') + +# Generate the changelog +generate_changelog() { + # Get a list of tags sorted by commit date + tags=($(git tag --sort=committerdate | grep "^$TAG_PATTERN")) + tags_size=${#tags[@]} + + # Check if there are tags + if [ ${#tags[@]} -eq 0 ]; then + commit_range="HEAD" + elif [ ${#tags[@]} -eq 1 ]; then + previous_tag="${tags[$tags_size-1]}" + current_tag="HEAD" + commit_range="${previous_tag}..${current_tag}" + else + previous_tag="${tags[$tags_size-2]}" + current_tag="${tags[$tags_size-1]}" + commit_range="${previous_tag}..${current_tag}" + fi + + # Get the changes for each section (Added, Removed, Fixed, Changed) + image_tag_changes=$(echo "Chart is using image tag $CHART_APP_VERSION" | sed -e 's/^/- /') + added_changes=$(git log --pretty=format:"%s :: %an" "$commit_range" -- "$CHART_DIR" | grep -iE "^feat|^add" | sed -e 's/^/- /') + removed_changes=$(git log --pretty=format:"%s :: %an" "$commit_range" -- "$CHART_DIR" | grep -iE "^remove|^deprecate|^delete" | sed -e 's/^/- /') + fixed_changes=$(git log --pretty=format:"%s :: %an" "$commit_range" -- "$CHART_DIR" | grep -iE "^fix|^bug" | sed -e 's/^/- /') + changed_changes=$(git log --pretty=format:"%s :: %an" "$commit_range" -- "$CHART_DIR" | grep -iEv "^feat|^add|^remove|^deprecate|^delete|^fix|^bug" | sed -e 's/^/- /') + + if [[ $(cat $CHANGELOG_FILE) == *"${current_tag}"* ]]; then + echo "Changelog already generated for ${current_tag}" + exit 0 + fi + + # Create a temporary file + temp_file=$(mktemp) + + # Write to the temporary file + echo "## :heavy_check_mark: ${current_tag}" >> "$temp_file" + echo "" >> "$temp_file" + echo "$image_tag_changes" >> "$temp_file" + echo "" >> "$temp_file" + + if [ -n "$added_changes" ]; then + echo "### Added" >> "$temp_file" + echo "$added_changes" >> "$temp_file" + echo "" >> "$temp_file" + fi + + if [ -n "$removed_changes" ]; then + echo "### Removed" >> "$temp_file" + echo "$removed_changes" >> "$temp_file" + echo "" >> "$temp_file" + fi + + if [ -n "$fixed_changes" ]; then + echo "### Fixed" >> "$temp_file" + echo "$fixed_changes" >> "$temp_file" + echo "" >> "$temp_file" + fi + + if [ -n "$changed_changes" ]; then + echo "### Changed" >> "$temp_file" + echo "$changed_changes" >> "$temp_file" + echo "" >> "$temp_file" + fi + + # Append the existing content of CHANGELOG to the temporary file + cat "$CHANGELOG_FILE" >> "$temp_file" + + # Overwrite CHANGELOG with the content of the temporary file + mv "$temp_file" "$CHANGELOG_FILE" +} + +# Run the function to generate the changelog +generate_changelog + +echo "Changelog generated successfully at $CHANGELOG_FILE" diff --git a/tests/SeleniumTests/__init__.py b/tests/SeleniumTests/__init__.py index 8d5927ad30..9f28da99d4 100644 --- a/tests/SeleniumTests/__init__.py +++ b/tests/SeleniumTests/__init__.py @@ -67,18 +67,34 @@ def test_play_video(self): def test_download_file(self): driver = self.driver - driver.get('https://demoqa.com/upload-download') - file_name = 'sampleFile.jpeg' - wait = WebDriverWait(driver, 30) - file_link = wait.until( - EC.element_to_be_clickable((By.XPATH, f'//*[@download="{file_name}"]')) - ) - file_link.click() - wait.until( - lambda d: len(d.get_downloadable_files()) > 0 and str(d.get_downloadable_files()[0]).endswith(file_name) - ) - time.sleep(5) - self.assertTrue(str(driver.get_downloadable_files()[0]).endswith(file_name)) + # driver.get('https://demoqa.com/upload-download') + # file_name = 'sampleFile.jpeg' + # wait = WebDriverWait(driver, 30) + # file_link = wait.until( + # EC.element_to_be_clickable((By.XPATH, f'//*[@download="{file_name}"]')) + # ) + # file_link.click() + # wait.until( + # lambda d: len(d.get_downloadable_files()) > 0 and str(d.get_downloadable_files()[0]).endswith(file_name) + # ) + # time.sleep(5) + # self.assertTrue(str(driver.get_downloadable_files()[0]).endswith(file_name)) + driver.get('https://the-internet.herokuapp.com/download') + file_name = 'some-file.txt' + is_continue = True + try: + wait = WebDriverWait(driver, 30) + file_link = wait.until( + EC.element_to_be_clickable((By.LINK_TEXT, file_name)) + ) + except: + is_continue = False + if is_continue: + file_link.click() + wait.until( + lambda d: str(d.get_downloadable_files()[0]).endswith(file_name) + ) + self.assertTrue(str(driver.get_downloadable_files()[0]).endswith(file_name)) def tearDown(self): self.driver.quit() @@ -88,6 +104,7 @@ class ChromeTests(SeleniumGenericTests): def setUp(self): options = ChromeOptions() options.enable_downloads = True + options.add_argument('disable-features=DownloadBubble,DownloadBubbleV2') self.driver = webdriver.Remote( options=options, command_executor="http://%s:%s" % (SELENIUM_GRID_HOST,SELENIUM_GRID_PORT) @@ -97,6 +114,7 @@ class EdgeTests(SeleniumGenericTests): def setUp(self): options = EdgeOptions() options.enable_downloads = True + options.add_argument('disable-features=DownloadBubble,DownloadBubbleV2') self.driver = webdriver.Remote( options=options, command_executor="http://%s:%s" % (SELENIUM_GRID_HOST,SELENIUM_GRID_PORT) @@ -105,7 +123,11 @@ def setUp(self): class FirefoxTests(SeleniumGenericTests): def setUp(self): + profile = webdriver.FirefoxProfile() + profile.set_preference("browser.download.manager.showWhenStarting", False) + profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "*/*") options = FirefoxOptions() + options.profile = profile options.enable_downloads = True self.driver = webdriver.Remote( options=options, @@ -117,7 +139,7 @@ def test_title_and_maximize_window(self): self.driver.maximize_window() self.assertTrue(self.driver.title == 'The Internet') -class ParallelAutoscaling(): +class JobAutoscaling(): def run(self, test_classes): with concurrent.futures.ThreadPoolExecutor() as executor: futures = [] @@ -128,7 +150,7 @@ def run(self, test_classes): for future in concurrent.futures.as_completed(futures): future.result() -class ParallelAutoscalingTests(unittest.TestCase): +class JobAutoscalingTests(unittest.TestCase): def test_parallel_autoscaling(self): - runner = ParallelAutoscaling() + runner = JobAutoscaling() runner.run([ChromeTests, EdgeTests, FirefoxTests]) diff --git a/tests/charts/bootstrap.sh b/tests/charts/bootstrap.sh index d961b63ae7..f1ade17d19 100755 --- a/tests/charts/bootstrap.sh +++ b/tests/charts/bootstrap.sh @@ -13,9 +13,9 @@ python -m pip install pyyaml==6.0.1 \ cd .. helm template dummy --values tests/charts/templates/render/dummy.yaml \ - charts/selenium-grid > ./tests/tests/output_deployment.yaml + charts/selenium-grid > ./tests/tests/dummy_template_manifests.yaml -python tests/charts/templates/test.py "./tests/tests/output_deployment.yaml" +python tests/charts/templates/test.py "./tests/tests/dummy_template_manifests.yaml" ret_code=$? if [ "${CI:-false}" = "false" ]; then diff --git a/tests/charts/ci/DeploymentAutoScaling-values.yaml b/tests/charts/ci/DeploymentAutoScaling-values.yaml new file mode 100644 index 0000000000..b9e5b120ee --- /dev/null +++ b/tests/charts/ci/DeploymentAutoScaling-values.yaml @@ -0,0 +1,72 @@ +autoscaling: + enableWithExistingKEDA: true + scalingType: deployment + scaledOptions: + minReplicaCount: 0 + maxReplicaCount: 3 + scaledObjectOptions: + cooldownPeriod: 30 + terminationGracePeriodSeconds: 360 +# Configuration for chrome nodes +chromeNode: + # (test): user is able to change `SE_NODE_PORT` + port: 6666 + # (test): user is able to set NodePort to expose `SE_NODE_PORT` + nodePort: 30666 + # (test): user is able to define list extra container ports + ports: + - 5900 + - 7900 + service: + type: NodePort + # (test): user is able to define extra ports for Node service + ports: + - name: vnc-port + protocol: TCP + port: 5900 + targetPort: 5900 + nodePort: 30590 + - name: novnc-port + protocol: TCP + port: 7900 + targetPort: 7900 + # NodePort will be assigned randomly if not set + nameOverride: my-chrome-name + extraEnvironmentVariables: &extraEnvironmentVariables + - name: SE_OPTS + value: "--enable-managed-downloads true" + - name: SE_DRAIN_AFTER_SESSION_COUNT + value: "0" + readinessProbe: + enabled: &readinessProbe true + livenessProbe: + enabled: &livenessProbe true +# Configuration for edge nodes +edgeNode: + # (test): user is able to define extra container ports + ports: + - containerPort: 5900 + name: vnc + protocol: TCP + - containerPort: 7900 + name: novnc + protocol: TCP + nameOverride: my-edge-name + extraEnvironmentVariables: *extraEnvironmentVariables + # (test): user is able to override probe method + startupProbe: + enabled: true + tcpSocket: + port: 8888 + readinessProbe: + enabled: *readinessProbe + livenessProbe: + enabled: *livenessProbe +# Configuration for firefox nodes +firefoxNode: + nameOverride: my-firefox-name + extraEnvironmentVariables: *extraEnvironmentVariables + readinessProbe: + enabled: *readinessProbe + livenessProbe: + enabled: *livenessProbe diff --git a/tests/charts/ci/ParallelAutoscaling-values.yaml b/tests/charts/ci/JobAutoscaling-values.yaml similarity index 67% rename from tests/charts/ci/ParallelAutoscaling-values.yaml rename to tests/charts/ci/JobAutoscaling-values.yaml index 39ea9434c8..d8fc0bc792 100644 --- a/tests/charts/ci/ParallelAutoscaling-values.yaml +++ b/tests/charts/ci/JobAutoscaling-values.yaml @@ -1,26 +1,43 @@ isolateComponents: false + autoscaling: + enableWithExistingKEDA: true + scalingType: job strategy: default scaledOptions: minReplicaCount: 0 maxReplicaCount: 5 + pollingInterval: 20 +# Configuration for chrome nodes chromeNode: nameOverride: my-chrome-name extraEnvironmentVariables: - name: SE_OPTS value: "--enable-managed-downloads true" + readinessProbe: + enabled: &readinessProbe false + livenessProbe: + enabled: &livenessProbe false # Configuration for edge nodes edgeNode: nameOverride: my-edge-name extraEnvironmentVariables: - name: SE_OPTS value: "--enable-managed-downloads true" + readinessProbe: + enabled: *readinessProbe + livenessProbe: + enabled: *livenessProbe # Configuration for firefox nodes firefoxNode: nameOverride: my-firefox-name extraEnvironmentVariables: - name: SE_OPTS value: "--enable-managed-downloads true" + readinessProbe: + enabled: *readinessProbe + livenessProbe: + enabled: *livenessProbe ingress: paths: @@ -31,10 +48,3 @@ ingress: name: '{{ template "seleniumGrid.hub.fullname" $ }}' port: number: 4444 - - path: /(/?)(session/.*/se/vnc) - pathType: ImplementationSpecific - backend: - service: - name: '{{ template "seleniumGrid.hub.fullname" $ }}' - port: - number: 4444 diff --git a/tests/charts/ci/NodeChrome-values.yaml b/tests/charts/ci/NodeChrome-values.yaml index 09396f42d0..d7c9df098b 100644 --- a/tests/charts/ci/NodeChrome-values.yaml +++ b/tests/charts/ci/NodeChrome-values.yaml @@ -1,6 +1,7 @@ # This is used in Helm chart testing # Configuration for chrome nodes chromeNode: + port: 6666 nameOverride: my-chrome-name extraEnvironmentVariables: - name: SE_OPTS diff --git a/tests/charts/ci/NodeEdge-values.yaml b/tests/charts/ci/NodeEdge-values.yaml index 27220e2759..7c78ccbe7d 100644 --- a/tests/charts/ci/NodeEdge-values.yaml +++ b/tests/charts/ci/NodeEdge-values.yaml @@ -4,6 +4,7 @@ chromeNode: enabled: false # Configuration for edge nodes edgeNode: + port: 8888 nameOverride: my-edge-name extraEnvironmentVariables: - name: SE_OPTS diff --git a/tests/charts/ci/NodeFirefox-values.yaml b/tests/charts/ci/NodeFirefox-values.yaml index 21bb6a2856..72cce27c5e 100644 --- a/tests/charts/ci/NodeFirefox-values.yaml +++ b/tests/charts/ci/NodeFirefox-values.yaml @@ -7,6 +7,7 @@ edgeNode: enabled: false # Configuration for firefox nodes firefoxNode: + port: 7777 nameOverride: my-firefox-name extraEnvironmentVariables: - name: SE_OPTS diff --git a/tests/charts/ci/auth-ingress-values.yaml b/tests/charts/ci/auth-ingress-values.yaml index e5d055ba63..38bc87e1b3 100644 --- a/tests/charts/ci/auth-ingress-values.yaml +++ b/tests/charts/ci/auth-ingress-values.yaml @@ -1,11 +1,16 @@ +global: + K8S_PUBLIC_IP: localhost + ingress: annotations: + kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/use-regex: "true" nginx.ingress.kubernetes.io/rewrite-target: /$2 nginx.ingress.kubernetes.io/app-root: &gridAppRoot "/selenium" nginx.ingress.kubernetes.io/proxy-connect-timeout: "360" nginx.ingress.kubernetes.io/proxy-read-timeout: "360" nginx.ingress.kubernetes.io/proxy-send-timeout: "360" + ingressClassName: nginx hostname: "" paths: - path: /selenium(/|$)(.*) @@ -15,16 +20,10 @@ ingress: name: '{{ template "seleniumGrid.router.fullname" $ }}' port: number: 4444 - - path: /(/?)(session/.*/se/vnc) - pathType: ImplementationSpecific - backend: - service: - name: '{{ template "seleniumGrid.router.fullname" $ }}' - port: - number: 4444 basicAuth: enabled: false + isolateComponents: true hub: @@ -32,3 +31,11 @@ hub: components: subPath: *gridAppRoot + +ingress-nginx: + enabled: true + controller: + hostNetwork: true + kind: DaemonSet + service: + type: ClusterIP diff --git a/tests/charts/ci/autoscaling-values.yaml b/tests/charts/ci/autoscaling-values.yaml deleted file mode 100644 index 7fa80b2bb3..0000000000 --- a/tests/charts/ci/autoscaling-values.yaml +++ /dev/null @@ -1,5 +0,0 @@ -autoscaling: - enableWithExistingKEDA: true - scalingType: job - scaledOptions: - minReplicaCount: 0 diff --git a/tests/charts/config/ct.yaml b/tests/charts/config/ct.yaml index 7c085d076c..2b2446823d 100755 --- a/tests/charts/config/ct.yaml +++ b/tests/charts/config/ct.yaml @@ -5,6 +5,7 @@ chart-dirs: - charts chart-repos: - kedacore=https://kedacore.github.io/charts + - ingressNginx=https://kubernetes.github.io/ingress-nginx upgrade: false helm-extra-args: --timeout 600s check-version-increment: false diff --git a/tests/charts/make/chart_cluster_setup.sh b/tests/charts/make/chart_cluster_setup.sh index 76b27872dc..c87cbc5b1d 100755 --- a/tests/charts/make/chart_cluster_setup.sh +++ b/tests/charts/make/chart_cluster_setup.sh @@ -38,13 +38,6 @@ kind create cluster --wait ${WAIT_TIMEOUT} --name ${CLUSTER_NAME} --config tests echo "Install KEDA core on kind kubernetes cluster" kubectl apply --server-side -f https://github.com/kedacore/keda/releases/download/v2.12.1/keda-2.12.1-core.yaml -echo "Install ingress-nginx on kind kubernetes cluster" -kubectl apply -n ${INGRESS_NAMESPACE} -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml -kubectl wait --namespace ${INGRESS_NAMESPACE} \ - --for=condition=ready pod \ - --selector=app.kubernetes.io/component=controller \ - --timeout=${WAIT_TIMEOUT} - echo "Load built local Docker Images into Kind Cluster" image_list=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep ${NAMESPACE} | grep ${VERSION}) for image in $image_list; do diff --git a/tests/charts/make/chart_test.sh b/tests/charts/make/chart_test.sh index 2d87c799ef..194bb60560 100755 --- a/tests/charts/make/chart_test.sh +++ b/tests/charts/make/chart_test.sh @@ -1,4 +1,6 @@ #!/bin/bash +mkdir -p tests/tests +set -o xtrace echo "Set ENV variables" CLUSTER_NAME=${CLUSTER_NAME:-"chart-testing"} @@ -31,7 +33,7 @@ cleanup() { on_failure() { local exit_status=$? echo "Describe all resources in the ${SELENIUM_NAMESPACE} namespace for debugging purposes" - kubectl describe all -n ${SELENIUM_NAMESPACE} + kubectl describe all -n ${SELENIUM_NAMESPACE} > tests/tests/describe_all_resources_${MATRIX_BROWSER}.txt echo "There is step failed with exit status $exit_status" cleanup exit $exit_status @@ -42,20 +44,25 @@ trap 'on_failure' ERR HELM_COMMAND_SET_AUTOSCALING="" if [ "${SELENIUM_GRID_AUTOSCALING}" = "true" ]; then - HELM_COMMAND_SET_AUTOSCALING="--values ${TEST_VALUES_PATH}/autoscaling-values.yaml \ + HELM_COMMAND_SET_AUTOSCALING="--values ${TEST_VALUES_PATH}/DeploymentAutoScaling-values.yaml \ --set autoscaling.enableWithExistingKEDA=${SELENIUM_GRID_AUTOSCALING} \ --set autoscaling.scaledOptions.minReplicaCount=${SELENIUM_GRID_AUTOSCALING_MIN_REPLICA}" fi -echo "Deploy Selenium Grid Chart" -helm upgrade --install ${RELEASE_NAME} \ +HELM_COMMAND_ARGS="${RELEASE_NAME} \ --values ${TEST_VALUES_PATH}/auth-ingress-values.yaml \ --values ${TEST_VALUES_PATH}/tracing-values.yaml \ --values ${TEST_VALUES_PATH}/${MATRIX_BROWSER}-values.yaml \ ${HELM_COMMAND_SET_AUTOSCALING} \ --set global.seleniumGrid.imageTag=${VERSION} --set global.seleniumGrid.imageRegistry=${NAMESPACE} \ --set global.seleniumGrid.nodesImageTag=${VERSION} \ -${CHART_PATH} --namespace ${SELENIUM_NAMESPACE} --create-namespace +${CHART_PATH} --namespace ${SELENIUM_NAMESPACE} --create-namespace" + +echo "Render manifests YAML for this deployment" +helm template ${HELM_COMMAND_ARGS} > tests/tests/cluster_deployment_manifests_${MATRIX_BROWSER}.yaml + +echo "Deploy Selenium Grid Chart" +helm upgrade --install ${HELM_COMMAND_ARGS} echo "Run Tests" export SELENIUM_GRID_HOST=${SELENIUM_GRID_HOST} @@ -71,6 +78,6 @@ echo "Get pods status" kubectl get pods -n ${SELENIUM_NAMESPACE} echo "Get all resources in the ${SELENIUM_NAMESPACE} namespace" -kubectl get all -n ${SELENIUM_NAMESPACE} +kubectl get all -n ${SELENIUM_NAMESPACE} > tests/tests/describe_all_resources_${MATRIX_BROWSER}.txt cleanup diff --git a/tests/charts/refValues/sample-aws.yaml b/tests/charts/refValues/sample-aws.yaml new file mode 100644 index 0000000000..06172f0e36 --- /dev/null +++ b/tests/charts/refValues/sample-aws.yaml @@ -0,0 +1,74 @@ +# README: This is a sample values for chart deployment in EKS AWS +# Chart dependency ingress-nginx is installed together by enabling `ingress-nginx.enabled`. On AWS, ingress-nginx is installed as a Classic LoadBalancer +# Chart dependency keda is installed together by enabling `autoscaling.enable` +# Enabled ingress with hostname, set the subPath `/selenium`. Grid is accessible via http://my.hostname/selenium +# Use this reference values to deploy e.g. `helm upgrade --install test --values tests/charts/refValues/sample-aws.yaml docker-selenium/selenium-grid --version <0.26.3_onwards>` +global: + K8S_PUBLIC_IP: "" + seleniumGrid: + logLevel: INFO # Change to FINE when you want to debug the issue + +ingress: + enabled: true + annotations: + kubernetes.io/ingress.class: nginx + nginx.ingress.kubernetes.io/use-regex: "true" + nginx.ingress.kubernetes.io/rewrite-target: /$2 + nginx.ingress.kubernetes.io/app-root: &gridAppRoot "/selenium" + ingressClassName: nginx + hostname: "aws.ndviet.org" # Replace with your hostname + paths: + - path: /selenium(/|$)(.*) + pathType: ImplementationSpecific + backend: + service: + name: '{{ template "seleniumGrid.router.fullname" $ }}' + port: + number: 4444 + +basicAuth: + enabled: false + +isolateComponents: true + +autoscaling: + enabled: true + scalingType: job + annotations: + helm.sh/hook: post-install,post-upgrade,post-rollback + scaledOptions: + minReplicaCount: 0 + maxReplicaCount: 8 + pollingInterval: 15 + scaledJobOptions: + successfulJobsHistoryLimit: 0 + failedJobsHistoryLimit: 5 + scalingStrategy: + strategy: default + +hub: + subPath: *gridAppRoot + +components: + subPath: *gridAppRoot + +chromeNode: + extraEnvironmentVariables: &extraEnvironmentVariablesNodes + - name: SE_NODE_SESSION_TIMEOUT + value: "300" + - name: SE_VNC_NO_PASSWORD + value: "true" + - name: SE_OPTS + value: "--enable-managed-downloads true" + +firefoxNode: + extraEnvironmentVariables: *extraEnvironmentVariablesNodes + +edgeNode: + extraEnvironmentVariables: *extraEnvironmentVariablesNodes + +videoRecorder: + enabled: false + +ingress-nginx: + enabled: true diff --git a/tests/charts/refValues/simplex-minikube.yaml b/tests/charts/refValues/simplex-minikube.yaml new file mode 100644 index 0000000000..5239714c7a --- /dev/null +++ b/tests/charts/refValues/simplex-minikube.yaml @@ -0,0 +1,88 @@ +# README: This is a sample values for chart deployment in Minikube +# Chart dependency ingress-nginx is installed together by enabling `ingress-nginx.enabled` +# Chart dependency keda is installed together by enabling `autoscaling.enable` +# Enabled ingress without hostname, set the subPath `/selenium`. Set K8S_PUBLIC_IP point to the public host IP, where Minikube is running +# `ingress-nginx.controller.hostNetwork` is set to true to allow access from outside the cluster via http:///selenium +# Components serviceType is set to NodePort to allow access from outside the cluster via K8S_PUBLIC_IP and NodePort http://:30444/selenium +# Use this reference values to deploy e.g. `helm upgrade --install test --values tests/charts/refValues/simplex-minikube.yaml docker-selenium/selenium-grid --version <0.26.3_onwards>` +global: + K8S_PUBLIC_IP: "10.10.10.10" # Replace with your public IP + seleniumGrid: + logLevel: INFO +# imageRegistry: selenium +# imageTag: latest +# nodesImageTag: latest +# videoImageTag: latest + +ingress: + enabled: true + annotations: + kubernetes.io/ingress.class: nginx + nginx.ingress.kubernetes.io/use-regex: "true" + nginx.ingress.kubernetes.io/rewrite-target: /$2 + nginx.ingress.kubernetes.io/app-root: &gridAppRoot "/selenium" + ingressClassName: nginx + hostname: "" + paths: + - path: /selenium(/|$)(.*) + pathType: ImplementationSpecific + backend: + service: + name: '{{ template "seleniumGrid.router.fullname" $ }}' + port: + number: 4444 + +basicAuth: + enabled: false + +isolateComponents: true + +autoscaling: + enabled: true + scalingType: job + annotations: + helm.sh/hook: post-install,post-upgrade,post-rollback + scaledOptions: + minReplicaCount: 0 + maxReplicaCount: 8 + pollingInterval: 15 + scaledJobOptions: + successfulJobsHistoryLimit: 0 + failedJobsHistoryLimit: 5 + scalingStrategy: + strategy: default + +hub: + subPath: *gridAppRoot + serviceType: NodePort + +components: + subPath: *gridAppRoot + router: + serviceType: NodePort + +chromeNode: + extraEnvironmentVariables: &extraEnvironmentVariablesNodes + - name: SE_NODE_SESSION_TIMEOUT + value: "300" + - name: SE_VNC_NO_PASSWORD + value: "true" + - name: SE_OPTS + value: "--enable-managed-downloads true" + +firefoxNode: + extraEnvironmentVariables: *extraEnvironmentVariablesNodes + +edgeNode: + extraEnvironmentVariables: *extraEnvironmentVariablesNodes + +videoRecorder: + enabled: false + +ingress-nginx: + enabled: true + controller: + hostNetwork: true + kind: DaemonSet + service: + type: ClusterIP diff --git a/tests/charts/templates/render/dummy.yaml b/tests/charts/templates/render/dummy.yaml index 19ca7d6d99..42864d78fc 100644 --- a/tests/charts/templates/render/dummy.yaml +++ b/tests/charts/templates/render/dummy.yaml @@ -1,6 +1,8 @@ # This is dummy values file for chart template testing global: + K8S_PUBLIC_IP: "10.10.10.10" seleniumGrid: + logLevel: FINE affinity: &affinity podAffinity: requiredDuringSchedulingIgnoredDuringExecution: @@ -11,6 +13,11 @@ global: values: - selenium topologyKey: "kubernetes.io/hostname" + +basicAuth: + username: sysadmin + password: strongPassword + ingress: nginx: proxyTimeout: 360 # Set different proxy timout @@ -24,6 +31,9 @@ ingress: nginx.ingress.kubernetes.io/proxy-connect-timeout: "3600" # Override default key nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" # Override default key hostname: "" + ports: + http: 8081 + https: 8443 paths: - path: /selenium(/|$)(.*) pathType: ImplementationSpecific @@ -42,6 +52,19 @@ ingress: isolateComponents: true +components: + subPath: *gridAppRoot + router: + serviceType: NodePort + distributor: + serviceType: NodePort + eventBus: + serviceType: NodePort + sessionQueue: + serviceType: NodePort + sessionMap: + serviceType: NodePort + chromeNode: affinity: *affinity diff --git a/tests/charts/templates/test.py b/tests/charts/templates/test.py index 1e751f4e33..8587b42d7c 100644 --- a/tests/charts/templates/test.py +++ b/tests/charts/templates/test.py @@ -45,6 +45,62 @@ def test_ingress_nginx_annotations(self): count += 1 self.assertEqual(count, len(resources_name), "No ingress resources found") + def test_sub_path_append_to_node_grid_url(self): + resources_name = ['selenium-node-config'] + count = 0 + for doc in LIST_OF_DOCUMENTS: + if doc['metadata']['name'] in resources_name and doc['kind'] == 'ConfigMap': + logger.info(f"Assert subPath is appended to node grid url") + self.assertTrue(doc['data']['SE_NODE_GRID_URL'] == 'http://sysadmin:strongPassword@10.10.10.10:8081/selenium') + count += 1 + self.assertEqual(count, len(resources_name), "No node config resources found") + + def test_sub_path_set_to_grid_env_var(self): + resources_name = ['selenium-router'] + is_present = False + for doc in LIST_OF_DOCUMENTS: + if doc['metadata']['name'] in resources_name and doc['kind'] == 'Deployment': + logger.info(f"Assert subPath is set to grid ENV variable") + list_env = doc['spec']['template']['spec']['containers'][0]['env'] + for env in list_env: + if env['name'] == 'SE_SUB_PATH' and env['value'] == '/selenium': + is_present = True + self.assertTrue(is_present, "ENV variable SE_SUB_PATH is not populated") + + def test_log_level_set_to_logging_config_map(self): + resources_name = ['selenium-chrome-node', 'selenium-distributor', 'selenium-edge-node', 'selenium-firefox-node', + 'selenium-event-bus', 'selenium-router', 'selenium-session-map', 'selenium-session-queue'] + logger.info(f"Assert log level value is set to logging ConfigMap") + count_config = 0 + for doc in LIST_OF_DOCUMENTS: + if doc['metadata']['name'] == 'selenium-logging-config' and doc['kind'] == 'ConfigMap': + self.assertTrue(doc['data']['SE_LOG_LEVEL'] == 'FINE') + count_config += 1 + self.assertEqual(count_config, 1, "No logging ConfigMap found") + count = 0 + for doc in LIST_OF_DOCUMENTS: + if doc['metadata']['name'] in resources_name and doc['kind'] == 'Deployment': + is_present = False + logger.info(f"Assert logging ConfigMap is set to envFrom in resource {doc['metadata']['name']}") + list_env_from = doc['spec']['template']['spec']['containers'][0]['envFrom'] + for env in list_env_from: + if env['configMapRef']['name'] == 'selenium-logging-config': + is_present = True + self.assertTrue(is_present, "envFrom doesn't contain logging ConfigMap") + count += 1 + self.assertEqual(count, len(resources_name), "Logging ConfigMap is not present in expected resources") + + def test_node_port_set_when_service_type_is_node_port(self): + single_node_port = {'selenium-distributor': 30553, 'selenium-router': 30444, 'selenium-session-queue': 30559} + count = 0 + logger.info(f"Assert NodePort is set to components service") + for doc in LIST_OF_DOCUMENTS: + if doc['metadata']['name'] in single_node_port.keys() and doc['kind'] == 'Service': + logger.info(f"Assert NodePort is set to service {doc['metadata']['name']}") + self.assertTrue(doc['spec']['ports'][0]['nodePort'] == single_node_port[doc['metadata']['name']], f"Service {doc['metadata']['name']} with expect NodePort {single_node_port[doc['metadata']['name']]} is not found") + count += 1 + self.assertEqual(count, len(single_node_port.keys()), "Number of services with NodePort is not correct") + if __name__ == '__main__': failed = False try: diff --git a/tests/test.py b/tests/test.py index c94df6a428..9757721032 100644 --- a/tests/test.py +++ b/tests/test.py @@ -65,7 +65,7 @@ 'StandaloneChromium': 'ChromeTests', # Chart Parallel Test - 'ParallelAutoscaling': 'ParallelAutoscalingTests' + 'JobAutoscaling': 'JobAutoscalingTests' } FROM_IMAGE_ARGS = { diff --git a/update_tag_in_docs_and_files.sh b/update_tag_in_docs_and_files.sh index 3783f30f51..11da34f953 100755 --- a/update_tag_in_docs_and_files.sh +++ b/update_tag_in_docs_and_files.sh @@ -11,14 +11,14 @@ echo -e "\033[0;32m LATEST_TAG -> ${LATEST_TAG}\033[0m" echo -e "\033[0;32m NEXT_TAG -> ${NEXT_TAG}\033[0m" # If you want to test this locally and you are using macOS, do `brew install gnu-sed` and change `sed` for `gsed`. -find . \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s/${LATEST_TAG}/${NEXT_TAG}/g" +find . \( -type d -name .git -prune \) -o -type f ! -name 'CHANGELOG.md' -print0 | xargs -0 sed -i "s/${LATEST_TAG}/${NEXT_TAG}/g" echo -e "\033[0;32m Updating date used in some docs and files...\033[0m" echo -e "\033[0;32m LATEST_DATE -> ${LATEST_DATE}\033[0m" echo -e "\033[0;32m NEXT_DATE -> ${NEXT_DATE}\033[0m" # If you want to test this locally and you are using macOS, do `brew install gnu-sed` and change `sed` for `gsed`. -find . \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s/${LATEST_DATE}/${NEXT_DATE}/g" +find . \( -type d -name .git -prune \) -o -type f ! -name 'CHANGELOG.md' -print0 | xargs -0 sed -i "s/${LATEST_DATE}/${NEXT_DATE}/g" # Bump chart version and appVersion if next tag is different if [ "$latest_chart_app_version" == $LATEST_TAG ] && [ "$latest_chart_app_version" != "$NEXT_TAG" ]; then @@ -42,6 +42,7 @@ if [ "$latest_chart_app_version" == $LATEST_TAG ] && [ "$latest_chart_app_versio echo -e "\033[0;32m NEXT_CHART_VERSION -> ${next_chart_version}\033[0m" # If you want to test this locally and you are using macOS, do `brew install gnu-sed` and change `sed` for `gsed`. find . \( -type d -name .git -prune \) -o -type f -name 'Chart.yaml' -print0 | xargs -0 sed -i "s/${latest_chart_version}/${next_chart_version}/g" + find . \( -type d -name .git -prune \) -o -type f -name 'bug_report.yaml' -print0 | xargs -0 sed -i "s/${latest_chart_version}/${next_chart_version}/g" fi git diff | cat