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
26 changes: 15 additions & 11 deletions solution-base/images/Makefile
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
BITNAMI_REMOTE := bitnami-containers
BITNAMI_REPO := https://github.com/bitnami/containers.git
BITNAMI_UPSTREAM_MAIN_REF := $(BITNAMI_REMOTE)/main

IMAGES := mongodb-sharded mongodb-exporter os-shell

BITNAMI_mongodb_sharded_PATH := 8.0/debian-12
# Latest commit on upstream main known to still contain
# bitnami/mongodb-sharded/8.0/debian-12.
BITNAMI_mongodb_sharded_REF := 48a109547d39cd8cf8a5d4058d832ecb5844829e
BITNAMI_mongodb_sharded_REF := 657585595c550d4dc107a4e6cd3a598a9d284eec

BITNAMI_mongodb_exporter_PATH := 0/debian-12
BITNAMI_mongodb_exporter_REF := $(BITNAMI_UPSTREAM_MAIN_REF)
BITNAMI_mongodb_exporter_REF := main

BITNAMI_os_shell_PATH := 12/debian-12
BITNAMI_os_shell_REF := $(BITNAMI_UPSTREAM_MAIN_REF)
BITNAMI_os_shell_REF := main

.PHONY: create-remote fetch-remote vendor-sync $(addprefix vendor-sync-,$(IMAGES)) $(addprefix update-vendor-branch-,$(IMAGES))
.PHONY: create-remote vendor-sync

normalize = $(subst -,_,$1)
bitnami_path = $(BITNAMI_$(call normalize,$1)_PATH)
Expand All @@ -25,15 +24,20 @@ vendor_branch = vendor/$1/$(call bitnami_path,$1)
create-remote:
@git remote get-url $(BITNAMI_REMOTE) >/dev/null 2>&1 || git remote add $(BITNAMI_REMOTE) $(BITNAMI_REPO)

fetch-remote: create-remote
# Fetch full history from Bitnami main so subtree split can see full subtree history.
git fetch $(BITNAMI_REMOTE) main

update-vendor-branch-%: fetch-remote
update-vendor-branch-%: create-remote
# Shallow-fetch only the pinned ref; full upstream history is unnecessary for a --squash merge.
git fetch --depth 1 --filter=blob:none $(BITNAMI_REMOTE) $(call bitnami_ref,$*)
-git branch -D $(call vendor_branch,$*)
git subtree split --prefix=bitnami/$*/$(call bitnami_path,$*) $(call bitnami_ref,$*) -b $(call vendor_branch,$*)
sha=$$(git rev-parse FETCH_HEAD) && \
wt=$$(mktemp -d) && \
trap 'git worktree remove --force "$$wt" 2>/dev/null' EXIT && \
git worktree add --no-checkout --detach "$$wt" "$$sha" && \
git -C "$$wt" sparse-checkout set --no-cone bitnami/$*/$(call bitnami_path,$*) && \
git -C "$$wt" checkout && \
git -C "$$wt" subtree split --prefix=bitnami/$*/$(call bitnami_path,$*) "$$sha" -b $(call vendor_branch,$*)

vendor-sync-%: update-vendor-branch-%
cd "$$(git rev-parse --show-toplevel)" && \
git subtree merge --prefix=solution-base/images/$*/debian-12 $(call vendor_branch,$*) --squash

vendor-sync: $(addprefix vendor-sync-,$(IMAGES))
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,32 @@ EOF
grep -q "ok: 1" <<<"$result"
}

########################
# Get if secondary node already has voting rights

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
# Get if secondary node already has voting rights
# Check if secondary node already has voting rights

# Globals:
# MONGODB_*
# Arguments:
# $1 - node
# $2 - port
# Returns:
# Boolean
#########################
mongodb_secondary_node_has_voting_rights() {
local -r node="${1:?node is required}"
local -r port="${2:?port is required}"
local result

debug "Checking voting rights of the node"
result=$(
mongodb_execute_print_output "$MONGODB_INITIAL_PRIMARY_ROOT_USER" "$MONGODB_INITIAL_PRIMARY_ROOT_PASSWORD" "admin" "$MONGODB_INITIAL_PRIMARY_HOST" "$MONGODB_INITIAL_PRIMARY_PORT_NUMBER" <<EOF
rs.conf().members.filter(m => m.host === '$node:$port' && m.votes > 0 && m.priority > 0).length === 1
EOF
)
debug "$result"

grep -q "true" <<<"$result"
}

########################
# Get if hidden node is pending
# Globals:
Expand Down Expand Up @@ -1187,7 +1213,15 @@ mongodb_configure_secondary() {
exit 1
fi
mongodb_wait_confirmation "$node" "$port"
fi

# Grant voting rights to the node if it does not have them yet. This must be
# done even when the node is already in the cluster: a previous attempt may
# have added it with votes/priority 0 and failed (or been restarted) before
# granting voting rights, leaving the node stuck without them.
if mongodb_secondary_node_has_voting_rights "$node" "$port"; then
info "Node already has voting rights"
else

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will not behave properly when we have 9-replicas, where 2 nodes are always "non voting". This is expected, and we must not try to change that (in particular, the voting nodes must be in precisely the expected DC for proper redundancy)

→ the change will make the startup slower on these extra secondaries -(re-)trying to make them voting-, possibly with the extra risk of changing the set of voters...

# Ensure that secondary nodes do not count as voting members until they are fully initialized
# https://docs.mongodb.com/manual/reference/method/rs.add/#behavior
if ! retry_while "mongodb_is_secondary_node_ready $node $port" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY"; then
Expand All @@ -1198,17 +1232,16 @@ mongodb_configure_secondary() {
# Grant voting rights to node
# https://docs.mongodb.com/manual/tutorial/modify-psa-replica-set-safely/
if ! retry_while "mongodb_configure_secondary_node_voting $node $port" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY"; then
error "Secondary node did not get marked as secondary"
error "Secondary node did not get granted voting rights"
exit 1
fi
fi

# Mark node as readable. This is necessary in cases where the PVC is lost
if is_boolean_yes "$MONGODB_SET_SECONDARY_OK"; then
mongodb_execute_print_output "$MONGODB_INITIAL_PRIMARY_ROOT_USER" "$MONGODB_INITIAL_PRIMARY_ROOT_PASSWORD" "admin" <<EOF
# Mark node as readable. This is necessary in cases where the PVC is lost
if is_boolean_yes "$MONGODB_SET_SECONDARY_OK"; then
mongodb_execute_print_output "$MONGODB_INITIAL_PRIMARY_ROOT_USER" "$MONGODB_INITIAL_PRIMARY_ROOT_PASSWORD" "admin" <<EOF
rs.secondaryOk()
EOF
fi

fi
}

Expand Down Expand Up @@ -1667,3 +1700,46 @@ mongodb_execute_print_output() {
mongodb_execute() {
debug_execute mongodb_execute_print_output "$@"
}

# Copyright Broadcom, Inc. All Rights Reserved.
# SPDX-License-Identifier: APACHE-2.0

# shellcheck disable=SC2148

########################
# Execute an arbitrary query/queries against the running MongoDB service
# Stdin:
# Query/queries to execute
# Arguments:
# $1 - User to run queries
# $2 - Password
# $3 - Database where to run the queries
# $4 - Host (default to result of get_mongo_hostname function)
# $5 - Port (default $MONGODB_PORT_NUMBER)
# $6 - Extra arguments (default $MONGODB_SHELL_EXTRA_FLAGS)
# Returns:
# None
########################
mongodb_execute() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already merged : please rebase on top of actual target branch

local -r user="${1:-}"
local -r password="${2:-}"
local -r database="${3:-}"
local -r host="${4:-$(get_mongo_hostname)}"
local -r port="${5:-$MONGODB_PORT_NUMBER}"
local -r extra_args="${6:-$MONGODB_SHELL_EXTRA_FLAGS}"
local final_user="$user"
# If password is empty it means no auth, do not specify user
[[ -z "$password" ]] && final_user=""

local -a args=("--host" "$host" "--port" "$port")
[[ -n "$final_user" ]] && args+=("-u" "$final_user")
[[ -n "$password" ]] && args+=("-p" "$password")
if [[ -n "$extra_args" ]]; then
local extra_args_array=()
read -r -a extra_args_array <<<"$extra_args"
[[ "${#extra_args_array[@]}" -gt 0 ]] && args+=("${extra_args_array[@]}")
fi
[[ -n "$database" ]] && args+=("$database")

"$MONGODB_BIN_DIR/mongosh" "${args[@]}"
}
Loading