From 16d24abadd586184bc2891a6fdbdf54f0b3d7f5f Mon Sep 17 00:00:00 2001 From: Viet Nguyen Duc Date: Tue, 3 Dec 2024 21:19:43 +0700 Subject: [PATCH 1/2] K8s: Add configs for sessions external datastore Signed-off-by: Viet Nguyen Duc --- Base/Dockerfile | 14 ++++- Makefile | 4 +- Sessions/Dockerfile | 17 ++++-- Sessions/generate_config | 39 +++++++++++++ Sessions/start-selenium-grid-sessions.sh | 26 ++++++++- charts/selenium-grid/CONFIGURATION.md | 14 +++++ charts/selenium-grid/Chart.yaml | 8 +++ charts/selenium-grid/README.md | 33 +++++++++++ .../selenium-grid/templates/_nameHelpers.tpl | 7 +++ .../templates/session-map-configmap.yaml | 45 +++++++++++++++ .../templates/session-map-deployment.yaml | 2 + charts/selenium-grid/values.yaml | 56 +++++++++++++++++++ tests/charts/config/ct.yaml | 1 + tests/charts/make/chart_test.sh | 14 +++++ tests/charts/templates/render/dummy.yaml | 3 + .../templates/render/dummy_solution.yaml | 3 + 16 files changed, 274 insertions(+), 12 deletions(-) create mode 100755 Sessions/generate_config create mode 100644 charts/selenium-grid/templates/session-map-configmap.yaml diff --git a/Base/Dockerfile b/Base/Dockerfile index bf6d4ffd01..40b4c979f1 100644 --- a/Base/Dockerfile +++ b/Base/Dockerfile @@ -11,6 +11,8 @@ ARG OPENTELEMETRY_VERSION=1.44.1 ARG GRPC_VERSION=1.68.1 ARG NETTY_VERSION=4.1.115.Final ARG CS_VERSION=2.1.18 +ARG POSTGRESQL_VERSION=42.7.4 +ARG MVN_SELENIUM_VERSION=4.27.0 #Arguments to define the user running Selenium ARG SEL_USER=seluser @@ -118,8 +120,16 @@ RUN --mount=type=secret,id=SEL_PASSWD \ && if [ -f "/tmp/cs" ]; then \ java -jar /tmp/cs fetch --classpath --cache /external_jars \ io.opentelemetry:opentelemetry-exporter-otlp:${OPENTELEMETRY_VERSION} \ - io.grpc:grpc-netty:${GRPC_VERSION} io.netty:netty-codec-http:${NETTY_VERSION} > /external_jars/.classpath.txt \ - && chmod 664 /external_jars/.classpath.txt ; \ + io.grpc:grpc-netty:${GRPC_VERSION} \ + io.netty:netty-codec-http:${NETTY_VERSION} \ + > /external_jars/.classpath.txt \ + && chmod 664 /external_jars/.classpath.txt \ + && java -jar /tmp/cs fetch --classpath --cache /external_jars \ + org.seleniumhq.selenium:selenium-session-map-jdbc:${MVN_SELENIUM_VERSION} \ + org.postgresql:postgresql:${POSTGRESQL_VERSION} \ + org.seleniumhq.selenium:selenium-session-map-redis:${MVN_SELENIUM_VERSION} \ + > /external_jars/.classpath_session_map.txt \ + && chmod 664 /external_jars/.classpath_session_map.txt ; \ fi \ && rm -fr /root/.cache/* \ # (Note that .bashrc is only executed in interactive bash shells.) diff --git a/Makefile b/Makefile index d0c4cfdb41..8b33a498d4 100644 --- a/Makefile +++ b/Makefile @@ -917,7 +917,7 @@ chart_test_autoscaling_disabled: ./tests/charts/make/chart_test.sh NoAutoscaling chart_test_autoscaling_deployment_https: - PLATFORMS=$(PLATFORMS) CHART_FULL_DISTRIBUTED_MODE=true CHART_ENABLE_BASIC_AUTH=true \ + PLATFORMS=$(PLATFORMS) CHART_FULL_DISTRIBUTED_MODE=true CHART_ENABLE_BASIC_AUTH=true TEST_EXTERNAL_DATASTORE=postgresql \ SECURE_INGRESS_ONLY_DEFAULT=true INGRESS_DISABLE_USE_HTTP2=true SELENIUM_GRID_PROTOCOL=https CHART_ENABLE_INGRESS_HOSTNAME=true SELENIUM_GRID_PORT=443 \ SELENIUM_GRID_AUTOSCALING_MIN_REPLICA=0 MAX_SESSIONS_FIREFOX=1 MAX_SESSIONS_EDGE=1 MAX_SESSIONS_CHROME=1 TEST_NAME_OVERRIDE=true \ VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) KEDA_BASED_NAME=$(KEDA_BASED_NAME) KEDA_BASED_TAG=$(KEDA_BASED_TAG) NAMESPACE=$(NAMESPACE) BINDING_VERSION=$(BINDING_VERSION) BASE_VERSION=$(BASE_VERSION) \ @@ -955,7 +955,7 @@ chart_test_autoscaling_job: ./tests/charts/make/chart_test.sh JobAutoscaling chart_test_autoscaling_playwright_connect_grid: - PLATFORMS=$(PLATFORMS) CHART_ENABLE_TRACING=true CHART_ENABLE_BASIC_AUTH=true MATRIX_TESTS=CDPTests \ + PLATFORMS=$(PLATFORMS) CHART_FULL_DISTRIBUTED_MODE=true CHART_ENABLE_BASIC_AUTH=true TEST_EXTERNAL_DATASTORE=redis MATRIX_TESTS=CDPTests \ BASIC_AUTH_USERNAME=docker-selenium BASIC_AUTH_PASSWORD=2NMI4jdBi6k7bENoeUfV25295VvzwAE9chM24a+2VL95uOHozo \ SECURE_INGRESS_ONLY_DEFAULT=true SECURE_USE_EXTERNAL_CERT=true SELENIUM_GRID_PROTOCOL=https SELENIUM_GRID_HOST=$$(hostname -I | cut -d' ' -f1) SELENIUM_GRID_PORT=443 \ VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) KEDA_BASED_NAME=$(KEDA_BASED_NAME) KEDA_BASED_TAG=$(KEDA_BASED_TAG) NAMESPACE=$(NAMESPACE) BINDING_VERSION=$(BINDING_VERSION) BASE_VERSION=$(BASE_VERSION) \ diff --git a/Sessions/Dockerfile b/Sessions/Dockerfile index a9d550a82c..66f7ceed7d 100644 --- a/Sessions/Dockerfile +++ b/Sessions/Dockerfile @@ -4,17 +4,24 @@ FROM ${NAMESPACE}/base:${VERSION} ARG AUTHORS LABEL authors=${AUTHORS} -USER ${SEL_UID} - #======================== # Selenium SessionMap Configuration #======================== -EXPOSE 5556 +USER root -COPY --chown="${SEL_UID}:${SEL_GID}" start-selenium-grid-sessions.sh \ +COPY --chown="${SEL_UID}:${SEL_GID}" start-selenium-grid-sessions.sh generate_config \ /opt/bin/ +RUN chmod +x /opt/bin/start-selenium-grid-sessions.sh /opt/bin/generate_config COPY selenium-grid-sessions.conf /etc/supervisor/conf.d/ -ENV SE_OTEL_SERVICE_NAME="selenium-session-map" +USER ${SEL_UID} + +EXPOSE 5556 + +ENV SE_OTEL_SERVICE_NAME="selenium-session-map" \ + # Path to the Configfile + CONFIG_FILE=/opt/selenium/config.toml \ + GENERATE_CONFIG=true \ + SE_SESSIONS_MAP_EXTERNAL_DATASTORE=false diff --git a/Sessions/generate_config b/Sessions/generate_config new file mode 100755 index 0000000000..7c41aa1085 --- /dev/null +++ b/Sessions/generate_config @@ -0,0 +1,39 @@ +#!/bin/bash + +if [[ -z "$CONFIG_FILE" ]]; then + FILENAME="/opt/selenium/config.toml" +else + FILENAME="$CONFIG_FILE" +fi + +echo "[sessions]" >"$FILENAME" + +if [ "${SE_SESSIONS_MAP_EXTERNAL_DATASTORE}" = "true" ]; then + if [[ -n "${SE_SESSIONS_MAP_EXTERNAL_SCHEME}" ]]; then + echo "scheme = \"${SE_SESSIONS_MAP_EXTERNAL_SCHEME}\"" >>"$FILENAME" + fi + + if [[ -n "${SE_SESSIONS_MAP_EXTERNAL_IMPLEMENTATION}" ]]; then + echo "implementation = \"${SE_SESSIONS_MAP_EXTERNAL_IMPLEMENTATION}\"" >>"$FILENAME" + fi + + if [[ -n "${SE_SESSIONS_MAP_EXTERNAL_HOSTNAME}" ]]; then + echo "hostname = \"${SE_SESSIONS_MAP_EXTERNAL_HOSTNAME}\"" >>"$FILENAME" + fi + + if [[ -n "${SE_SESSIONS_MAP_EXTERNAL_PORT}" ]]; then + echo "port = \"${SE_SESSIONS_MAP_EXTERNAL_PORT}\"" >>"$FILENAME" + fi + + if [[ -n "${SE_SESSIONS_MAP_EXTERNAL_JDBC_URL}" ]]; then + echo "jdbc-url = \"${SE_SESSIONS_MAP_EXTERNAL_JDBC_URL}\"" >>"$FILENAME" + fi + + if [[ -n "${SE_SESSIONS_MAP_EXTERNAL_JDBC_USER}" ]]; then + echo "jdbc-user = \"${SE_SESSIONS_MAP_EXTERNAL_JDBC_USER}\"" >>"$FILENAME" + fi + + if [[ -n "${SE_SESSIONS_MAP_EXTERNAL_JDBC_PASSWORD}" ]]; then + echo "jdbc-password = \"${SE_SESSIONS_MAP_EXTERNAL_JDBC_PASSWORD}\"" >>"$FILENAME" + fi +fi diff --git a/Sessions/start-selenium-grid-sessions.sh b/Sessions/start-selenium-grid-sessions.sh index db8dfffdb5..b0357269ff 100755 --- a/Sessions/start-selenium-grid-sessions.sh +++ b/Sessions/start-selenium-grid-sessions.sh @@ -3,8 +3,6 @@ # set -e: exit asap if a command exits with a non-zero status set -e -echo "Starting Selenium Grid Sessions..." - function append_se_opts() { local option="${1}" local value="${2:-""}" @@ -98,12 +96,21 @@ if [ ! -z "$SE_REGISTRATION_SECRET" ]; then append_se_opts "--registration-secret" "${SE_REGISTRATION_SECRET}" "false" fi +if [ "$GENERATE_CONFIG" = true ]; then + echo "Generating Selenium Config for Sessions" + /opt/bin/generate_config +fi + +if [ ! -z "${CONFIG_FILE}" ]; then + append_se_opts "--config" "${CONFIG_FILE}" +fi + EXTRA_LIBS="" if [ "$SE_ENABLE_TRACING" = "true" ]; then EXTERNAL_JARS=$( Date: Wed, 4 Dec 2024 01:33:08 +0700 Subject: [PATCH 2/2] Add docker-compose file for reference [skip ci] Signed-off-by: Viet Nguyen Duc --- Base/Dockerfile | 2 + Distributor/selenium-grid-distributor.conf | 5 +- EventBus/selenium-grid-eventbus.conf | 5 +- Hub/selenium-grid-hub.conf | 5 +- Router/selenium-grid-router.conf | 5 +- SessionQueue/selenium-grid-session-queue.conf | 5 +- Sessions/init.sql | 7 + Sessions/selenium-grid-sessions.conf | 5 +- docker-compose-v2-tracing.yml | 2 +- ...ompose-v3-full-grid-external-datastore.yml | 133 ++++++++++++++++++ docker-compose-v3-full-grid-tracing.yml | 2 +- docker-compose-v3-tracing.yml | 2 +- 12 files changed, 163 insertions(+), 15 deletions(-) create mode 100644 Sessions/init.sql create mode 100644 docker-compose-v3-full-grid-external-datastore.yml diff --git a/Base/Dockerfile b/Base/Dockerfile index 40b4c979f1..348e845746 100644 --- a/Base/Dockerfile +++ b/Base/Dockerfile @@ -175,6 +175,8 @@ ENV SE_BIND_HOST=false \ SE_SUPERVISORD_CHILD_LOG_DIR="/tmp" \ SE_SUPERVISORD_LOG_FILE="/tmp/supervisord.log" \ SE_SUPERVISORD_PID_FILE="/tmp/supervisord.pid" \ + SE_SUPERVISORD_AUTO_RESTART=true \ + SE_SUPERVISORD_START_RETRIES=5 \ SE_LOG_TIMESTAMP_FORMAT="%Y-%m-%d %H:%M:%S,%3N" \ SE_LOG_LEVEL="INFO" \ SE_HTTP_LOGS=false \ diff --git a/Distributor/selenium-grid-distributor.conf b/Distributor/selenium-grid-distributor.conf index 0a3dda3163..8bb3e19f06 100644 --- a/Distributor/selenium-grid-distributor.conf +++ b/Distributor/selenium-grid-distributor.conf @@ -5,9 +5,10 @@ priority=0 command=/opt/bin/start-selenium-grid-distributor.sh autostart=true -autorestart=false +autorestart=%(ENV_SE_SUPERVISORD_AUTO_RESTART)s startsecs=0 -startretries=0 +startretries=%(ENV_SE_SUPERVISORD_START_RETRIES)s +stopsignal=TERM ;Logs (all Hub activity redirected to stdout so it can be seen through "docker logs" redirect_stderr=true diff --git a/EventBus/selenium-grid-eventbus.conf b/EventBus/selenium-grid-eventbus.conf index 3e12c746f8..3409e4f4cd 100644 --- a/EventBus/selenium-grid-eventbus.conf +++ b/EventBus/selenium-grid-eventbus.conf @@ -5,9 +5,10 @@ priority=0 command=/opt/bin/start-selenium-grid-eventbus.sh autostart=true -autorestart=false +autorestart=%(ENV_SE_SUPERVISORD_AUTO_RESTART)s startsecs=0 -startretries=0 +startretries=%(ENV_SE_SUPERVISORD_START_RETRIES)s +stopsignal=TERM ;Logs (all Hub activity redirected to stdout so it can be seen through "docker logs" redirect_stderr=true diff --git a/Hub/selenium-grid-hub.conf b/Hub/selenium-grid-hub.conf index bd67dae312..42ffbfef93 100644 --- a/Hub/selenium-grid-hub.conf +++ b/Hub/selenium-grid-hub.conf @@ -5,9 +5,10 @@ priority=0 command=/opt/bin/start-selenium-grid-hub.sh autostart=true -autorestart=false +autorestart=%(ENV_SE_SUPERVISORD_AUTO_RESTART)s startsecs=0 -startretries=0 +startretries=%(ENV_SE_SUPERVISORD_START_RETRIES)s +stopsignal=TERM ;Logs (all Hub activity redirected to stdout so it can be seen through "docker logs" redirect_stderr=true diff --git a/Router/selenium-grid-router.conf b/Router/selenium-grid-router.conf index a5c3dca905..931857bb4c 100644 --- a/Router/selenium-grid-router.conf +++ b/Router/selenium-grid-router.conf @@ -5,9 +5,10 @@ priority=0 command=/opt/bin/start-selenium-grid-router.sh autostart=true -autorestart=false +autorestart=%(ENV_SE_SUPERVISORD_AUTO_RESTART)s startsecs=0 -startretries=0 +startretries=%(ENV_SE_SUPERVISORD_START_RETRIES)s +stopsignal=TERM ;Logs (all Hub activity redirected to stdout so it can be seen through "docker logs" redirect_stderr=true diff --git a/SessionQueue/selenium-grid-session-queue.conf b/SessionQueue/selenium-grid-session-queue.conf index e82308526e..0511b993c0 100644 --- a/SessionQueue/selenium-grid-session-queue.conf +++ b/SessionQueue/selenium-grid-session-queue.conf @@ -5,9 +5,10 @@ priority=0 command=/opt/bin/start-selenium-grid-session-queue.sh autostart=true -autorestart=false +autorestart=%(ENV_SE_SUPERVISORD_AUTO_RESTART)s startsecs=0 -startretries=0 +startretries=%(ENV_SE_SUPERVISORD_START_RETRIES)s +stopsignal=TERM ;Logs (all Hub activity redirected to stdout so it can be seen through "docker logs" redirect_stderr=true diff --git a/Sessions/init.sql b/Sessions/init.sql new file mode 100644 index 0000000000..989ee55168 --- /dev/null +++ b/Sessions/init.sql @@ -0,0 +1,7 @@ +CREATE TABLE IF NOT EXISTS sessions_map( + session_ids varchar(256), + session_caps text, + session_uri varchar(256), + session_stereotype text, + session_start varchar(256) + ); diff --git a/Sessions/selenium-grid-sessions.conf b/Sessions/selenium-grid-sessions.conf index a3b9487ad4..8af1e8855b 100644 --- a/Sessions/selenium-grid-sessions.conf +++ b/Sessions/selenium-grid-sessions.conf @@ -5,9 +5,10 @@ priority=0 command=/opt/bin/start-selenium-grid-sessions.sh autostart=true -autorestart=false +autorestart=%(ENV_SE_SUPERVISORD_AUTO_RESTART)s startsecs=0 -startretries=0 +startretries=%(ENV_SE_SUPERVISORD_START_RETRIES)s +stopsignal=TERM ;Logs (all Hub activity redirected to stdout so it can be seen through "docker logs" redirect_stderr=true diff --git a/docker-compose-v2-tracing.yml b/docker-compose-v2-tracing.yml index df5df9109b..c0219a95b4 100644 --- a/docker-compose-v2-tracing.yml +++ b/docker-compose-v2-tracing.yml @@ -4,7 +4,7 @@ version: '2' services: jaeger: - image: jaegertracing/all-in-one:1.60 + image: jaegertracing/all-in-one:latest ports: - "16686:16686" - "4317:4317" diff --git a/docker-compose-v3-full-grid-external-datastore.yml b/docker-compose-v3-full-grid-external-datastore.yml new file mode 100644 index 0000000000..8fa7d73507 --- /dev/null +++ b/docker-compose-v3-full-grid-external-datastore.yml @@ -0,0 +1,133 @@ +# To execute this docker compose yml file use `docker compose -f docker-compose-v3-full-grid.yml up` +# Add the `-d` flag at the end for detached execution +# To stop the execution, hit Ctrl+C, and then `docker compose -f docker-compose-v3-full-grid.yml down` +version: "3" +services: + selenium-event-bus: + image: selenium/event-bus:4.27.0-20241127 + container_name: selenium-event-bus + environment: + - SE_ENABLE_TRACING=false + ports: + - "4442:4442" + - "4443:4443" + - "5557:5557" + + selenium-sessions: + image: selenium/sessions:4.27.0-20241127 + container_name: selenium-sessions + ports: + - "5556:5556" + depends_on: + - selenium-event-bus + environment: + - SE_EVENT_BUS_HOST=selenium-event-bus + - SE_EVENT_BUS_PUBLISH_PORT=4442 + - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 + - SE_ENABLE_TRACING=false + - SE_SESSIONS_MAP_EXTERNAL_DATASTORE=true + - SE_SESSIONS_MAP_EXTERNAL_IMPLEMENTATION=org.openqa.selenium.grid.sessionmap.jdbc.JdbcBackedSessionMap + - SE_SESSIONS_MAP_EXTERNAL_JDBC_URL=jdbc:postgresql://postgresql:5432/selenium_sessions + - SE_SESSIONS_MAP_EXTERNAL_JDBC_USER=seluser + - SE_SESSIONS_MAP_EXTERNAL_JDBC_PASSWORD=seluser +# Uncomment the following lines to use Redis as the external datastore +# - SE_SESSIONS_MAP_EXTERNAL_SCHEME=redis +# - SE_SESSIONS_MAP_EXTERNAL_IMPLEMENTATION=org.openqa.selenium.grid.sessionmap.redis.RedisBackedSessionMap +# - SE_SESSIONS_MAP_EXTERNAL_HOSTNAME=redis +# - SE_SESSIONS_MAP_EXTERNAL_PORT=6379 + + postgresql: + image: postgres:latest + restart: always + environment: + - POSTGRES_USER=seluser + - POSTGRES_PASSWORD=seluser + - POSTGRES_DB=selenium_sessions + ports: + - "5432:5432" + volumes: + - ./Sessions/init.sql:/docker-entrypoint-initdb.d/init.sql + + redis: + image: redis:latest + restart: always + ports: + - "6379:6379" + + selenium-session-queue: + image: selenium/session-queue:4.27.0-20241127 + container_name: selenium-session-queue + environment: + - SE_ENABLE_TRACING=false + ports: + - "5559:5559" + + selenium-distributor: + image: selenium/distributor:4.27.0-20241127 + container_name: selenium-distributor + ports: + - "5553:5553" + depends_on: + - selenium-event-bus + - selenium-sessions + - selenium-session-queue + environment: + - SE_EVENT_BUS_HOST=selenium-event-bus + - SE_EVENT_BUS_PUBLISH_PORT=4442 + - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 + - SE_SESSIONS_MAP_HOST=selenium-sessions + - SE_SESSIONS_MAP_PORT=5556 + - SE_SESSION_QUEUE_HOST=selenium-session-queue + - SE_SESSION_QUEUE_PORT=5559 + - SE_ENABLE_TRACING=false + + selenium-router: + image: selenium/router:4.27.0-20241127 + container_name: selenium-router + ports: + - "4444:4444" + depends_on: + - selenium-distributor + - selenium-sessions + - selenium-session-queue + environment: + - SE_DISTRIBUTOR_HOST=selenium-distributor + - SE_DISTRIBUTOR_PORT=5553 + - SE_SESSIONS_MAP_HOST=selenium-sessions + - SE_SESSIONS_MAP_PORT=5556 + - SE_SESSION_QUEUE_HOST=selenium-session-queue + - SE_SESSION_QUEUE_PORT=5559 + - SE_ENABLE_TRACING=false + + chrome: + image: selenium/node-chrome:4.27.0-20241127 + shm_size: 2gb + depends_on: + - selenium-event-bus + environment: + - SE_EVENT_BUS_HOST=selenium-event-bus + - SE_EVENT_BUS_PUBLISH_PORT=4442 + - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 + - SE_ENABLE_TRACING=false + + edge: + image: selenium/node-edge:4.27.0-20241127 + shm_size: 2gb + depends_on: + - selenium-event-bus + environment: + - SE_EVENT_BUS_HOST=selenium-event-bus + - SE_EVENT_BUS_PUBLISH_PORT=4442 + - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 + - SE_ENABLE_TRACING=false + + firefox: + image: selenium/node-firefox:4.27.0-20241127 + shm_size: 2gb + depends_on: + - selenium-event-bus + environment: + - SE_EVENT_BUS_HOST=selenium-event-bus + - SE_EVENT_BUS_PUBLISH_PORT=4442 + - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 + - SE_ENABLE_TRACING=false diff --git a/docker-compose-v3-full-grid-tracing.yml b/docker-compose-v3-full-grid-tracing.yml index f0d0b8fd3b..8d43276a55 100644 --- a/docker-compose-v3-full-grid-tracing.yml +++ b/docker-compose-v3-full-grid-tracing.yml @@ -4,7 +4,7 @@ version: "3" services: jaeger: - image: jaegertracing/all-in-one:1.60 + image: jaegertracing/all-in-one:latest ports: - "16686:16686" - "4317:4317" diff --git a/docker-compose-v3-tracing.yml b/docker-compose-v3-tracing.yml index 847dd38402..412cedd6b0 100644 --- a/docker-compose-v3-tracing.yml +++ b/docker-compose-v3-tracing.yml @@ -4,7 +4,7 @@ version: "3" services: jaeger: - image: jaegertracing/all-in-one:1.60 + image: jaegertracing/all-in-one:latest ports: - "16686:16686" - "4317:4317"