Name: valkey-scripts Namespace: openstack Labels: app.kubernetes.io/instance=valkey app.kubernetes.io/managed-by=Helm app.kubernetes.io/name=valkey app.kubernetes.io/part-of=valkey app.kubernetes.io/version=8.0.2 helm.sh/chart=valkey-2.4.6 Annotations: meta.helm.sh/release-name: valkey meta.helm.sh/release-namespace: openstack Data ==== prestop-sentinel.sh: ---- #!/bin/bash . /opt/bitnami/scripts/libvalidations.sh . /opt/bitnami/scripts/libos.sh HEADLESS_SERVICE="valkey-headless.openstack.svc.cluster.local" get_full_hostname() { hostname="$1" full_hostname="${hostname}.${HEADLESS_SERVICE}" echo "${full_hostname}" } run_sentinel_command() { if is_boolean_yes "$VALKEY_SENTINEL_TLS_ENABLED"; then valkey-cli -h "$VALKEY_SERVICE" -p "$VALKEY_SENTINEL_TLS_PORT_NUMBER" --tls --cert "$VALKEY_SENTINEL_TLS_CERT_FILE" --key "$VALKEY_SENTINEL_TLS_KEY_FILE" --cacert "$VALKEY_SENTINEL_TLS_CA_FILE" sentinel "$@" else valkey-cli -h "$VALKEY_SERVICE" -p "$VALKEY_SENTINEL_PORT" sentinel "$@" fi } sentinel_failover_finished() { VALKEY_SENTINEL_INFO=($(run_sentinel_command get-primary-addr-by-name "atmosphere")) VALKEY_PRIMARY_HOST="${VALKEY_SENTINEL_INFO[0]}" [[ "$VALKEY_PRIMARY_HOST" != "$(get_full_hostname $HOSTNAME)" ]] } VALKEY_SERVICE="valkey.openstack.svc.cluster.local" if ! sentinel_failover_finished; then echo "I am the primary pod and you are stopping me. Starting sentinel failover" if retry_while "sentinel_failover_finished" "20" 1; then echo "Primary has been successfuly failed over to a different pod." exit 0 else echo "Primary failover failed" exit 1 fi else exit 0 fi prestop-valkey.sh: ---- #!/bin/bash . /opt/bitnami/scripts/libvalidations.sh . /opt/bitnami/scripts/libos.sh run_valkey_command() { if is_boolean_yes "$VALKEY_TLS_ENABLED"; then valkey-cli -h 127.0.0.1 -p "$VALKEY_TLS_PORT" --tls --cert "$VALKEY_TLS_CERT_FILE" --key "$VALKEY_TLS_KEY_FILE" --cacert "$VALKEY_TLS_CA_FILE" "$@" else valkey-cli -h 127.0.0.1 -p "$VALKEY_PORT" "$@" fi } is_primary() { VALKEY_ROLE=$(run_valkey_command role | head -1) [[ "$VALKEY_ROLE" == "master" ]] } HEADLESS_SERVICE="valkey-headless.openstack.svc.cluster.local" get_full_hostname() { hostname="$1" full_hostname="${hostname}.${HEADLESS_SERVICE}" echo "${full_hostname}" } run_sentinel_command() { if is_boolean_yes "$VALKEY_SENTINEL_TLS_ENABLED"; then env -u REDISCLI_AUTH valkey-cli -h "$VALKEY_SERVICE" -p "$VALKEY_SENTINEL_TLS_PORT_NUMBER" --tls --cert "$VALKEY_SENTINEL_TLS_CERT_FILE" --key "$VALKEY_SENTINEL_TLS_KEY_FILE" --cacert "$VALKEY_SENTINEL_TLS_CA_FILE" sentinel "$@" else env -u REDISCLI_AUTH valkey-cli -h "$VALKEY_SERVICE" -p "$VALKEY_SENTINEL_PORT" sentinel "$@" fi } sentinel_failover_finished() { VALKEY_SENTINEL_INFO=($(run_sentinel_command get-primary-addr-by-name "atmosphere")) VALKEY_PRIMARY_HOST="${VALKEY_SENTINEL_INFO[0]}" [[ "$VALKEY_PRIMARY_HOST" != "$(get_full_hostname $HOSTNAME)" ]] } VALKEY_SERVICE="valkey.openstack.svc.cluster.local" # valkey-cli automatically consumes credentials from the REDISCLI_AUTH variable [[ -n "$VALKEY_PASSWORD" ]] && export REDISCLI_AUTH="$VALKEY_PASSWORD" [[ -f "$VALKEY_PASSWORD_FILE" ]] && export REDISCLI_AUTH="$(< "${VALKEY_PASSWORD_FILE}")" if is_primary && ! sentinel_failover_finished; then echo "I am the primary pod and you are stopping me. Pausing client connections." # Pausing client write connections to avoid data loss run_valkey_command CLIENT PAUSE "22000" WRITE echo "Issuing failover" # if I am the primary, issue a command to failover once run_sentinel_command failover "atmosphere" echo "Waiting for sentinel to complete failover for up to 20s" retry_while "sentinel_failover_finished" "20" 1 else exit 0 fi start-node.sh: ---- #!/bin/bash . /opt/bitnami/scripts/libos.sh . /opt/bitnami/scripts/liblog.sh . /opt/bitnami/scripts/libvalidations.sh get_port() { hostname="$1" type="$2" port_var=$(echo "${hostname^^}_SERVICE_PORT_$type" | sed "s/-/_/g") port=${!port_var} if [ -z "$port" ]; then case $type in "SENTINEL") echo 26379 ;; "VALKEY") echo 6379 ;; esac else echo $port fi } get_full_hostname() { hostname="$1" full_hostname="${hostname}.${HEADLESS_SERVICE}" echo "${full_hostname}" } VALKEYPORT=$(get_port "$HOSTNAME" "VALKEY") HEADLESS_SERVICE="valkey-headless.openstack.svc.cluster.local" if [ -n "$VALKEY_EXTERNAL_PRIMARY_HOST" ]; then VALKEY_SERVICE="$VALKEY_EXTERNAL_PRIMARY_HOST" else VALKEY_SERVICE="valkey.openstack.svc.cluster.local" fi SENTINEL_SERVICE_PORT=$(get_port "valkey" "SENTINEL") validate_quorum() { if is_boolean_yes "$VALKEY_TLS_ENABLED"; then quorum_info_command="valkey-cli -h $VALKEY_SERVICE -p $SENTINEL_SERVICE_PORT --tls --cert ${VALKEY_TLS_CERT_FILE} --key ${VALKEY_TLS_KEY_FILE} --cacert ${VALKEY_TLS_CA_FILE} sentinel primary atmosphere" else quorum_info_command="valkey-cli -h $VALKEY_SERVICE -p $SENTINEL_SERVICE_PORT sentinel primary atmosphere" fi info "about to run the command: $quorum_info_command" eval $quorum_info_command | grep -Fq "s_down" } trigger_manual_failover() { if is_boolean_yes "$VALKEY_TLS_ENABLED"; then failover_command="valkey-cli -h $VALKEY_SERVICE -p $SENTINEL_SERVICE_PORT --tls --cert ${VALKEY_TLS_CERT_FILE} --key ${VALKEY_TLS_KEY_FILE} --cacert ${VALKEY_TLS_CA_FILE} sentinel failover atmosphere" else failover_command="valkey-cli -h $VALKEY_SERVICE -p $SENTINEL_SERVICE_PORT sentinel failover atmosphere" fi info "about to run the command: $failover_command" eval $failover_command } get_sentinel_primary_info() { if is_boolean_yes "$VALKEY_TLS_ENABLED"; then sentinel_info_command="timeout 90 valkey-cli -h $VALKEY_SERVICE -p $SENTINEL_SERVICE_PORT --tls --cert ${VALKEY_TLS_CERT_FILE} --key ${VALKEY_TLS_KEY_FILE} --cacert ${VALKEY_TLS_CA_FILE} sentinel get-primary-addr-by-name atmosphere" else sentinel_info_command="timeout 90 valkey-cli -h $VALKEY_SERVICE -p $SENTINEL_SERVICE_PORT sentinel get-primary-addr-by-name atmosphere" fi info "about to run the command: $sentinel_info_command" retry_while "eval $sentinel_info_command" 2 5 } [[ -f $VALKEY_PASSWORD_FILE ]] && export VALKEY_PASSWORD="$(< "${VALKEY_PASSWORD_FILE}")" [[ -f $VALKEY_PRIMARY_PASSWORD_FILE ]] && export VALKEY_PRIMARY_PASSWORD="$(< "${VALKEY_PRIMARY_PASSWORD_FILE}")" # check if there is a primary primary_in_persisted_conf="$(get_full_hostname "$HOSTNAME")" primary_port_in_persisted_conf="$VALKEY_PRIMARY_PORT_NUMBER" primary_in_sentinel="$(get_sentinel_primary_info)" valkeyRetVal=$? if [[ -f /opt/bitnami/valkey-sentinel/etc/sentinel.conf ]]; then primary_in_persisted_conf="$(awk '/monitor/ {print $4}' /opt/bitnami/valkey-sentinel/etc/sentinel.conf)" primary_port_in_persisted_conf="$(awk '/monitor/ {print $5}' /opt/bitnami/valkey-sentinel/etc/sentinel.conf)" info "Found previous primary ${primary_in_persisted_conf}:${primary_port_in_persisted_conf} in /opt/bitnami/valkey-sentinel/etc/sentinel.conf" debug "$(cat /opt/bitnami/valkey-sentinel/etc/sentinel.conf | grep monitor)" fi if [[ $valkeyRetVal -ne 0 ]]; then if [[ "$primary_in_persisted_conf" == "$(get_full_hostname "$HOSTNAME")" ]]; then # Case 1: No active sentinel and in previous sentinel.conf we were the primary --> PRIMARY info "Configuring the node as primary" export VALKEY_REPLICATION_MODE="primary" else # Case 2: No active sentinel and in previous sentinel.conf we were not primary --> REPLICA info "Configuring the node as replica" export VALKEY_REPLICATION_MODE="replica" VALKEY_PRIMARY_HOST=${primary_in_persisted_conf} VALKEY_PRIMARY_PORT_NUMBER=${primary_port_in_persisted_conf} fi else # Fetches current primary's host and port VALKEY_SENTINEL_INFO=($(get_sentinel_primary_info)) info "Current primary: VALKEY_SENTINEL_INFO=(${VALKEY_SENTINEL_INFO[0]},${VALKEY_SENTINEL_INFO[1]})" VALKEY_PRIMARY_HOST=${VALKEY_SENTINEL_INFO[0]} VALKEY_PRIMARY_PORT_NUMBER=${VALKEY_SENTINEL_INFO[1]} if [[ "$VALKEY_PRIMARY_HOST" == "$(get_full_hostname "$HOSTNAME")" ]]; then # Case 3: Active sentinel and primary it is this node --> PRIMARY info "Configuring the node as primary" export VALKEY_REPLICATION_MODE="primary" else # Case 4: Active sentinel and primary is not this node --> REPLICA info "Configuring the node as replica" export VALKEY_REPLICATION_MODE="replica" fi fi if [[ -n "$VALKEY_EXTERNAL_PRIMARY_HOST" ]]; then VALKEY_PRIMARY_HOST="$VALKEY_EXTERNAL_PRIMARY_HOST" VALKEY_PRIMARY_PORT_NUMBER="${VALKEY_EXTERNAL_PRIMARY_PORT}" fi if [[ -f /opt/bitnami/valkey/mounted-etc/replica.conf ]];then cp /opt/bitnami/valkey/mounted-etc/replica.conf /opt/bitnami/valkey/etc/replica.conf fi if [[ -f /opt/bitnami/valkey/mounted-etc/valkey.conf ]];then cp /opt/bitnami/valkey/mounted-etc/valkey.conf /opt/bitnami/valkey/etc/valkey.conf fi echo "" >> /opt/bitnami/valkey/etc/replica.conf echo "replica-announce-port $VALKEYPORT" >> /opt/bitnami/valkey/etc/replica.conf echo "replica-announce-ip $(get_full_hostname "$HOSTNAME")" >> /opt/bitnami/valkey/etc/replica.conf ARGS=("--port" "0") ARGS+=("--tls-port" "${VALKEY_TLS_PORT}") ARGS+=("--tls-cert-file" "${VALKEY_TLS_CERT_FILE}") ARGS+=("--tls-key-file" "${VALKEY_TLS_KEY_FILE}") ARGS+=("--tls-ca-cert-file" "${VALKEY_TLS_CA_FILE}") ARGS+=("--tls-auth-clients" "${VALKEY_TLS_AUTH_CLIENTS}") ARGS+=("--tls-replication" "yes") if [[ "$VALKEY_REPLICATION_MODE" = "replica" ]]; then ARGS+=("--replicaof" "${VALKEY_PRIMARY_HOST}" "${VALKEY_PRIMARY_PORT_NUMBER}") fi ARGS+=("--protected-mode" "no") ARGS+=("--include" "/opt/bitnami/valkey/etc/replica.conf") ARGS+=("--include" "/opt/bitnami/valkey/etc/valkey.conf") exec valkey-server "${ARGS[@]}" start-sentinel.sh: ---- #!/bin/bash . /opt/bitnami/scripts/libos.sh . /opt/bitnami/scripts/libvalidations.sh . /opt/bitnami/scripts/libfile.sh HEADLESS_SERVICE="valkey-headless.openstack.svc.cluster.local" VALKEY_SERVICE="valkey.openstack.svc.cluster.local" get_port() { hostname="$1" type="$2" port_var=$(echo "${hostname^^}_SERVICE_PORT_$type" | sed "s/-/_/g") port=${!port_var} if [ -z "$port" ]; then case $type in "SENTINEL") echo 26379 ;; "VALKEY") echo 6379 ;; esac else echo $port fi } get_full_hostname() { hostname="$1" full_hostname="${hostname}.${HEADLESS_SERVICE}" echo "${full_hostname}" } SERVPORT=$(get_port "$HOSTNAME" "SENTINEL") VALKEYPORT=$(get_port "$HOSTNAME" "VALKEY") SENTINEL_SERVICE_PORT=$(get_port "valkey" "SENTINEL") sentinel_conf_set() { local -r key="${1:?missing key}" local value="${2:-}" # Sanitize inputs value="${value//\\/\\\\}" value="${value//&/\\&}" value="${value//\?/\\?}" [[ "$value" = "" ]] && value="\"$value\"" replace_in_file "/opt/bitnami/valkey-sentinel/etc/prepare-sentinel.conf" "^#*\s*${key} .*" "${key} ${value}" false } sentinel_conf_add() { echo $'\n'"$@" >> "/opt/bitnami/valkey-sentinel/etc/prepare-sentinel.conf" } host_id() { echo "$1" | openssl sha1 | awk '{print $2}' } get_sentinel_primary_info() { if is_boolean_yes "$VALKEY_SENTINEL_TLS_ENABLED"; then sentinel_info_command="timeout 90 valkey-cli -h $VALKEY_SERVICE -p $SENTINEL_SERVICE_PORT --tls --cert ${VALKEY_SENTINEL_TLS_CERT_FILE} --key ${VALKEY_SENTINEL_TLS_KEY_FILE} --cacert ${VALKEY_SENTINEL_TLS_CA_FILE} sentinel get-primary-addr-by-name atmosphere" else sentinel_info_command="timeout 90 valkey-cli -h $VALKEY_SERVICE -p $SENTINEL_SERVICE_PORT sentinel get-primary-addr-by-name atmosphere" fi info "about to run the command: $sentinel_info_command" retry_while "eval $sentinel_info_command" 2 5 } [[ -f $VALKEY_PASSWORD_FILE ]] && export VALKEY_PASSWORD="$(< "${VALKEY_PASSWORD_FILE}")" primary_in_persisted_conf="$(get_full_hostname "$HOSTNAME")" if [[ -f /opt/bitnami/valkey-sentinel/etc/sentinel.conf ]]; then primary_in_persisted_conf="$(awk '/monitor/ {print $4}' /opt/bitnami/valkey-sentinel/etc/sentinel.conf)" info "Found previous primary $primary_in_persisted_conf in /opt/bitnami/valkey-sentinel/etc/sentinel.conf" debug "$(cat /opt/bitnami/valkey-sentinel/etc/sentinel.conf | grep monitor)" fi VALKEY_SENTINEL_INFO=($(get_sentinel_primary_info)) if [ "$?" -eq "0" ]; then # current primary's host and port obtained from other Sentinel info "printing VALKEY_SENTINEL_INFO=(${VALKEY_SENTINEL_INFO[0]},${VALKEY_SENTINEL_INFO[1]})" VALKEY_PRIMARY_HOST=${VALKEY_SENTINEL_INFO[0]} VALKEY_PRIMARY_PORT_NUMBER=${VALKEY_SENTINEL_INFO[1]} else VALKEY_PRIMARY_HOST="$primary_in_persisted_conf" VALKEY_PRIMARY_PORT_NUMBER="$VALKEYPORT" fi if [[ "$VALKEY_PRIMARY_HOST" == "$(get_full_hostname "$HOSTNAME")" ]]; then export VALKEY_REPLICATION_MODE="primary" else export VALKEY_REPLICATION_MODE="replica" fi if [[ -n "$VALKEY_EXTERNAL_PRIMARY_HOST" ]]; then VALKEY_PRIMARY_HOST="$VALKEY_EXTERNAL_PRIMARY_HOST" VALKEY_PRIMARY_PORT_NUMBER="${VALKEY_EXTERNAL_PRIMARY_PORT}" fi # To prevent incomplete configuration and as the valkey container accesses /opt/bitnami/valkey-sentinel/etc/sentinel.conf # as well, prepare the new config in `prepare-sentinel.conf` and move it atomically to the ultimate destination when it is complete. cp /opt/bitnami/valkey-sentinel/mounted-etc/sentinel.conf /opt/bitnami/valkey-sentinel/etc/prepare-sentinel.conf printf "\nsentinel myid %s" "$(host_id "$HOSTNAME")" >> /opt/bitnami/valkey-sentinel/etc/prepare-sentinel.conf if [[ -z "$VALKEY_PRIMARY_HOST" ]] || [[ -z "$VALKEY_PRIMARY_PORT_NUMBER" ]] then # Prevent incorrect configuration to be written to sentinel.conf error "Valkey primary host is configured incorrectly (host: $VALKEY_PRIMARY_HOST, port: $VALKEY_PRIMARY_PORT_NUMBER)" exit 1 fi sentinel_conf_set "sentinel monitor" "atmosphere "$VALKEY_PRIMARY_HOST" "$VALKEY_PRIMARY_PORT_NUMBER" 2" add_known_sentinel() { hostname="$1" ip="$2" if [[ -n "$hostname" && -n "$ip" && "$hostname" != "$HOSTNAME" ]]; then sentinel_conf_add "sentinel known-sentinel atmosphere $(get_full_hostname "$hostname") $(get_port "$hostname" "SENTINEL") $(host_id "$hostname")" fi } add_known_replica() { hostname="$1" ip="$2" if [[ -n "$ip" && "$(get_full_hostname "$hostname")" != "$VALKEY_PRIMARY_HOST" ]]; then sentinel_conf_add "sentinel known-replica atmosphere $(get_full_hostname "$hostname") $(get_port "$hostname" "VALKEY")" fi } # Add available hosts on the network as known replicas & sentinels for node in $(seq 0 $((1-1))); do hostname="valkey-node-$node" ip="$(getent hosts "$hostname.$HEADLESS_SERVICE" | awk '{ print $1 }')" add_known_sentinel "$hostname" "$ip" add_known_replica "$hostname" "$ip" done echo "" >> /opt/bitnami/valkey-sentinel/etc/prepare-sentinel.conf echo "sentinel announce-hostnames yes" >> /opt/bitnami/valkey-sentinel/etc/prepare-sentinel.conf echo "sentinel resolve-hostnames yes" >> /opt/bitnami/valkey-sentinel/etc/prepare-sentinel.conf echo "sentinel announce-port $SERVPORT" >> /opt/bitnami/valkey-sentinel/etc/prepare-sentinel.conf echo "sentinel announce-ip $(get_full_hostname "$HOSTNAME")" >> /opt/bitnami/valkey-sentinel/etc/prepare-sentinel.conf ARGS=("--port" "0") ARGS+=("--tls-port" "${VALKEY_SENTINEL_TLS_PORT_NUMBER}") ARGS+=("--tls-cert-file" "${VALKEY_SENTINEL_TLS_CERT_FILE}") ARGS+=("--tls-key-file" "${VALKEY_SENTINEL_TLS_KEY_FILE}") ARGS+=("--tls-ca-cert-file" "${VALKEY_SENTINEL_TLS_CA_FILE}") ARGS+=("--tls-replication" "yes") ARGS+=("--tls-auth-clients" "${VALKEY_SENTINEL_TLS_AUTH_CLIENTS}") mv /opt/bitnami/valkey-sentinel/etc/prepare-sentinel.conf /opt/bitnami/valkey-sentinel/etc/sentinel.conf exec valkey-server /opt/bitnami/valkey-sentinel/etc/sentinel.conf "${ARGS[@]}" --sentinel BinaryData ==== Events: