Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ansible/configure-selenium-grid-local-oracle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@
cloud: "oracle"
- { role: "jitsi-torture-assets", tags: "torture-assets", when: selenium_grid_enable_nomad == "true" }
- { role: "consul-agent", tags: "consul", consul_install_flag: false, when: selenium_grid_enable_nomad == "true"}
- { role: "autoscaler-sidecar", tags: "autoscaler-sidecar",
autoscaler_instance_type: "selenium-grid", cloud_provider: "oracle", autoscaler_install_flag: false, autoscaler_configure_flag: true, when: nomad_enable_jitsi_autoscaler == "true"}
- { role: "docker-daemon-config", tags: "docker-daemon-config", when: selenium_grid_enable_nomad == "true" }
- { role: "docker-auth-config", tags: "docker-auth-config", docker_ecr_credentials: "{{ nomad_docker_ecr_credentials }}", when: selenium_grid_enable_nomad == "true" }
- { role: "nomad-jitsi", tags: "nomad-jitsi", when: selenium_grid_enable_nomad == "true" }
Expand Down
2 changes: 1 addition & 1 deletion ansible/nomad-client.yml
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@
- { role: "journald", tags: "journald"}
- { role: "rsyslog", rsyslog_install_flag: false, tags: "rsyslog", rsyslog_tcp_output_enabled: true}
- { role: "autoscaler-sidecar", tags: "autoscaler-sidecar",
autoscaler_instance_type: "nomad", cloud_provider: "oracle", autoscaler_install_flag: false, autoscaler_configure_flag: true, when: nomad_enable_jitsi_autoscaler}
autoscaler_instance_type: "nomad", cloud_provider: "oracle", autoscaler_install_flag: false, autoscaler_configure_flag: true, when: nomad_enable_jitsi_autoscaler == "true"}
- { role: "consul-agent", tags: "consul", consul_install_flag: false}
- { role: "nvidia-docker", tags: "nvidia-docker", when: nvidia_docker_flag }
- { role: "docker-daemon-config", tags: "docker-daemon-config" }
Expand Down
12 changes: 12 additions & 0 deletions ansible/roles/autoscaler-sidecar/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ autoscaler_force_shutdown_command_by_type:
'jigasi': 'service jigasi stop'
'sip-jibri': 'service jibri stop'
'nomad': 'nomad node drain -self -enable -force -detach -yes'
'selenium-grid': 'nomad node drain -self -enable -force -detach -yes'
autoscaler_git_repo: https://github.com/jitsi/jitsi-autoscaler-sidecar.git
autoscaler_graceful_shutdown_script: "{{
autoscaler_graceful_shutdown_scripts[autoscaler_instance_type]
Expand All @@ -26,6 +27,7 @@ autoscaler_graceful_shutdown_scripts:
'jigasi': /usr/local/bin/graceful-shutdown-wrapper-jigasi.sh
'sip-jibri': /opt/jitsi/jibri/wait_graceful_shutdown.sh
'nomad': /usr/local/bin/nomad_graceful_shutdown.sh
'selenium-grid': /usr/local/bin/graceful_shutdown_selenium_grid.sh
autoscaler_graceful_shutdown_wrapper: /usr/local/bin/graceful_shutdown_wrapper.sh
autoscaler_group: "default"
autoscaler_groupname: jsidecar
Expand Down Expand Up @@ -67,6 +69,15 @@ autoscaler_sidecar_instance_version_command_by_type:
'jigasi': "dpkg -s jigasi | grep Version | awk '{print $2}' | sed 's/..$//'"
'sip-jibri': "dpkg -s jibri | grep Version | awk '{print $2}' | sed 's/..$//'"
'nomad': "nomad --version | head -1 | cut -d' ' -f2 | tr -d 'v'"
'selenium-grid': >-
NODE_ID=$(curl -s http://localhost:4646/v1/agent/self |
jq -r '.stats.client.node_id') &&
JOB_ID=$(curl -s http://localhost:4646/v1/node/$NODE_ID/allocations |
jq -r '[.[] | select(.JobID | contains("grid-node")) |
select(.ClientStatus=="running")][0].JobID') &&
curl -s http://localhost:4646/v1/job/$JOB_ID |
jq -r '.TaskGroups[].Tasks[].Config.image' |
head -1 | rev | cut -d: -f1 | rev
autoscaler_sidecar_private_ip: "{{ ansible_default_ipv4.address }}"
autoscaler_sidecar_public_ip: "{{ ansible_ec2_public_ipv4 if ansible_ec2_public_ipv4 is defined else false }}"
autoscaler_sidecar_service_name: jitsi-autoscaler-sidecar
Expand All @@ -80,6 +91,7 @@ autoscaler_stats_retrieve_urls:
'jibri': http://localhost:2222/jibri/api/v1.0/health
'jigasi': http://localhost:8788/about/stats
'sip-jibri': http://localhost:2222/jibri/api/v1.0/health
'selenium-grid': http://localhost:4444/status
autoscaler_status_url: "https://{{ autoscaler_server_host }}/sidecar/status"
autoscaler_shutdown_url: "https://{{ autoscaler_server_host }}/sidecar/shutdown"
autoscaler_terminate_script: '/usr/local/bin/terminate_instance.sh'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/bash

# Graceful shutdown for selenium-grid nodes running under nomad
# 1. Drain the Selenium Grid 4 node (stop accepting new sessions, wait for existing to finish)
# 2. Then perform the normal nomad graceful shutdown

SELENIUM_NODE_PORT=${SELENIUM_NODE_PORT:-5555}
SELENIUM_DRAIN_URL="http://localhost:${SELENIUM_NODE_PORT}/se/grid/node/drain"
SELENIUM_STATUS_URL="http://localhost:${SELENIUM_NODE_PORT}/status"
SELENIUM_DRAIN_TIMEOUT=${SELENIUM_DRAIN_TIMEOUT:-300}
SLEEP_TIME=10

echo "Starting selenium-grid graceful shutdown"

# Step 1: Issue drain command to the selenium grid node
echo "Sending drain request to Selenium Grid node at ${SELENIUM_DRAIN_URL}"
DRAIN_RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -X POST "${SELENIUM_DRAIN_URL}")

if [[ "$DRAIN_RESPONSE" == "200" ]]; then
echo "Drain request accepted by Selenium Grid node"
else
echo "Warning: Drain request returned HTTP ${DRAIN_RESPONSE}, continuing with shutdown"
fi

# Step 2: Wait for active sessions to complete
echo "Waiting for active sessions to drain (timeout: ${SELENIUM_DRAIN_TIMEOUT}s)"
ELAPSED=0
while [[ $ELAPSED -lt $SELENIUM_DRAIN_TIMEOUT ]]; do
STATUS=$(curl -s "${SELENIUM_STATUS_URL}" 2>/dev/null)
if [[ $? -ne 0 ]]; then
echo "Node status endpoint unreachable, assuming drained"
break
fi

# Check if node has any active sessions
ACTIVE_SESSIONS=$(echo "$STATUS" | jq -r '.value.node.slots // [] | map(select(.session != null)) | length' 2>/dev/null)
if [[ $? -ne 0 ]] || [[ -z "$ACTIVE_SESSIONS" ]]; then
echo "Could not parse session count, assuming drained"
break
fi

if [[ "$ACTIVE_SESSIONS" -eq 0 ]]; then
echo "All sessions drained from Selenium Grid node"
break
fi

echo "Still waiting for ${ACTIVE_SESSIONS} active session(s) to complete... (${ELAPSED}s/${SELENIUM_DRAIN_TIMEOUT}s)"
sleep $SLEEP_TIME
ELAPSED=$((ELAPSED + SLEEP_TIME))
done

if [[ $ELAPSED -ge $SELENIUM_DRAIN_TIMEOUT ]]; then
echo "Selenium drain timeout reached after ${SELENIUM_DRAIN_TIMEOUT}s, proceeding with nomad shutdown"
fi

# Step 3: Proceed with normal nomad graceful shutdown
echo "Starting nomad graceful shutdown"
/usr/local/bin/nomad_graceful_shutdown.sh
exit $?
7 changes: 7 additions & 0 deletions ansible/roles/autoscaler-sidecar/tasks/configure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@
regexp: "^%{{ autoscaler_groupname }}"
line: "%{{ autoscaler_groupname }} ALL=(ALL) NOPASSWD: ALL"

- name: Copy selenium-grid graceful shutdown script
ansible.builtin.copy:
dest: /usr/local/bin/graceful_shutdown_selenium_grid.sh
src: "graceful_shutdown_selenium_grid.sh"
mode: 0755
when: autoscaler_instance_type == 'selenium-grid'

- name: Copy graceful shutdown wrapper script
ansible.builtin.template:
dest: "{{ autoscaler_graceful_shutdown_wrapper }}"
Expand Down
1 change: 1 addition & 0 deletions ansible/roles/jitsi-torture-assets/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
repo: "{{ jitsi_torture_assets_git_repo }}"
version: "{{ jitsi_torture_assets_git_branch }}"
dest: "{{ jitsi_torture_assets_path }}"
force: true

- name: Ensure directory for assets
ansible.builtin.file:
Expand Down