Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: video upload supports both docker-compose and helm chart #2131

Merged
merged 3 commits into from
Feb 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/helm-chart-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ jobs:
echo "BUILD_DATE=$(date '+%Y%m%d')" >> $GITHUB_ENV
echo "IMAGE_REGISTRY=artifactory/selenium" >> $GITHUB_ENV
- name: Setup Kubernetes environment
run: make chart_setup_env
uses: nick-invision/retry@master
with:
timeout_minutes: 10
max_attempts: 3
command: make chart_setup_env
- name: Build Helm charts
run: |
BUILD_DATE=${BUILD_DATE} make chart_build
Expand Down
21 changes: 5 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ MAJOR_MINOR_PATCH := $(word 1,$(subst -, ,$(TAG_VERSION)))
FFMPEG_TAG_VERSION := $(or $(FFMPEG_TAG_VERSION),$(FFMPEG_TAG_VERSION),ffmpeg-6.1)
FFMPEG_BASED_NAME := $(or $(FFMPEG_BASED_NAME),$(FFMPEG_BASED_NAME),ndviet)
FFMPEG_BASED_TAG := $(or $(FFMPEG_BASED_TAG),$(FFMPEG_BASED_TAG),6.1-ubuntu2204)
RCLONE_BASED_TAG := $(or $(RCLONE_BASED_TAG),$(RCLONE_BASED_TAG),1.65)
RCLONE_TAG_VERSION := $(or $(RCLONE_TAG_VERSION),$(RCLONE_TAG_VERSION),rclone-1.65)

all: hub \
distributor \
Expand All @@ -36,7 +34,6 @@ all: hub \
standalone_edge \
standalone_firefox \
standalone_docker \
uploader \
video

build_nightly:
Expand Down Expand Up @@ -133,9 +130,6 @@ standalone_edge_dev: edge_dev
standalone_edge_beta: edge_beta
cd ./Standalone && docker build $(BUILD_ARGS) --build-arg NAMESPACE=$(NAME) --build-arg VERSION=beta --build-arg BASE=node-edge -t $(NAME)/standalone-edge:beta .

uploader:
cd ./Uploader && docker build $(BUILD_ARGS) --build-arg BASED_TAG=$(RCLONE_BASED_TAG) -t $(NAME)/uploader:$(RCLONE_TAG_VERSION)-$(BUILD_DATE) .

video:
cd ./Video && docker build $(BUILD_ARGS) --build-arg NAMESPACE=$(FFMPEG_BASED_NAME) --build-arg BASED_TAG=$(FFMPEG_BASED_TAG) -t $(NAME)/video:$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) .

Expand Down Expand Up @@ -171,7 +165,6 @@ tag_latest:
docker tag $(NAME)/standalone-firefox:$(TAG_VERSION) $(NAME)/standalone-firefox:latest
docker tag $(NAME)/standalone-docker:$(TAG_VERSION) $(NAME)/standalone-docker:latest
docker tag $(NAME)/video:$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) $(NAME)/video:latest
docker tag $(NAME)/uploader:$(RCLONE_TAG_VERSION)-$(BUILD_DATE) $(NAME)/uploader:latest

release_latest:
docker push $(NAME)/base:latest
Expand All @@ -191,7 +184,6 @@ release_latest:
docker push $(NAME)/standalone-firefox:latest
docker push $(NAME)/standalone-docker:latest
docker push $(NAME)/video:latest
docker push $(NAME)/uploader:latest

tag_nightly:
docker tag $(NAME)/base:$(TAG_VERSION) $(NAME)/base:nightly
Expand All @@ -211,7 +203,6 @@ tag_nightly:
docker tag $(NAME)/standalone-firefox:$(TAG_VERSION) $(NAME)/standalone-firefox:nightly
docker tag $(NAME)/standalone-docker:$(TAG_VERSION) $(NAME)/standalone-docker:nightly
docker tag $(NAME)/video:$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) $(NAME)/video:nightly
docker tag $(NAME)/uploader:$(RCLONE_TAG_VERSION)-$(BUILD_DATE) $(NAME)/uploader:nightly

release_nightly:
docker push $(NAME)/base:nightly
Expand All @@ -231,7 +222,6 @@ release_nightly:
docker push $(NAME)/standalone-firefox:nightly
docker push $(NAME)/standalone-docker:nightly
docker push $(NAME)/video:nightly
docker push $(NAME)/uploader:nightly

tag_major_minor:
docker tag $(NAME)/base:$(TAG_VERSION) $(NAME)/base:$(MAJOR)
Expand Down Expand Up @@ -365,7 +355,6 @@ release: tag_major_minor
docker push $(NAME)/standalone-firefox:$(MAJOR_MINOR_PATCH)
docker push $(NAME)/standalone-docker:$(MAJOR_MINOR_PATCH)
docker push $(NAME)/video:$(FFMPEG_TAG_VERSION)-$(BUILD_DATE)
docker push $(NAME)/uploader:$(RCLONE_TAG_VERSION)-$(BUILD_DATE)

test: test_chrome \
test_firefox \
Expand Down Expand Up @@ -443,29 +432,29 @@ chart_test_template:
./tests/charts/bootstrap.sh

chart_test_chrome:
VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) UPLOADER_TAG=$(RCLONE_TAG_VERSION)-$(BUILD_DATE) NAMESPACE=$(NAMESPACE) \
VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) NAMESPACE=$(NAMESPACE) \
./tests/charts/make/chart_test.sh NodeChrome

chart_test_firefox:
VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) UPLOADER_TAG=$(RCLONE_TAG_VERSION)-$(BUILD_DATE) NAMESPACE=$(NAMESPACE) \
VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) NAMESPACE=$(NAMESPACE) \
./tests/charts/make/chart_test.sh NodeFirefox

chart_test_edge:
VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) UPLOADER_TAG=$(RCLONE_TAG_VERSION)-$(BUILD_DATE) NAMESPACE=$(NAMESPACE) \
VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) NAMESPACE=$(NAMESPACE) \
./tests/charts/make/chart_test.sh NodeEdge

chart_test_autoscaling_deployment_https:
SELENIUM_GRID_TEST_HEADLESS=true SELENIUM_GRID_PROTOCOL=https SELENIUM_GRID_PORT=443 make chart_test_autoscaling_deployment

chart_test_autoscaling_deployment:
VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) UPLOADER_TAG=$(RCLONE_TAG_VERSION)-$(BUILD_DATE) NAMESPACE=$(NAMESPACE) \
VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) NAMESPACE=$(NAMESPACE) \
./tests/charts/make/chart_test.sh DeploymentAutoscaling

chart_test_autoscaling_job_https:
SELENIUM_GRID_TEST_HEADLESS=true SELENIUM_GRID_PROTOCOL=https SELENIUM_GRID_PORT=443 make chart_test_autoscaling_job

chart_test_autoscaling_job:
VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) UPLOADER_TAG=$(RCLONE_TAG_VERSION)-$(BUILD_DATE) NAMESPACE=$(NAMESPACE) \
VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) NAMESPACE=$(NAMESPACE) \
./tests/charts/make/chart_test.sh JobAutoscaling

.PHONY: \
Expand Down
114 changes: 88 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,45 +21,59 @@ Talk to us at https://www.selenium.dev/support/

## Contents

<!-- TOC -->
* [Community](#community)
* [Contents](#contents)
* [Quick start](#quick-start)
* [Try them out in a ready-to-use GitPod environment!](#try-them-out-in-a-ready-to-use-gitpod-environment)
* [Experimental Mult-Arch aarch64/armhf/amd64 Images](#experimental-mult-arch-aarch64armhfamd64-images)
* [Nightly Images](#nightly-images)
* [Dev and Beta Channel Browser Images](#dev-and-beta-channel-browser-images)
+ [Dev and Beta Standalone Mode](#dev-and-beta-standalone-mode)
+ [Dev and Beta on the Grid](#dev-and-beta-on-the-grid)
* [Dev and Beta Standalone Mode](#dev-and-beta-standalone-mode)
* [Dev and Beta on the Grid](#dev-and-beta-on-the-grid)
* [Execution modes](#execution-modes)
+ [Standalone](#standalone)
+ [Hub and Nodes](#hub-and-nodes)
- [Docker networking](#docker-networking)
- [Using different machines/VMs](#using-different-machinesvms)
- [Docker Compose](#docker-compose)
+ [Fully distributed mode - Router, Queue, Distributor, EventBus, SessionMap and Nodes](#fully-distributed-mode---router-queue-distributor-eventbus-sessionmap-and-nodes)
* [Standalone](#standalone)
* [Hub and Nodes](#hub-and-nodes)
* [Fully distributed mode - Router, Queue, Distributor, EventBus, SessionMap and Nodes](#fully-distributed-mode---router-queue-distributor-eventbus-sessionmap-and-nodes)
* [Video recording](#video-recording)
* [Video recording and uploading](#video-recording-and-uploading)
* [Dynamic Grid](#dynamic-grid)
+ [Configuration example](#configuration-example)
+ [Execution with Hub & Node roles](#execution-with-hub--node-roles)
+ [Execution with Standalone roles](#execution-with-standalone-roles)
+ [Using Dynamic Grid in different machines/VMs](#using-dynamic-grid-in-different-machinesvms)
+ [Execution with Docker Compose](#execution-with-docker-compose)
+ [Video recording, screen resolution, and time zones in a Dynamic Grid](#video-recording-screen-resolution-and-time-zones-in-a-dynamic-grid)
* [Kubernetes](#deploying-to-kubernetes)
* [Configuration example](#configuration-example)
* [Execution with Hub & Node roles](#execution-with-hub--node-roles)
* [Execution with Standalone roles](#execution-with-standalone-roles)
* [Using Dynamic Grid in different machines/VMs](#using-dynamic-grid-in-different-machinesvms)
* [Execution with Docker Compose](#execution-with-docker-compose)
* [Configuring the child containers](#configuring-the-child-containers)
* [Video recording, screen resolution, and time zones in a Dynamic Grid](#video-recording-screen-resolution-and-time-zones-in-a-dynamic-grid)
* [Deploying to Kubernetes](#deploying-to-kubernetes)
* [Configuring the containers](#configuring-the-containers)
+ [SE_OPTS Selenium Configuration Options](#se_opts-selenium-configuration-options)
+ [SE_JAVA_OPTS Java Environment Options](#se_java_opts-java-environment-options)
+ [Node configuration options](#node-configuration-options)
+ [Setting Sub Path](#setting-sub-path)
+ [Setting Screen Resolution](#setting-screen-resolution)
+ [Grid Url and Session Timeout](#grid-url-and-session-timeout)
+ [Session request timeout](#session-request-timeout)
+ [Increasing session concurrency per container](#increasing-session-concurrency-per-container)
+ [Running in Headless mode](#running-in-headless-mode)
* [SE_OPTS Selenium Configuration Options](#se_opts-selenium-configuration-options)
* [SE_JAVA_OPTS Java Environment Options](#se_java_opts-java-environment-options)
* [Node configuration options](#node-configuration-options)
* [Setting Sub Path](#setting-sub-path)
* [Setting Screen Resolution](#setting-screen-resolution)
* [Grid Url and Session Timeout](#grid-url-and-session-timeout)
* [Session request timeout](#session-request-timeout)
* [Increasing session concurrency per container](#increasing-session-concurrency-per-container)
* [Running in Headless mode](#running-in-headless-mode)
* [Stopping the Node/Standalone after N sessions have been executed](#stopping-the-nodestandalone-after-n-sessions-have-been-executed)
* [Building the images](#building-the-images)
* [Waiting for the Grid to be ready](#waiting-for-the-grid-to-be-ready)
* [Adding a HEALTHCHECK to the Grid](#adding-a-healthcheck-to-the-grid)
* [Using a bash script to wait for the Grid](#using-a-bash-script-to-wait-for-the-grid)
* [Install certificates for Chromium-based browsers](#install-certificates-for-chromium-based-browsers)
* [Alternative method: Add certificates to existing Selenium based images for browsers](#alternative-method-add-certificates-to-existing-selenium-based-images-for-browsers)
* [Debugging](#debugging)
* [Install certificates for Chromium based browsers](#install-certificates-for-Chromium-based-browsers)
* [Using a VNC client](#using-a-vnc-client)
* [Using your browser (no VNC client is needed)](#using-your-browser-no-vnc-client-is-needed)
* [Disabling VNC](#disabling-vnc)
* [Tracing in Grid](#tracing-in-grid)
* [Troubleshooting](#troubleshooting)

* [`--shm-size="2g"`](#--shm-size2g)
* [Headless](#headless)
* [Mounting volumes to retrieve downloaded files](#mounting-volumes-to-retrieve-downloaded-files)
* [Mounting volumes to retrieve video files](#mounting-volumes-to-retrieve-video-files)
<!-- TOC -->

## Quick start

Expand Down Expand Up @@ -521,6 +535,47 @@ Here is an example using a Hub and a few Nodes:

[`docker-compose-v3-video.yml`](docker-compose-v3-video.yml)

## Video recording and uploading

[RCLONE](https://rclone.org/) is installed in the video recorder image. You can use it to upload the videos to a cloud storage service.
Besides the video recording mentioned above, you can enable the upload functionality by setting the following environment variables:

```yaml
version: "3"
services:
chrome_video:
image: selenium/video:nightly
depends_on:
- chrome
environment:
- DISPLAY_CONTAINER_NAME=chrome
- SE_VIDEO_FILE_NAME=auto
- SE_VIDEO_UPLOAD_ENABLED=true
- SE_VIDEO_INTERNAL_UPLOAD=true
- SE_UPLOAD_DESTINATION_PREFIX=s3://mybucket/path
- RCLONE_CONFIG_S3_TYPE=s3
- RCLONE_CONFIG_S3_PROVIDER=GCS
- RCLONE_CONFIG_S3_ENV_AUTH=true
- RCLONE_CONFIG_S3_REGION=asia-southeast1
- RCLONE_CONFIG_S3_LOCATION_CONSTRAINT=asia-southeast1
- RCLONE_CONFIG_S3_ACL=private
- RCLONE_CONFIG_S3_ACCESS_KEY_ID=xxx
- RCLONE_CONFIG_S3_SECRET_ACCESS_KEY=xxx
- RCLONE_CONFIG_S3_ENDPOINT=https://storage.googleapis.com
```

`SE_VIDEO_FILE_NAME=auto` will use the session id as the video file name. This ensures that the video file name is unique to upload.

`SE_VIDEO_UPLOAD_ENABLED=true` will enable the video upload feature. In the background, it will create a pipefile with file and destination for uploader to consume and proceed.

`SE_VIDEO_INTERNAL_UPLOAD=true` will use RCLONE installed in the container for upload. If you want to use another container for upload, set it to `false`.

For environment variables with prefix `RCLONE_` is used to pass remote configuration to RCLONE. You can find more information about RCLONE configuration [here](https://rclone.org/docs/).

[`docker-compose-v3-video-upload.yml`](docker-compose-v3-video-upload.yml)

Note that upload function is not supported for Dynamic Grid. If you want it, please create a feature request.

___

## Dynamic Grid
Expand Down Expand Up @@ -1336,4 +1391,11 @@ 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!

### Mounting volumes to retrieve video files

Similar to mount volumes to retrieve downloaded files. For video files, you might need to do the same

```bash
mkdir /tmp/videos
chown 1200:1201 /tmp/videos
```
12 changes: 0 additions & 12 deletions Uploader/Dockerfile

This file was deleted.

21 changes: 17 additions & 4 deletions Video/Dockerfile
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ ARG BASED_TAG
FROM $NAMESPACE/ffmpeg:$BASED_TAG
LABEL authors="Selenium <selenium-developers@googlegroups.com>"

ARG RCLONE_VERSION=current
#Arguments to define the user running the container
ARG SEL_USER=seluser
ARG SEL_GROUP=${SEL_USER}
Expand All @@ -29,7 +30,7 @@ ENV DEBIAN_FRONTEND=noninteractive \
RUN apt-get -qqy update \
&& apt-get upgrade -yq \
&& apt-get -qqy --no-install-recommends install \
supervisor x11-xserver-utils x11-utils curl jq python3-pip tzdata acl \
supervisor x11-xserver-utils x11-utils curl jq python3-pip tzdata acl unzip \
&& python3 -m pip install --upgrade pip \
&& python3 -m pip install --upgrade setuptools \
&& python3 -m pip install --upgrade wheel \
Expand Down Expand Up @@ -71,7 +72,20 @@ RUN groupadd ${SEL_GROUP} \
# Add Supervisor configuration files
#======================================
COPY supervisord.conf /etc
COPY --chown="${SEL_UID}:${SEL_GID}" entry_point.sh video.sh video_ready.py /opt/bin/
COPY --chown="${SEL_UID}:${SEL_GID}" entry_point.sh video.sh video_ready.py video_graphQLQuery.sh /opt/bin/

#======================================
# Add RCLONE for uploading videos
#======================================
RUN curl -fLo /tmp/rclone.zip https://downloads.rclone.org/rclone-${RCLONE_VERSION}-linux-amd64.zip \
&& unzip -a /tmp/rclone.zip -d /tmp \
&& mv /tmp/rclone-*-linux-amd64/rclone /usr/local/bin/ \
&& rm -rf /tmp/rclone-*
COPY --chown="${SEL_UID}:${SEL_GID}" upload.sh upload.conf /opt/bin/
ENV SE_VIDEO_UPLOAD_ENABLED false
ENV SE_UPLOAD_DESTINATION_PREFIX ""
ENV SE_VIDEO_INTERNAL_UPLOAD false
ENV UPLOAD_OPTS "-P"

ENV SE_VIDEO_FOLDER /videos
RUN mkdir -p /var/run/supervisor /var/log/supervisor $SE_VIDEO_FOLDER \
Expand All @@ -82,7 +96,6 @@ RUN mkdir -p /var/run/supervisor /var/log/supervisor $SE_VIDEO_FOLDER \
&& setfacl -Rdm u:${SEL_USER}:rwx,g:${SEL_GROUP}:rwx /var/run/supervisor /var/log/supervisor $SE_VIDEO_FOLDER $HOME

USER ${SEL_UID}
VOLUME ${SE_VIDEO_FOLDER}

ENTRYPOINT ["/opt/bin/entry_point.sh"]
CMD ["/opt/bin/entry_point.sh"]
Expand All @@ -94,6 +107,6 @@ ENV SE_SCREEN_HEIGHT 1020
ENV SE_FRAME_RATE 15
ENV SE_CODEC libx264
ENV SE_PRESET "-preset ultrafast"
ENV FILE_NAME video.mp4
ENV SE_VIDEO_FILE_NAME video.mp4

EXPOSE 9000
12 changes: 12 additions & 0 deletions Video/supervisord.conf
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,15 @@ stopsignal=INT
redirect_stderr=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0

[program:video-upload]
priority=10
command=bash -c "if [ ${SE_VIDEO_INTERNAL_UPLOAD} = "true" ]; then /opt/bin/upload.sh; fi"
autostart=%(ENV_SE_VIDEO_INTERNAL_UPLOAD)s
autorestart=%(ENV_SE_VIDEO_INTERNAL_UPLOAD)s
stopsignal=INT

;Logs (all activity redirected to stdout so it can be seen through "docker logs"
redirect_stderr=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
Empty file added Video/upload.conf
Empty file.