Skip to content

Add PBM and PMM user configuration for config servers - #1165

Open
peterSirotnak wants to merge 4 commits into
mainfrom
claude/grafana-chunks-dynamic-panel-okswwe
Open

Add PBM and PMM user configuration for config servers#1165
peterSirotnak wants to merge 4 commits into
mainfrom
claude/grafana-chunks-dynamic-panel-okswwe

Conversation

@peterSirotnak

Copy link
Copy Markdown
Contributor

Configure PBM and PMM users on the config server replica sets in sharded MongoDB deployments.

This change adds user and role setup for the config server replica set (rscfg) in both the PMM-integrated and standalone sharded cluster initialization scripts:

  • Create root user on the config server primary
  • Define custom roles (pbmAnyAction and explainRole) required by PBM and PMM
  • Create PBM user with appropriate backup and cluster permissions
  • Create PMM user with monitoring and diagnostic permissions

These configurations mirror the existing setup for shard replica sets, ensuring consistent authentication and authorization across all cluster components.

https://claude.ai/code/session_01LyoNZANW3DpCvzF2th7b8d

The sharded MongoDB setup scripts created shard-local root/pbm/pmm
users directly on rs1 and rs2 (bypassing mongos), but skipped this
step for the config server replicaset (rscfg). Users created while
connected to mongos can only authenticate through mongos, not via a
direct connection to a shard or config server member, so the later
`pmm-admin add mongodb ... 127.0.0.1:27017` calls against rscfg01/02/03
were authenticating with credentials that don't work for a direct
connection.

This broke monitoring of the config servers themselves, and since the
mongos-connected exporter's sharding/chunks collector output feeds the
Grafana `$shard` template variable used across the MongoDB Cluster
Summary dashboard (including the config-servers topology panel), it
left chunk-distribution panels like "Dynamic of Chunks" empty.

Add the same local user-creation block used for rs1/rs2, scoped to the
rscfg replicaset, in both start-sharded.sh and
start-sharded-with-pmm.sh.
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The two sharded setup scripts now configure rscfg authentication and create a background process that inserts documents, moves chunks between shards, attempts chunk splits, and logs operation failures.

Changes

Sharded Setup

Layer / File(s) Summary
Config server authentication
qa-integration/pmm_psmdb-pbm_setup/start-sharded*.sh
Both scripts create the rscfg root user, define PBM and explain roles, and create configured PBM and PMM users.
Chunk activity generation
qa-integration/pmm_psmdb-pbm_setup/start-sharded*.sh
Both scripts run a background loop that inserts test documents, moves chunks to each shard, attempts chunk splits, logs individual failures, and waits four minutes before repeating.

Sequence Diagram(s)

sequenceDiagram
  participant SetupScript
  participant Rscfg
  participant Shards
  SetupScript->>Rscfg: Insert test document
  Rscfg->>Shards: Identify chunk and shard metadata
  SetupScript->>Shards: Attempt chunk moves
  SetupScript->>Rscfg: Attempt chunk split
  SetupScript->>SetupScript: Log failures and wait 240 seconds
Loading
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary change: adding PBM and PMM user configuration for config servers.
Description check ✅ Passed The description accurately explains the user, role, and permission setup added to both sharded cluster initialization scripts.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh`:
- Around line 180-190: Encode all configured credentials before interpolation
into Mongo shell JavaScript: update
qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh ranges 180-190 and
195-208 for pbm_user/pbm_pass and pmm_user/pmm_pass, and
qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh ranges 185-195 and 200-213
for pbm_user/pbm_pass and pmm_mongo_user/pmm_mongo_user_pass. Use
JavaScript-safe serialization or pass values as shell data so quotes,
backslashes, and line breaks cannot break the generated source or inject
commands.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e21572ab-2676-4661-b042-2d59333ff7c5

📥 Commits

Reviewing files that changed from the base of the PR and between 7dd1989 and 8e66cad.

📒 Files selected for processing (2)
  • qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh
  • qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • percona/pmm-qa (manual)
  • percona/pmm (manual)

Comment thread qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh
The "Chunks Move Events" dashboard panel graphs moveChunk.start/commit
events from config.changelog (mongodb_mongos_sharding_changelog_10min_total).
With hashed sharding, shardCollection pre-splits and evenly distributes
the initial chunks across shards at creation time, so with only ~10MB
of test data the balancer never has an imbalance to correct and no
moveChunk event is ever logged - the panel stays empty regardless of
monitoring being set up correctly.

After loading the datagen data, explicitly move every chunk of
test.test to a different shard via sh.moveChunk() so real
moveChunk.start/moveChunk.commit changelog events exist for the
dashboard to show.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh`:
- Around line 319-325: Update the chunk-migration logic in both sharded setup
scripts to use the database moveChunk command with each chunk’s min and max
bounds instead of sh.moveChunk() with only chunk.min. Preserve the existing
target-shard selection and migrate hashed-key chunks by passing the chunk bounds
in the command format.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 60a0f59f-e4f4-4c82-a7aa-06b4c6bf7db5

📥 Commits

Reviewing files that changed from the base of the PR and between 8e66cad and 5e72703.

📒 Files selected for processing (2)
  • qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh
  • qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • percona/pmm-qa (manual)
  • percona/pmm (manual)
🚧 Files skipped from review as they are similar to previous changes (1)
  • qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh

Comment on lines +319 to +325
docker compose -f docker-compose-sharded.yaml exec -T mongos mongo "mongodb://root:root@localhost" --quiet --eval '
var coll = db.getSiblingDB("config").collections.findOne({ _id: "test.test" });
var shards = db.getSiblingDB("config").shards.find().toArray().map(function (s) { return s._id; });
db.getSiblingDB("config").chunks.find({ uuid: coll.uuid }).forEach(function (chunk) {
var target = shards.filter(function (s) { return s !== chunk.shard; })[0];
if (target) {
sh.moveChunk("test.test", chunk.min, target);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

mapfile -t files < <(fd -a -t f '^(sharded\.json|docker-compose-sharded.*\.yaml)$' .)
((${`#files`[@]} > 0))

rg -n -C 4 'hashed|shardCollection|sh\.moveChunk|moveChunk' \
  "${files[@]}" qa-integration/pmm_psmdb-pbm_setup

Repository: percona/pmm-qa

Length of output: 204


🏁 Script executed:

set -euo pipefail
printf '%s\n' '--- candidate files ---'
fd -a -t f 'start-sharded.*\.sh$|.*sharded.*\.json$|docker-compose-sharded.*\.yaml$|README.*|.*\.md$' qa-integration 2>/dev/null | head -200
printf '%s\n' '--- relevant references ---'
rg -n -C 6 'hashed|shardCollection|sh\.moveChunk|moveChunk|test\.test|set -e' qa-integration/pmm_psmdb-pbm_setup .github 2>/dev/null || true
printf '%s\n' '--- target sections ---'
sed -n '285,345p' qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh
printf '%s\n' '--- sibling script section ---'
sed -n '285,345p' qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh 2>/dev/null || true

Repository: percona/pmm-qa

Length of output: 27266


🏁 Script executed:

set -euo pipefail
python3 - <<'PY'
import json
from pathlib import Path

root = Path("qa-integration/pmm_psmdb-pbm_setup")
config = json.loads((root / "conf/datagen/sharded.json").read_text())
entry = next(x for x in config if x.get("collection") == "test")
print("shardCollection:", entry["shardConfig"]["shardCollection"])
print("shard key:", entry["shardConfig"]["key"])
for name in ("start-sharded.sh", "start-sharded-with-pmm.sh"):
    text = (root / name).read_text()
    print(name, {
        "set_e": text.splitlines()[1].strip(),
        "uses_find_form": 'sh.moveChunk("test.test", chunk.min, target);' in text,
        "uses_bounds_command": 'bounds: [chunk.min, chunk.max]' in text,
        "migration_count": text.count('sh.moveChunk("test.test", chunk.min, target);'),
    })
PY

Repository: percona/pmm-qa

Length of output: 444


🌐 Web query:

MongoDB sh.moveChunk hashed shard key find form bounds moveChunk command documentation

💡 Result:

To move a chunk in a MongoDB collection that uses a hashed shard key, you must use the moveChunk database command with the bounds field [1][2]. The sh.moveChunk() helper method cannot be used for hashed shard keys because it relies on the find option, which is incompatible with hashed indexes [2][3]. When using the moveChunk command for hashed shard keys, follow these requirements: 1. Use the bounds parameter instead of find. The find field is for equality matches on shard keys and must not be used with hashed shard keys [1][4]. 2. The bounds field must be an array consisting of two documents that define the lower and upper shard key values of the chunk to move [1][5]. 3. The format for the bounds array is: [ { hashedField: }, { hashedField: } ] [1][4] Example command structure: db.adminCommand( { moveChunk: , bounds: [ { hashedField: }, { hashedField: } ], to: }) [1][4] Ensure you are executing this command via a mongos instance while connected to the admin database [1][5]. The find field, which is often used in tutorials for non-hashed shard keys, will fail or be prohibited for collections using hashed sharding [1][6].

Citations:


Use the bounds form for hashed chunk migrations.

test.test uses the hashed _id key. Replace sh.moveChunk() with the moveChunk command in both sharded setup scripts. Otherwise, setup exits before tests run. Make it so.

Use chunk bounds
-            sh.moveChunk("test.test", chunk.min, target);
+            var result = db.getSiblingDB("admin").runCommand({
+                moveChunk: "test.test",
+                bounds: [chunk.min, chunk.max],
+                to: target
+            });
+            if (!result.ok) {
+                throw new Error("moveChunk failed: " + tojson(result));
+            }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
docker compose -f docker-compose-sharded.yaml exec -T mongos mongo "mongodb://root:root@localhost" --quiet --eval '
var coll = db.getSiblingDB("config").collections.findOne({ _id: "test.test" });
var shards = db.getSiblingDB("config").shards.find().toArray().map(function (s) { return s._id; });
db.getSiblingDB("config").chunks.find({ uuid: coll.uuid }).forEach(function (chunk) {
var target = shards.filter(function (s) { return s !== chunk.shard; })[0];
if (target) {
sh.moveChunk("test.test", chunk.min, target);
docker compose -f docker-compose-sharded.yaml exec -T mongos mongo "mongodb://root:root@localhost" --quiet --eval '
var coll = db.getSiblingDB("config").collections.findOne({ _id: "test.test" });
var shards = db.getSiblingDB("config").shards.find().toArray().map(function (s) { return s._id; });
db.getSiblingDB("config").chunks.find({ uuid: coll.uuid }).forEach(function (chunk) {
var target = shards.filter(function (s) { return s !== chunk.shard; })[0];
if (target) {
var result = db.getSiblingDB("admin").runCommand({
moveChunk: "test.test",
bounds: [chunk.min, chunk.max],
to: target
});
if (!result.ok) {
throw new Error("moveChunk failed: " + tojson(result));
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh` around lines 319 - 325,
Update the chunk-migration logic in both sharded setup scripts to use the
database moveChunk command with each chunk’s min and max bounds instead of
sh.moveChunk() with only chunk.min. Preserve the existing target-shard selection
and migrate hashed-key chunks by passing the chunk bounds in the command format.

Root cause found by reproducing against a live sharded cluster: the
previous moveChunk step had no error handling, and sh.moveChunk can
transiently fail (MongoDB rejects a migration while the orphan-cleanup
routine from a prior migration on that range hasn't finished yet).
With set -e/set -ex, that uncaught failure aborted the whole setup
script right at this step - leaving chunks unmoved and skipping
tests/cleanup, exactly matching the observed "still empty" dashboards.

Wrap the moveChunk call in try/catch so one transient failure doesn't
kill the run. Also add an explicit sh.splitFind() so "Chunks Split
Events" (same config.changelog-based metric family, filtered on
event=~".*split.*") has real data too - confirmed both moveChunk.* and
split events land in config.changelog end to end against a live
cluster.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh (2)

200-211: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Limit ${pmm_mongo_user} to monitoring.

The script grants ${pmm_mongo_user} readWrite, backup, restore, and pbmAnyAction. Because pbmAnyAction allows anyAction on anyResource, this credential has unrestricted MongoDB privileges. Keep these roles on ${pbm_user} only. Retain explainRole, clusterMonitor, and read on local for ${pmm_mongo_user}.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh` around lines 200 - 211,
Update the createUser roles for ${pmm_mongo_user} to retain only explainRole,
clusterMonitor, and read on local. Remove its admin readWrite, backup, restore,
and pbmAnyAction roles, leaving those roles assigned only to ${pbm_user}.

148-150: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Make it so: create the cluster authentication objects once.

The mongos bootstrap repeats root, pbmAnyAction, explainRole, ${pbm_user}, and ${pmm_mongo_user} after the config-server bootstrap creates them. MongoDB rejects duplicate users and roles. With set -e, setup stops before sh.addShard.

Remove the duplicate mongos root, role, and user creation blocks. Keep the authenticated sh.addShard commands. Apply the same fix to qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh` around lines 148 - 150,
Remove the duplicate root, pbmAnyAction, explainRole, ${pbm_user}, and
${pmm_mongo_user} creation blocks from the mongos bootstrap in both
start-sharded.sh and start-sharded-with-pmm.sh, leaving the authenticated
sh.addShard commands intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh`:
- Around line 200-211: Update the createUser roles for ${pmm_mongo_user} to
retain only explainRole, clusterMonitor, and read on local. Remove its admin
readWrite, backup, restore, and pbmAnyAction roles, leaving those roles assigned
only to ${pbm_user}.
- Around line 148-150: Remove the duplicate root, pbmAnyAction, explainRole,
${pbm_user}, and ${pmm_mongo_user} creation blocks from the mongos bootstrap in
both start-sharded.sh and start-sharded-with-pmm.sh, leaving the authenticated
sh.addShard commands intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bd600086-2c55-4b83-94fe-31feb7cae6c3

📥 Commits

Reviewing files that changed from the base of the PR and between 5e72703 and 24d0eda.

📒 Files selected for processing (2)
  • qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh
  • qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • percona/pmm-qa (manual)
  • percona/pmm (manual)
🚧 Files skipped from review as they are similar to previous changes (1)
  • qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh

Reproduced against the user's live deployment (65.108.48.166): the
mongodb_mongos_sharding_changelog_10min_total metric had zero
moveChunk/split events ever, even though the previous fix's one-shot
trigger step had run.

Root cause, confirmed by reproducing against a live cluster: picking
an arbitrary existing chunk via config.chunks and moving it can be a
silent no-op - sh.moveChunk() returns {ok: 1} in milliseconds without
actually migrating anything or writing a changelog entry when the
chunk range happens to be empty. The previous script's chunk.min-based
selection had no guarantee the chunk it grabbed held any documents.

Fix the selection to always target a chunk that provably has data: use
sh.moveChunk()/sh.splitFind() on a query matching a document just
inserted, exactly as MongoDB's own docs recommend, and try moving it
to every shard in turn - guaranteed to force at least one migration
whichever shard it's not currently on. This alone is not durable
either: the underlying metric is a live 10-minute rolling window over
config.changelog, so a one-shot run at setup time reads empty for
anyone checking the dashboard later. Replace the one-shot trigger with
a small script written into the mongos container and launched detached
(docker compose exec -d) that repeats every 4 minutes for as long as
the environment is up, so the window never goes empty.

Verified end to end against a live cluster: repeated cycles produce
real moveChunk.start/commit changelog entries (including hitting and
correctly swallowing the transient orphan-cleanup migration error).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh (3)

183-195: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Serialize environment-derived credentials before embedding them in JavaScript.

The unquoted EOF heredocs insert usernames and passwords into double-quoted JavaScript strings. A quote, backslash, or newline can break the command. A crafted value can escape the string and execute Mongo shell statements in the root-authenticated session. JSON-encode each value or pass it through a quoted environment channel. Apply the same fix to the shard and mongos blocks.

Also applies to: 198-214

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh` around lines 183 - 195,
The unquoted heredocs in the configserver, shard, and mongos PBM user-creation
blocks embed pbm_user and pbm_pass directly into JavaScript strings. Serialize
each environment-derived credential safely before insertion, such as
JSON-encoding the values or passing them through a quoted environment channel,
and apply the same protection to all three blocks while preserving the existing
Mongo authentication and user-creation behavior.

148-150: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Wait for rscfg01 to become a writable primary.

The fixed 60-second delay after rs.initiate() does not guarantee primary readiness. If rscfg01 is still secondary, createUser fails and set -e aborts setup. Poll hello.isWritablePrimary with bounded retries before creating root.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh` around lines 148 - 150,
Replace the fixed 60-second delay after rs.initiate for rscfg01 with bounded
polling of hello.isWritablePrimary, retrying until the config server is a
writable primary or exiting with an explicit failure after the retry limit. Only
execute the root-user createUser command after the readiness check succeeds.

Source: MCP tools


148-150: 🗄️ Data Integrity & Integration | 🔴 Critical | ⚡ Quick win

Remove duplicate user and role provisioning.

The rscfg01 and mongos blocks create the same root, pbmAnyAction, explainRole, ${pbm_user}, and ${pmm_mongo_user} names in the config server admin database. MongoDB rejects duplicate users and roles. With set -e, setup stops at the mongos root creation before shard registration. Provision each name once, or use distinct local config-server credentials.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh` around lines 148 - 150,
Remove the duplicate user and role creation between the rscfg01 config-server
block and the mongos block in start-sharded.sh. Ensure root, pbmAnyAction,
explainRole, ${pbm_user}, and ${pmm_mongo_user} are provisioned only once in the
config-server admin database, while preserving the credentials required for
subsequent shard registration.

Source: MCP tools

qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh (2)

195-208: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Separate the PMM and PBM credentials.

The PMM agent uses pmm_user, but all three pmm_user definitions also grant readWrite, backup, restore, and pbmAnyAction. Remove these roles from pmm_user and retain them only on pbm_user. Make it so.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh` around lines
195 - 208, Update the user setup around the pmm_user and pbm_user definitions so
pmm_user retains only its PMM-required roles and no longer receives readWrite,
backup, restore, or pbmAnyAction privileges. Ensure those PBM-specific roles
remain assigned exclusively to pbm_user across all three definitions.

143-145: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Use separate supported authentication paths for rscfg.

MongoDB requires cluster-level users and roles to be created through mongos. Direct creation on rscfg01 is unsupported.

PBM and PMM later connect directly to each rscfg member. Do not simply remove the rscfg blocks. Create distinct, documented shard-local credentials for direct connections, and create cluster-level credentials once through mongos.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh` around lines
143 - 145, Update the setup flow around the rscfg01 root-user creation to stop
creating cluster-level users directly on the config-server member. Create the
required cluster-level credentials once through mongos, while retaining separate
documented shard-local credentials for PBM and PMM’s direct connections to each
rscfg member; do not remove the rscfg setup blocks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh`:
- Around line 314-338: Update the chunk-activity generator setup around the
heredocs and background launch to create a private mode-700 temporary directory
with mktemp -d inside the mongos container. Use that directory for
keep_chunks_moving.js, keep_chunks_moving.sh, and keep_chunks_moving.log, and
update the script invocation to reference the new private paths instead of
predictable /tmp locations.
- Around line 316-325: Update the test.test sharding setup around sh.moveChunk
and sh.splitFind to use bounds compatible with the configured hashed _id shard
key, or change the collection to a range-based shard key. Ensure the moveChunk
and splitFind calls use valid hashed chunk-bound arguments so they execute
successfully, while preserving the existing target iteration and inserted
document flow.

In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh`:
- Around line 342-343: Register an EXIT cleanup trap before launching the
detached keep_chunks_moving.sh process, using the existing cleanup behavior and
honoring CLEANUP=no. Ensure the trap stops the background generator and Compose
stack even when set -e exits before the current post-test cleanup block, while
preserving normal cleanup behavior.
- Around line 329-333: Replace the sh.splitFind call in the hashed-key setup
flow with logic that resolves the current chunk bounds for test.test and invokes
adminCommand using split: "test.test" and those bounds. Preserve the existing
failure handling and ensure the split command executes successfully so split
events are emitted.
- Line 319: Update the generator-file setup around the mongos tee command to
create a private mktemp -d directory inside the container, and store all three
generated files there using quoted paths. Ensure the temporary directory is
removed when the background process exits, while preserving the existing
generator execution flow.

---

Outside diff comments:
In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh`:
- Around line 195-208: Update the user setup around the pmm_user and pbm_user
definitions so pmm_user retains only its PMM-required roles and no longer
receives readWrite, backup, restore, or pbmAnyAction privileges. Ensure those
PBM-specific roles remain assigned exclusively to pbm_user across all three
definitions.
- Around line 143-145: Update the setup flow around the rscfg01 root-user
creation to stop creating cluster-level users directly on the config-server
member. Create the required cluster-level credentials once through mongos, while
retaining separate documented shard-local credentials for PBM and PMM’s direct
connections to each rscfg member; do not remove the rscfg setup blocks.

In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh`:
- Around line 183-195: The unquoted heredocs in the configserver, shard, and
mongos PBM user-creation blocks embed pbm_user and pbm_pass directly into
JavaScript strings. Serialize each environment-derived credential safely before
insertion, such as JSON-encoding the values or passing them through a quoted
environment channel, and apply the same protection to all three blocks while
preserving the existing Mongo authentication and user-creation behavior.
- Around line 148-150: Replace the fixed 60-second delay after rs.initiate for
rscfg01 with bounded polling of hello.isWritablePrimary, retrying until the
config server is a writable primary or exiting with an explicit failure after
the retry limit. Only execute the root-user createUser command after the
readiness check succeeds.
- Around line 148-150: Remove the duplicate user and role creation between the
rscfg01 config-server block and the mongos block in start-sharded.sh. Ensure
root, pbmAnyAction, explainRole, ${pbm_user}, and ${pmm_mongo_user} are
provisioned only once in the config-server admin database, while preserving the
credentials required for subsequent shard registration.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 083122c8-0053-41bd-932f-ddc4ff01bfd0

📥 Commits

Reviewing files that changed from the base of the PR and between 24d0eda and ca026c1.

📒 Files selected for processing (2)
  • qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh
  • qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • percona/pmm-qa (manual)
  • percona/pmm (manual)

Comment on lines +314 to +338
docker compose -f docker-compose-sharded-with-pmm.yaml exec -T mongos tee /tmp/keep_chunks_moving.js > /dev/null << 'JSEOF'
var shards = db.getSiblingDB("config").shards.find().toArray().map(function (s) { return s._id; });
var ins = db.getSiblingDB("test").test.insertOne({ ts: new Date() });
shards.forEach(function (target) {
try {
sh.moveChunk("test.test", { _id: ins.insertedId }, target);
} catch (e) {
print("moveChunk to " + target + " failed, skipping: " + e);
}
});
try {
sh.splitFind("test.test", { _id: ins.insertedId });
} catch (e) {
print("splitFind failed, skipping: " + e);
}
JSEOF
docker compose -f docker-compose-sharded-with-pmm.yaml exec -T mongos tee /tmp/keep_chunks_moving.sh > /dev/null << 'SHEOF'
#!/bin/bash
while true; do
mongo "mongodb://root:root@localhost" --quiet /tmp/keep_chunks_moving.js > /tmp/keep_chunks_moving.log 2>&1
sleep 240
done
SHEOF
echo "starting background chunk-activity generator"
docker compose -f docker-compose-sharded-with-pmm.yaml exec -d mongos bash /tmp/keep_chunks_moving.sh

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Use a private temporary directory for generator state.

Lines [314], [330], and [333] use predictable paths under /tmp. If another process in the mongos container can write there, it can pre-create a symlink and redirect tee or shell-redirection writes. Create a mktemp -d directory with mode 700 inside the container and use it for the JavaScript file, shell script, and log.

🧰 Tools
🪛 ast-grep (0.45.1)

[warning] 329-329: Writing to or reading from a hardcoded, predictable path under /tmp is vulnerable to symlink and TOCTOU attacks: a local attacker can pre-create the file (or a symlink pointing elsewhere) and hijack or corrupt the contents. Generate a unique, unpredictable temporary file with mktemp instead, e.g. tmpfile="$(mktemp)" (or mktemp -d for directories) and reference "$tmpfile".
Context: /tmp/keep_chunks_moving.sh
Note: [CWE-377] Insecure Temporary File.

(predictable-tmp-file-bash)


[warning] 337-337: Writing to or reading from a hardcoded, predictable path under /tmp is vulnerable to symlink and TOCTOU attacks: a local attacker can pre-create the file (or a symlink pointing elsewhere) and hijack or corrupt the contents. Generate a unique, unpredictable temporary file with mktemp instead, e.g. tmpfile="$(mktemp)" (or mktemp -d for directories) and reference "$tmpfile".
Context: /tmp/keep_chunks_moving.sh
Note: [CWE-377] Insecure Temporary File.

(predictable-tmp-file-bash)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh` around lines
314 - 338, Update the chunk-activity generator setup around the heredocs and
background launch to create a private mode-700 temporary directory with mktemp
-d inside the mongos container. Use that directory for keep_chunks_moving.js,
keep_chunks_moving.sh, and keep_chunks_moving.log, and update the script
invocation to reference the new private paths instead of predictable /tmp
locations.

Source: Linters/SAST tools

Comment on lines +316 to +325
var ins = db.getSiblingDB("test").test.insertOne({ ts: new Date() });
shards.forEach(function (target) {
try {
sh.moveChunk("test.test", { _id: ins.insertedId }, target);
} catch (e) {
print("moveChunk to " + target + " failed, skipping: " + e);
}
});
try {
sh.splitFind("test.test", { _id: ins.insertedId });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

found=0
while IFS= read -r config; do
  found=1
  echo "== $config =="
  rg -n -C 6 'test|collection|namespace|shard|key|_id' "$config"
done < <(fd -i -t f 'sharded\.json$')

if [ "$found" -eq 0 ]; then
  echo "No sharded.json file found" >&2
  exit 1
fi

Repository: percona/pmm-qa

Length of output: 204


🏁 Script executed:

set -euo pipefail
printf '%s\n' '== candidate files =='
fd -i -t f 'sharded\.json$|start-sharded-with-pmm\.sh$|datagen' . || true
printf '%s\n' '== relevant references =='
rg -n -C 8 'sharded\.json|test\.test|moveChunk|splitFind|shardCollection|shardKey|_id' qa-integration .github 2>/dev/null || true

Repository: percona/pmm-qa

Length of output: 50371


🏁 Script executed:

set -euo pipefail
printf '%s\n' '== sharded.json =='
cat -n qa-integration/pmm_psmdb-pbm_setup/conf/datagen/sharded.json
printf '%s\n' '== generator and surrounding setup =='
sed -n '295,345p' qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh
printf '%s\n' '== compose image and datagen mounts =='
rg -n -C 5 'mongos:|mongo:|mgodatagen|datagen|image:' qa-integration/pmm_psmdb-pbm_setup/docker-compose-sharded-with-pmm.yaml

Repository: percona/pmm-qa

Length of output: 7934


🏁 Script executed:

set -euo pipefail
printf '%s\n' '== image definition =='
cat -n qa-integration/pmm_psmdb-pbm_setup/Dockerfile
printf '%s\n' '== mongo shell references =='
rg -n -C 6 'mongo(shell)?|mongos|MONGO|PSMDB|percona-server-mongodb|mongodb-org|mgodatagen' qa-integration/pmm_psmdb-pbm_setup --glob '!*.json'
printf '%s\n' '== repository metadata for image version =='
rg -n -C 4 'REPO|PSMDB|MONGODB|VERSION|TAG' qa-integration/pmm_psmdb-pbm_setup/{Dockerfile,docker-compose-sharded-with-pmm.yaml,.env,Makefile} 2>/dev/null || true

Repository: percona/pmm-qa

Length of output: 50371


🌐 Web query:

MongoDB mongosh sh.moveChunk sh.splitFind helper availability signatures MongoDB 8.0

💡 Result:

In MongoDB 8.0, both sh.moveChunk and sh.splitFind are available as helper methods in mongosh [1][2][3]. sh.moveChunk The signature for this method is sh.moveChunk(namespace, query, destination) [4]. - namespace (string): The full namespace (database.collection) of the sharded collection [4]. - query (document): An equality match on the shard key used to identify the chunk to move [4]. - destination (string): The ID of the recipient shard [4]. This method wraps the moveChunk database command [4]. It is not suitable for hashed shard keys when using the query parameter; for hashed shard keys, users should instead utilize the moveChunk command directly with the bounds field [4][5]. sh.splitFind The signature for this method is sh.splitFind(namespace, query) [6]. - namespace (string): The full namespace of the sharded collection [6][7]. - query (document): A query that identifies the shard key value within the chunk to be split [6][7]. This method splits the identified chunk at its median point, resulting in two roughly equal chunks [6][3]. It wraps the split database command [6][8]. General Note MongoDB documentation emphasizes that in most production environments, automatic chunk management (balancing and splitting) should be left to the built-in system processes rather than manual intervention via these helpers [4][6][7]. Furthermore, while these helpers provide convenience in mongosh, they may not return the same comprehensive information as the underlying database commands [5][8].

Citations:


🌐 Web query:

site:mongodb.com/docs sh.splitFind hashed shard key unsupported

💡 Result:

The sh.splitFind method is not directly supported for splitting chunks in a collection partitioned using a hashed shard key [1][2][3][4]. In MongoDB, while sh.splitFind and sh.splitAt are convenient helpers for manual chunk splitting, they are designed to work with range-based sharding [5][6][7]. For collections using a hashed shard key, you must use the underlying split database command with the bounds parameter [1][2][3][4]. The bounds parameter requires an array containing two documents that specify the exact lower and upper shard-key values of the chunk you intend to split [1][2][3][4]. These values must match the minimum and maximum boundaries of an existing chunk, which can be identified using sh.status [1][2][3][4]. Example of splitting a hashed chunk via the database command: db.adminCommand({ split: "database.collection", bounds: [ { hashed_shard_key: NumberLong("-5838464104018346494") }, { hashed_shard_key: NumberLong("-5557153028469814163") } ] }) [1][2][3][4] Because hashed values are represented as 64-bit integers, you must use the NumberLong type when specifying these bounds [1][2][3][4].

Citations:


Use a range-based shard key for test.test, or use hashed chunk bounds. sharded.json configures { _id: "hashed" }. Therefore, sh.moveChunk() and sh.splitFind() reject these calls. The catch blocks hide each failure, so the loop produces no move or split events. The image’s mongosh shell provides both helpers with the expected signatures.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded-with-pmm.sh` around lines
316 - 325, Update the test.test sharding setup around sh.moveChunk and
sh.splitFind to use bounds compatible with the configured hashed _id shard key,
or change the collection to a range-based shard key. Ensure the moveChunk and
splitFind calls use valid hashed chunk-bound arguments so they execute
successfully, while preserving the existing target iteration and inserted
document flow.

docker compose -f docker-compose-sharded.yaml exec -T mongos mgodatagen -f /etc/datagen/sharded.json --uri=mongodb://root:root@127.0.0.1:27017

echo "writing chunk-activity generator so the chunk-move/split dashboards keep getting data"
docker compose -f docker-compose-sharded.yaml exec -T mongos tee /tmp/keep_chunks_moving.js > /dev/null << 'JSEOF'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- target script context ---'
sed -n '290,355p' qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh
printf '%s\n' '--- all generated-path references ---'
rg -n -C 3 'keep_chunks_moving|docker compose.*mongos|JSEOF' qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh
printf '%s\n' '--- container user and compose mounts ---'
sed -n '1,180p' qa-integration/pmm_psmdb-pbm_setup/docker-compose-sharded.yaml
printf '%s\n' '--- repository guidance files ---'
find . -maxdepth 3 -type f \( -iname 'README*' -o -iname '*CONTRIBUTING*' -o -iname '*GUIDELINE*' \) -print

Repository: percona/pmm-qa

Length of output: 12651


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- relevant compose services ---'
rg -n -A35 -B8 '^[[:space:]]+mongos:|^[[:space:]]+test:' qa-integration/pmm_psmdb-pbm_setup/docker-compose-sharded.yaml
printf '%s\n' '--- setup documentation ---'
sed -n '1,220p' qa-integration/pmm_psmdb-pbm_setup/readme.md
printf '%s\n' '--- image and privilege declarations ---'
rg -n -C 3 'FROM|USER|privileged|volumes:|mongos|test' qa-integration/pmm_psmdb-pbm_setup/Dockerfile qa-integration/pmm_psmdb-pbm_setup/docker-compose-sharded.yaml
printf '%s\n' '--- script lifecycle and cleanup ---'
sed -n '1,90p' qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh
sed -n '343,390p' qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh

Repository: percona/pmm-qa

Length of output: 44242


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- test image capabilities and Docker access ---'
sed -n '1,220p' qa-integration/pmm_psmdb-pbm_setup/Dockerfile-testinfra
rg -n -C 4 'docker|exec|mongos|keep_chunks|/tmp' qa-integration/pmm_psmdb-pbm_setup/test qa-integration/pmm_psmdb-pbm_setup/*.sh
printf '%s\n' '--- image user declarations ---'
rg -n '^[[:space:]]*USER[[:space:]]|^[[:space:]]*ENTRYPOINT|^[[:space:]]*CMD' qa-integration/pmm_psmdb-pbm_setup/Dockerfile qa-integration/pmm_psmdb-pbm_setup/Dockerfile-testinfra || true
printf '%s\n' '--- deterministic path and symlink check ---'
python3 - <<'PY'
from pathlib import Path
script = Path("qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh").read_text()
compose = Path("qa-integration/pmm_psmdb-pbm_setup/docker-compose-sharded.yaml").read_text()
paths = ["/tmp/keep_chunks_moving.js", "/tmp/keep_chunks_moving.sh", "/tmp/keep_chunks_moving.log"]
print("generated_paths:", paths)
print("all_paths_in_script:", all(p in script for p in paths))
print("mongos_service_privileged:", "  mongos:" in compose and "    privileged: true" in compose[compose.index("  mongos:"):])
mongos = compose[compose.index("  mongos:"):compose.index("  minio:")]
print("mongos_has_tmp_mount:", "/tmp" in mongos)
print("mongos_has_user_override:", any(line.lstrip().startswith("user:") for line in mongos.splitlines()))
# Demonstrate the relevant filesystem property without touching repository files.
import tempfile, os
with tempfile.TemporaryDirectory() as d:
    target = Path(d) / "target"
    link = Path(d) / "fixed-name"
    target.write_text("original")
    link.symlink_to(target)
    with link.open("w") as f:
        f.write("overwritten")
    print("ordinary_writer_follows_precreated_symlink:", target.read_text() == "overwritten")
PY

Repository: percona/pmm-qa

Length of output: 50370


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- focused verifier output ---'
python3 - <<'PY'
from pathlib import Path
script = Path("qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh").read_text()
compose = Path("qa-integration/pmm_psmdb-pbm_setup/docker-compose-sharded.yaml").read_text()
paths = ["/tmp/keep_chunks_moving.js", "/tmp/keep_chunks_moving.sh", "/tmp/keep_chunks_moving.log"]
mongos = compose[compose.index("  mongos:"):compose.index("  minio:")]
print("generated_paths:", all(p in script for p in paths))
print("mongos_privileged:", "    privileged: true" in mongos)
print("mongos_tmp_mount:", "/tmp" in mongos)
print("mongos_user_override:", any(x.lstrip().startswith("user:") for x in mongos.splitlines()))
import tempfile
with tempfile.TemporaryDirectory() as d:
    target, link = Path(d)/"target", Path(d)/"fixed-name"
    target.write_text("original")
    link.symlink_to(target)
    link.write_text("overwritten")
    print("writer_follows_precreated_symlink:", target.read_text() == "overwritten")
PY
printf '%s\n' '--- test sources with Docker or container access ---'
find qa-integration/pmm_psmdb-pbm_setup/test -maxdepth 2 -type f -print
rg -n -C 2 --glob '*.py' 'docker|Docker|exec|mongos|/tmp|subprocess' qa-integration/pmm_psmdb-pbm_setup/test || true

Repository: percona/pmm-qa

Length of output: 3831


Use a private temporary directory for the generator files. tee and shell redirection follow pre-existing symlinks. Create a mktemp -d directory inside mongos, use quoted paths for all three files, and remove it when the background process exits.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh` at line 319, Update the
generator-file setup around the mongos tee command to create a private mktemp -d
directory inside the container, and store all three generated files there using
quoted paths. Ensure the temporary directory is removed when the background
process exits, while preserving the existing generator execution flow.

Source: Linters/SAST tools

Comment on lines +329 to +333
try {
sh.splitFind("test.test", { _id: ins.insertedId });
} catch (e) {
print("splitFind failed, skipping: " + e);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- target context ---'
sed -n '300,350p' qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh
printf '%s\n' '--- shard-key and split-related references ---'
rg -n -C 3 'splitFind|split|shardCollection|shard key|shardKey|hashed|test\.test' qa-integration/pmm_psmdb-pbm_setup
printf '%s\n' '--- MongoDB image/version declarations ---'
rg -n -i 'mongo.*(image|version)|mongodb|percona-server-mongodb|psmdb' qa-integration/pmm_psmdb-pbm_setup .github docker-compose*.yml 2>/dev/null | head -200

Repository: percona/pmm-qa

Length of output: 35832


🌐 Web query:

MongoDB sh.splitFind hashed shard key find form split command bounds behavior

💡 Result:

In MongoDB, for collections using a hashed shard key, you should not use sh.splitFind to manually split chunks [1][2]. The split command requires the bounds parameter to split chunks in hashed sharded collections, rather than the find parameter used by sh.splitFind [1][2]. The reasons and behavior are as follows: 1. Parameter Mismatch: The sh.splitFind method wraps the split database command using the find parameter [3][4]. However, the documentation for the split command explicitly states that you must use the bounds parameter for collections partitioned using a hashed shard key [1][2]. 2. Bounds Requirement: The bounds parameter requires an array containing two documents that specify the exact minimum and maximum shard-key values of the existing chunk you intend to split [1][2]. These values must match the current chunk's boundaries, which can be identified using sh.status [1][2]. 3. Median Splitting: When the bounds parameter is used correctly, MongoDB splits the chunk along its median [1][2]. The split command cannot use the find or middle parameters for hashed shard keys because hashed shards rely on specific, pre-defined chunk ranges rather than the query-based discovery used by sh.splitFind [1][2]. Attempting to use sh.splitFind on a hashed sharded collection may fail or behave unexpectedly because it is designed for range-based sharding where the query can identify a document within a chunk to determine the split point, which is not applicable to the distribution logic of hashed shard keys [3][1]. To manually split a hashed chunk, you should invoke the split command directly via db.adminCommand using the bounds option [1][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -eu
python3 - <<'PY'
import json
from pathlib import Path

setup = Path("qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh").read_text()
config = json.loads(Path("qa-integration/pmm_psmdb-pbm_setup/conf/datagen/sharded.json").read_text())

collection = config["collections"][0]
shard_config = collection["shardConfig"]
key = shard_config["key"]

print("collection:", f'{shard_config["shardCollection"]}')
print("shard_key:", key)
print("insert_target_present:", 'getSiblingDB("test").test.insertOne' in setup)
print("splitFind_present:", 'sh.splitFind("test.test", { _id: ins.insertedId })' in setup)
print("catch_logs_and_skips:", 'print("splitFind failed, skipping: " + e);' in setup)
print("hashed_id_for_test.test:", shard_config["shardCollection"] == "test.test" and key == {"_id": "hashed"})
PY

Repository: percona/pmm-qa

Length of output: 285


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- sharded data generator ---'
cat -n qa-integration/pmm_psmdb-pbm_setup/conf/datagen/sharded.json
printf '%s\n' '--- focused consistency check ---'
python3 - <<'PY'
import json
from pathlib import Path

setup = Path("qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh").read_text()
data = json.loads(Path("qa-integration/pmm_psmdb-pbm_setup/conf/datagen/sharded.json").read_text())

matches = []
for item in data:
    shard_config = item.get("shardConfig", {})
    if shard_config.get("shardCollection") == "test.test":
        matches.append((item.get("collection"), shard_config.get("key")))

print("test.test shard configuration:", matches)
print("insert_target_present:", 'getSiblingDB("test").test.insertOne' in setup)
print("splitFind_present:", 'sh.splitFind("test.test", { _id: ins.insertedId })' in setup)
print("failure_is_swallowed:", 'print("splitFind failed, skipping: " + e);' in setup)
PY

Repository: percona/pmm-qa

Length of output: 1163


Use bounds for the hashed-key split.

test.test uses the hashed _id shard key. sh.splitFind() does not support hashed shard keys. Resolve the current chunk bounds and run adminCommand({ split: "test.test", bounds: [...] }); otherwise, the catch logs the failure and no split events reach the dashboard.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh` around lines 329 - 333,
Replace the sh.splitFind call in the hashed-key setup flow with logic that
resolves the current chunk bounds for test.test and invokes adminCommand using
split: "test.test" and those bounds. Preserve the existing failure handling and
ensure the split command executes successfully so split events are emitted.

Source: MCP tools

Comment on lines +342 to +343
echo "starting background chunk-activity generator"
docker compose -f docker-compose-sharded.yaml exec -d mongos bash /tmp/keep_chunks_moving.sh

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Install cleanup before launching the detached loop.

The loop starts before the tests, but cleanup runs only after the tests complete. With set -e, any later failure exits before Lines 353-356, leaving the detached process and Compose stack running. Register an EXIT trap before Line 343 and make the trap honor CLEANUP=no.

🧰 Tools
🪛 ast-grep (0.45.1)

[warning] 342-342: Writing to or reading from a hardcoded, predictable path under /tmp is vulnerable to symlink and TOCTOU attacks: a local attacker can pre-create the file (or a symlink pointing elsewhere) and hijack or corrupt the contents. Generate a unique, unpredictable temporary file with mktemp instead, e.g. tmpfile="$(mktemp)" (or mktemp -d for directories) and reference "$tmpfile".
Context: /tmp/keep_chunks_moving.sh
Note: [CWE-377] Insecure Temporary File.

(predictable-tmp-file-bash)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qa-integration/pmm_psmdb-pbm_setup/start-sharded.sh` around lines 342 - 343,
Register an EXIT cleanup trap before launching the detached
keep_chunks_moving.sh process, using the existing cleanup behavior and honoring
CLEANUP=no. Ensure the trap stops the background generator and Compose stack
even when set -e exits before the current post-test cleanup block, while
preserving normal cleanup behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants