Skip to content

Commit f928f6f

Browse files
committed
K8s: Fix deployment config error in video-manager
Signed-off-by: Viet Nguyen Duc <[email protected]>
1 parent b2cede1 commit f928f6f

20 files changed

+237
-20
lines changed

.github/workflows/helm-chart-test.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565
docker-version: '26.1.4'
6666
python-version: '3.9'
6767
test-upgrade: true
68-
service-mesh: true
68+
service-mesh: false
6969
os: ubuntu-22.04
7070
check-records-output: true
7171
test-strategy: job
@@ -115,7 +115,7 @@ jobs:
115115
docker-version: '26.1.4'
116116
python-version: '3.10'
117117
test-upgrade: true
118-
service-mesh: true
118+
service-mesh: false
119119
os: ubuntu-22.04
120120
check-records-output: true
121121
test-strategy: playwright_connect_grid
@@ -126,7 +126,7 @@ jobs:
126126
python-version: '3.10'
127127
test-upgrade: true
128128
service-mesh: true
129-
os: blacksmith-8vcpu-ubuntu-2204
129+
os: ubuntu-22.04
130130
check-records-output: false
131131
test-strategy: job_relay
132132
env:

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ BASE_RELEASE := $(or $(BASE_RELEASE),$(BASE_RELEASE),selenium-4.32.0)
55
BASE_VERSION := $(or $(BASE_VERSION),$(BASE_VERSION),4.32.0)
66
BINDING_VERSION := $(or $(BINDING_VERSION),$(BINDING_VERSION),4.32.0)
77
BASE_RELEASE_NIGHTLY := $(or $(BASE_RELEASE_NIGHTLY),$(BASE_RELEASE_NIGHTLY),nightly)
8-
BASE_VERSION_NIGHTLY := $(or $(BASE_VERSION_NIGHTLY),$(BASE_VERSIO3_NIGHTLY),4.33.0-SNAPSHOT)
8+
BASE_VERSION_NIGHTLY := $(or $(BASE_VERSION_NIGHTLY),$(BASE_VERSION_NIGHTLY),4.33.0-SNAPSHOT)
99
VERSION := $(or $(VERSION),$(VERSION),4.32.0)
1010
MVN_SELENIUM_VERSION := $(or $(MVN_SELENIUM_VERSION),$(MVN_SELENIUM_VERSION),4.32.0)
1111
TAG_VERSION := $(VERSION)-$(BUILD_DATE)

README.md

+39
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,43 @@ When using in Dynamic Grid, those variables should be combined with the prefix `
707707
| `SE_UPLOAD_CONFIG_FILE_NAME` | `upload.conf` | Config file for remote host instead of set via env variable prefix SE_RCLONE_* |
708708
| `SE_UPLOAD_CONFIG_DIRECTORY` | `/opt/bin` | Directory of config file (change it when conf file in another directory is mounted) |
709709

710+
## Video recordings manager
711+
712+
We utilize [File Browser](https://filebrowser.org/) as a video manager. It is a web-based file manager that allows you to manage files and folders in the storage.
713+
714+
The File Browser container dir `/srv` should be mounted to the same storage as video recordings stored. For example a compose file:
715+
716+
```yaml
717+
services:
718+
chrome:
719+
deploy:
720+
mode: replicated
721+
replicas: 3
722+
image: selenium/node-chrome:4.32.0-20250505
723+
platform: linux/amd64
724+
shm_size: 2gb
725+
depends_on:
726+
- selenium-hub
727+
volumes:
728+
- /tmp/videos:/videos
729+
environment:
730+
- SE_EVENT_BUS_HOST=selenium-hub
731+
- SE_RECORD_VIDEO=true
732+
- SE_VIDEO_FILE_NAME=auto
733+
- SE_NODE_GRID_URL=http://selenium-hub:4444
734+
735+
file_browser:
736+
image: filebrowser/filebrowser:latest
737+
container_name: file_browser
738+
restart: always
739+
ports:
740+
- "8081:80"
741+
volumes:
742+
- /tmp/videos:/srv
743+
environment:
744+
- FB_NOAUTH=true
745+
```
746+
710747
___
711748

712749
## Dynamic Grid
@@ -1010,6 +1047,8 @@ Get started to deploy Selenium Grid on Kubernetes, you can refer to YAML files i
10101047
To simplify the deployment process, hide the complexity of Kubernetes objects, and provide a more straightforward way to deploy Selenium Grid on Kubernetes, we offer a Helm chart to deploy Selenium Grid to Kubernetes.
10111048
Read more details at the Helm [chart README](./charts/selenium-grid/README.md) and [chart CONFIGURATION](./charts/selenium-grid/CONFIGURATION.md).
10121049

1050+
- Get started to hands-on with Selenium Grid on Kubernetes. See local env setup with [Docker Desktop](./tests/charts/refValues/README.md).
1051+
10131052
___
10141053

10151054
## Configuring the containers

charts/selenium-grid/.helmignore

+2
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,5 @@
2323
.vscode/
2424
ci/
2525
certs/add-*-helper.sh
26+
CHANGELOG.md
27+
TESTING.md

charts/selenium-grid/CONFIGURATION.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ A Helm chart for creating a Selenium Grid Server in Kubernetes
689689
| videoManager.imageTag | string | `"latest"` | File browser image tag (this overwrites global.seleniumGrid.imageTag parameter) |
690690
| videoManager.imagePullPolicy | string | `"IfNotPresent"` | Image pull policy (see https://kubernetes.io/docs/concepts/containers/images/#updating-images) |
691691
| videoManager.imagePullSecret | string | `""` | Image pull secret (see https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) |
692-
| videoManager.config.baseurl | string | `"recordings"` | Base URL use to access the file browser (e.g. http://public.ip/recordings) |
692+
| videoManager.config.baseurl | string | `"/recordings"` | Base URL use to access the file browser (in case expose both Grid and file browser via ingress, e.g. Grid at http://public.ip/selenium and FB at http://public.ip/recordings) |
693693
| videoManager.config.username | string | `""` | Username for the first user when using quick config (default "admin") |
694694
| videoManager.config.password | string | `""` | Hashed password (bcrypt) for the first user when using quick config (default "admin") |
695695
| videoManager.config.noauth | bool | `true` | Use the noauth auther when using quick setup |

charts/selenium-grid/README.md

+40
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ This chart enables the creation of a Selenium Grid Server in Kubernetes.
3636
* [Configuration of video recorder and video uploader](#configuration-of-video-recorder-and-video-uploader)
3737
* [Video recorder](#video-recorder)
3838
* [Video uploader](#video-uploader)
39+
* [Video manager](#video-manager)
3940
* [Configuration of Secure Communication](#configuration-of-secure-communication)
4041
* [Create TLS Secret](#create-tls-secret)
4142
* [Secure Connection to Selenium Grid components](#secure-connection-to-selenium-grid-components)
@@ -793,6 +794,45 @@ videoRecorder:
793794
imageTag: latest
794795
```
795796

797+
#### Video manager
798+
799+
We utilize [File Browser](https://filebrowser.org/) as a video manager. It is a web-based file manager that allows you to manage files and folders in the storage. The video manager is disabled by default. To enable it, you need to set config key `videoManager.enabled` to `true`.
800+
801+
The service can be exposed via NodePort or Ingress (if enabled global ingress). By default, there is a baseurl is `/recordings`, if enabled svc type NodePort: `http://<node-ip>:30080/recordings`, or ingress `http://<ingress-hostname>/recordings`. You also can change the baseurl to another value via config key `videoManager.config.baseurl`
802+
803+
804+
The File Browser container dir `/srv` should be mounted to the same storage as video recordings stored. The storage here is persistent volume claim (PVC) that is created by you or dynamically provisioned by the storage class. Configure recorder and manager to use the same PVC. For example
805+
806+
```yaml
807+
videoRecorder:
808+
enabled: true
809+
extraVolumeMounts:
810+
- name: videos
811+
mountPath: /videos
812+
subPath: videos
813+
extraVolumes:
814+
- name: videos
815+
persistentVolumeClaim:
816+
claimName: local-pv-storage
817+
818+
videoManager:
819+
enabled: true
820+
extraVolumeMounts:
821+
- name: videos
822+
mountPath: /srv
823+
subPath: videos
824+
extraVolumes:
825+
- name: videos
826+
persistentVolumeClaim:
827+
claimName: local-pv-storage
828+
```
829+
830+
When configuration is done, via File Browser you can centralize all the recordings in one place. You can manage the recordings, delete them, or download them.
831+
832+
![img_1.png](./images/video-manager_1.png)
833+
834+
![img_2.png](./images/video-manager_2.png)
835+
796836
### Configuration of Secure Communication
797837

798838
Selenium Grid supports secure communication between components. Refer to the [instructions](https://github.com/SeleniumHQ/selenium/blob/trunk/java/src/org/openqa/selenium/grid/commands/security.txt) and [options](https://www.selenium.dev/documentation/grid/configuration/cli_options/#server) are able to configure the secure communication. Below is the details on how to enable secure communication in Selenium Grid chart.
60.5 KB
Loading
Loading

charts/selenium-grid/templates/chrome-node-scaledjobs.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{{- range $i, $newNode := .Values.crossBrowsers.chromeNode }}
22
{{- $nodeConfig := merge $newNode $.Values.chromeNode -}}
3-
{{- if and $nodeConfig.enabled (include "seleniumGrid.useKEDA" $) (eq $.Values.autoscaling.scalingType "job") }}
3+
{{- if and $nodeConfig.enabled (eq (include "seleniumGrid.useKEDA" $) "true") (eq $.Values.autoscaling.scalingType "job") }}
44
apiVersion: keda.sh/v1alpha1
55
kind: ScaledJob
66
metadata:

charts/selenium-grid/templates/relay-node-scaledjobs.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{{- range $i, $newNode := .Values.crossBrowsers.relayNode }}
22
{{- $nodeConfig := merge $newNode $.Values.relayNode -}}
3-
{{- if and $nodeConfig.enabled (include "seleniumGrid.useKEDA" $) (eq $.Values.autoscaling.scalingType "job") }}
3+
{{- if and $nodeConfig.enabled (eq (include "seleniumGrid.useKEDA" $) "true") (eq $.Values.autoscaling.scalingType "job") }}
44
apiVersion: keda.sh/v1alpha1
55
kind: ScaledJob
66
metadata:

charts/selenium-grid/templates/video-manager/file-browser-ingress.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ spec:
5353
name: {{ include "seleniumGrid.videoManager.fullname" $ | quote }}
5454
port:
5555
number: 80
56-
path: {{ printf "/%s" $.Values.videoManager.config.baseurl | quote }}
56+
path: {{ $.Values.videoManager.config.baseurl | quote }}
5757
pathType: Prefix
5858
{{- end }}
5959
{{- end }}

charts/selenium-grid/values.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -2056,8 +2056,8 @@ videoManager:
20562056
# -- Image pull secret (see https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/)
20572057
imagePullSecret: ""
20582058
config:
2059-
# -- Base URL use to access the file browser (e.g. http://public.ip/recordings)
2060-
baseurl: "recordings"
2059+
# -- Base URL use to access the file browser (in case expose both Grid and file browser via ingress, e.g. Grid at http://public.ip/selenium and FB at http://public.ip/recordings)
2060+
baseurl: "/recordings"
20612061
# -- Username for the first user when using quick config (default "admin")
20622062
username: ""
20632063
# -- Hashed password (bcrypt) for the first user when using quick config (default "admin")

tests/CDPTests/bootstrap.sh

+8-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ BROWSER=${1:-"chrome"}
1010
SELENIUM_REMOTE_URL="${SELENIUM_GRID_PROTOCOL}://${SELENIUM_GRID_HOST}:${SELENIUM_GRID_PORT}"
1111
echo "SELENIUM_REMOTE_URL=${SELENIUM_REMOTE_URL}" > .env
1212

13-
if [ -n ${SELENIUM_GRID_USERNAME} ] && [ -n ${SELENIUM_GRID_PASSWORD} ]; then
13+
if [ -n "${SELENIUM_GRID_USERNAME}" ] && [ -n "${SELENIUM_GRID_PASSWORD}" ]; then
1414
BASIC_AUTH="$(echo -en "${SELENIUM_GRID_USERNAME}:${SELENIUM_GRID_PASSWORD}" | base64 -w0)"
1515
echo "SELENIUM_REMOTE_HEADERS={\"Authorization\": \"Basic ${BASIC_AUTH}\"}" >> .env
1616
BASIC_AUTH="Authorization: Basic ${BASIC_AUTH}"
@@ -21,7 +21,14 @@ echo "NODE_EXTRA_CA_CERTS=${CHART_CERT_PATH}" >> .env
2121

2222
cat .env
2323

24+
start_time=$(date +%s)
2425
until [ "$(curl --noproxy "*" -sk -H "${BASIC_AUTH}" -o /dev/null -w "%{http_code}" "${SELENIUM_REMOTE_URL}/status")" = "200" ]; do
26+
current_time=$(date +%s)
27+
elapsed_time=$((current_time - start_time))
28+
if [ $elapsed_time -ge 400 ]; then
29+
echo "Timeout reached: Grid is not ready after 5 minutes."
30+
exit 1
31+
fi
2532
echo "Waiting for Grid to be ready..."
2633
sleep 1
2734
done

tests/charts/make/chart_cluster_setup.sh

+3-1
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,18 @@ if [ "${CLUSTER}" = "kind" ]; then
4242
echo "Start Kind cluster"
4343
kind create cluster --image kindest/node:${KUBERNETES_VERSION} --wait ${WAIT_TIMEOUT} --name ${CLUSTER_NAME} --config tests/charts/config/kind-cluster.yaml
4444
elif [ "${CLUSTER}" = "minikube" ]; then
45+
HOST_IP="$(hostname -I | cut -d' ' -f1)"
4546
echo "Start Minikube cluster"
4647
sudo chmod 777 /tmp
4748
export CHANGE_MINIKUBE_NONE_USER=true
48-
sudo -SE minikube start --vm-driver=none \
49+
NO_PROXY="$NO_PROXY,$HOST_IP" sudo -SE minikube start --vm-driver=none \
4950
--kubernetes-version=${KUBERNETES_VERSION} --network-plugin=cni --cni=${CNI} --container-runtime=${CONTAINER_RUNTIME} --wait=all
5051
sudo chown -R $USER $HOME/.kube $HOME/.minikube
5152
if [ "${SERVICE_MESH}" = "true" ]; then
5253
minikube addons enable istio-provisioner
5354
minikube addons enable istio
5455
fi
56+
kubectl set env daemonset/calico-node -n kube-system IP_AUTODETECTION_METHOD="can-reach=${HOST_IP}"
5557
fi
5658

5759
if [ "${CLUSTER}" = "kind" ]; then

tests/charts/make/chart_test.sh

+4-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,10 @@ on_failure() {
106106
if [ ${RENDER_HELM_TEMPLATE_ONLY} = "true" ]; then
107107
exit $exit_status
108108
fi
109-
kubectl get pods -A
109+
kubectl get pods -n "${SELENIUM_NAMESPACE}" -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\n' | while read pod; do
110+
echo "Logs for pod $pod"
111+
kubectl logs -n "${SELENIUM_NAMESPACE}" "$pod" --all-containers --tail=10000
112+
done
110113
echo "Get all resources in all namespaces"
111114
kubectl get all -A >> tests/tests/describe_all_resources_${MATRIX_BROWSER}.txt
112115
echo "Describe all resources in the ${SELENIUM_NAMESPACE} namespace for debugging purposes"

tests/charts/refValues/README.md

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<!-- TOC -->
2+
* [Introduction](#introduction)
3+
* [Docker Desktop](#docker-desktop)
4+
* [Install Required Software](#install-required-software)
5+
* [Configure Kubernetes cluster in Docker Desktop](#configure-kubernetes-cluster-in-docker-desktop)
6+
* [Deploy Selenium Grid solution using Helm chart](#deploy-selenium-grid-solution-using-helm-chart)
7+
* [Deploy PVC for video recording and video manager storage.](#deploy-pvc-for-video-recording-and-video-manager-storage)
8+
* [Add Docker Selenium Helm chart repository](#add-docker-selenium-helm-chart-repository)
9+
* [Install latest chart with reference values.](#install-latest-chart-with-reference-values)
10+
* [Verify Grid installation](#verify-grid-installation)
11+
* [Browser Nodes in autoscaling from zero mode.](#browser-nodes-in-autoscaling-from-zero-mode)
12+
* [Run a test in Grid](#run-a-test-in-grid)
13+
<!-- TOC -->
14+
15+
# Introduction
16+
17+
This directory contains the reference values for the Helm charts in the `charts` directory. The reference values are used to test the Helm charts and ensure that they are working correctly. The reference values are stored in YAML files, which can be used to generate the expected output of the Helm charts.
18+
19+
# Docker Desktop
20+
21+
## Install Required Software
22+
23+
_Note: This guide is for macOS. For other operating systems, please refer to particular tool documentation._
24+
```sh
25+
brew install docker kubectl helm
26+
```
27+
28+
Verify the installation
29+
```sh
30+
java -version
31+
docker --version
32+
kubectl version --client
33+
helm version
34+
```
35+
36+
## Configure Kubernetes cluster in Docker Desktop
37+
38+
Most users are able to installed Docker Desktop and start Kubernetes cluster in settings as below.
39+
40+
![img.png](images/docker-desktop-1.png)
41+
42+
If you are having a local machine with good resources, configure Docker Desktop to use more resources. Then you can install orchestration containers with autoscaling capability.
43+
44+
![img_1.png](images/docker-desktop-2.png)
45+
46+
Open a terminal, ensure `kubectl` is able to connect to the cluster
47+
48+
```sh
49+
kubectl cluster-info
50+
```
51+
52+
## Deploy Selenium Grid solution using Helm chart
53+
54+
#### Deploy PVC for video recording and video manager storage.
55+
56+
Checkout file [local-pvc-docker-desktop.yaml](local-pvc-docker-desktop.yaml)
57+
58+
```sh
59+
kubectl apply -f local-pvc-docker-desktop.yaml
60+
```
61+
62+
#### Add Docker Selenium Helm chart repository
63+
64+
```sh
65+
helm repo add docker-selenium https://www.selenium.dev/docker-selenium
66+
helm repo update
67+
```
68+
69+
#### Install latest chart with reference values.
70+
71+
Checkout file [simplex-docker-desktop.yaml](simplex-docker-desktop.yaml)
72+
73+
```sh
74+
helm upgrade -i selenium docker-selenium/selenium-grid \
75+
--namespace default \
76+
-f simplex-docker-desktop.yaml
77+
```
78+
79+
#### Verify Grid installation
80+
81+
- Grid components in cluster: `kubectl get pod -n default`
82+
- Grid UI: [http://localhost/selenium](http://localhost/selenium)
83+
- Recordings manager: [http://localhost/recordings](http://localhost/recordings)
84+
85+
#### Browser Nodes in autoscaling from zero mode.
86+
87+
There is no Node visible on Grid UI. The browser nodes are created on demand when a test is started. The browser nodes are automatically removed when the test is finished.
88+
89+
#### Run a test in Grid
90+
91+
Refer to [get_started.py](../../get_started.py) for a simple test using Python and Selenium. The test will run remotely on the Grid.
92+
93+
- Check the Grid UI to see the test running.
94+
- Check the Recordings manager to see the video recording of the test.
95+
- Check if the test passed or failed.
Loading
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: v1
2+
kind: PersistentVolumeClaim
3+
metadata:
4+
name: local-pv-storage
5+
namespace: default
6+
spec:
7+
accessModes:
8+
- "ReadWriteOnce"
9+
resources:
10+
requests:
11+
storage: "2Gi"
12+
storageClassName: hostpath
13+
---

0 commit comments

Comments
 (0)