[bitnami/mongodb, bitnami/mongodb-sharded] Fix secondary voting-rights check always returning true (#96305)

mongodb_secondary_node_has_voting_rights(), introduced in #95156, greps the
mongosh output for "true". mongosh always prints a connection banner holding
"directConnection=true" on stdout, so the grep matches unconditionally and the
function can never return false.

mongodb_configure_secondary() therefore always takes the "Node already has
voting rights" branch and the grant is never executed: secondaries are added
with votes:0/priority:0 by rs.add() and stay there permanently, so only the
node that ran rs.initiate() ends up holding a vote.

Reproduced with mongosh 2.9.2, the version shipped in the 8.3 images:

    $ mongosh --host <host> --port 27017 admin 2>/dev/null <<< 'print("x")'
    Current Mongosh Log ID: ...
    Connecting to:  mongodb://<host>:27017/admin?directConnection=true&appName=mongosh+2.9.2

Print an explicit HAS_VOTES_YES/HAS_VOTES_NO sentinel and match on that. The
sentinel is concatenated at runtime so the positive value never appears
verbatim in the script sent to mongosh. Also use .some() rather than
.filter().length === 1.

Verified on a 9-member sharded replica set: before the fix, a new secondary
joining with a free voter slot stayed at votes:0 (9 members / 6 voters); after
the fix it is granted votes:1/priority:1 (9 members / 7 voters).

Signed-off-by: Edouard COMTET <edouard.comtet@scality.com>
This commit is contained in:
Edouard COMTET
2026-08-17 10:53:53 +02:00
committed by GitHub
parent f6a6e6b825
commit 159c87c0e6
2 changed files with 10 additions and 4 deletions
@@ -957,14 +957,17 @@ mongodb_secondary_node_has_voting_rights() {
local result
debug "Checking voting rights of the node"
# mongosh prints a connection banner containing 'directConnection=true', so a
# plain 'true' match always succeeds. Match an explicit sentinel instead, built
# at runtime so the positive value never appears verbatim in the sent script.
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
print("HAS_VOTES_" + (rs.conf().members.some(m => m.host === '$node:$port' && m.votes > 0 && m.priority > 0) ? "YES" : "NO"))
EOF
)
debug "$result"
grep -q "true" <<<"$result"
grep -q "HAS_VOTES_YES" <<<"$result"
}
########################
@@ -957,14 +957,17 @@ mongodb_secondary_node_has_voting_rights() {
local result
debug "Checking voting rights of the node"
# mongosh prints a connection banner containing 'directConnection=true', so a
# plain 'true' match always succeeds. Match an explicit sentinel instead, built
# at runtime so the positive value never appears verbatim in the sent script.
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
print("HAS_VOTES_" + (rs.conf().members.some(m => m.host === '$node:$port' && m.votes > 0 && m.priority > 0) ? "YES" : "NO"))
EOF
)
debug "$result"
grep -q "true" <<<"$result"
grep -q "HAS_VOTES_YES" <<<"$result"
}
########################