Skip to content

Commit

Permalink
feat: video upload supports both docker-compose and helm chart (#2131)
Browse files Browse the repository at this point in the history
* feat: add RCLONE to video recorder image

Signed-off-by: Viet Nguyen Duc <nguyenducviet4496@gmail.com>

* breaking-change(chart): config for video uploader

After RCLONE is installed and upload scripts is moved to built-in recorder image, by default no need the third sidecar container for uploader.
If not using default RCLONE, user is able to configure for the third container with their settings

Signed-off-by: Viet Nguyen Duc <nguyenducviet4496@gmail.com>

* feat: add docker-compose video upload

Signed-off-by: Viet Nguyen Duc <nguyenducviet4496@gmail.com>

---------

Signed-off-by: Viet Nguyen Duc <nguyenducviet4496@gmail.com>
  • Loading branch information
VietND96 committed Feb 11, 2024
1 parent 6eab711 commit b1d36d5
Show file tree
Hide file tree
Showing 29 changed files with 688 additions and 357 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/helm-chart-test.yml
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
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
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
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
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.

0 comments on commit b1d36d5

Please sign in to comment.