mirror of
https://github.com/gadgethd/ukmesh.git
synced 2026-10-15 10:40:01 +00:00
fix(ops): cover partial newuser rollback failures
This commit is contained in:
+6
-3
@@ -617,9 +617,12 @@ else
|
||||
password="$(openssl rand -hex 24)"
|
||||
|
||||
log 'creating persistent Mosquitto credential'
|
||||
# Mark the transaction as owning this username before invoking the mutating
|
||||
# command. If it changes the passwd file and then exits unsuccessfully, EXIT
|
||||
# rollback must still remove the partial credential.
|
||||
credential_created=1
|
||||
docker exec "$MOSQUITTO_CONTAINER" \
|
||||
mosquitto_passwd -b /mosquitto/config/passwd "$username" "$password"
|
||||
credential_created=1
|
||||
# mosquitto only re-reads password_file on SIGHUP; the reconciler reloads
|
||||
# every ~60s but a device may connect before then, so reload immediately.
|
||||
docker exec "$MOSQUITTO_CONTAINER" sh -c 'kill -HUP 1' >/dev/null 2>&1 \
|
||||
@@ -715,10 +718,11 @@ else
|
||||
new_owner_map=$new_entry
|
||||
fi
|
||||
log 'adding deduplicated owner grant to OWNER_MQTT_USERNAME_MAP'
|
||||
replace_owner_map "$new_owner_map"
|
||||
env_changed=1
|
||||
replace_owner_map "$new_owner_map"
|
||||
|
||||
log 'inserting verified owner account and node grant rows'
|
||||
db_changed=1
|
||||
docker exec -i "$TIMESCALEDB_CONTAINER" \
|
||||
psql -X -q -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -d "$OWNER_DATABASE" \
|
||||
-v "mqtt_username=${username}" -v "node_ids=${key_csv}" >/dev/null <<'SQL'
|
||||
@@ -759,7 +763,6 @@ SET verification_method = 'operator-config',
|
||||
updated_at = NOW();
|
||||
COMMIT;
|
||||
SQL
|
||||
db_changed=1
|
||||
|
||||
log 'recreating only the backend to reconcile owner grants and reload the ACL'
|
||||
apply_backend_config
|
||||
|
||||
+28
-1
@@ -227,4 +227,31 @@ expected_map="OWNER_MQTT_USERNAME_MAP=alice=${NODE_A},bob=${NODE_C},charlie=${NO
|
||||
[[ $(<"$SANDBOX/repo/.env") == "$expected_map" ]] \
|
||||
|| { printf 'concurrent owner map lost a grant: %s\n' "$(<"$SANDBOX/repo/.env")" >&2; exit 1; }
|
||||
|
||||
printf 'newuser concurrent-discovery regression test passed\n'
|
||||
# Inject failures after each mutation class and check that EXIT rollback is
|
||||
# idempotent and restores the mocked broker/config/database state.
|
||||
for stage in credential environment db acl; do
|
||||
init_sandbox "rollback-${stage}" "alice=${NODE_A}"
|
||||
if run_newuser "$SANDBOX" "$SANDBOX/output.log" alice alice "$stage" dave "$NODE_B"; then
|
||||
printf 'expected injected %s failure\n' "$stage" >&2
|
||||
exit 1
|
||||
fi
|
||||
[[ $(<"$SANDBOX/repo/.env") == "OWNER_MQTT_USERNAME_MAP=alice=${NODE_A}" ]] \
|
||||
|| { printf '%s failure did not restore the environment map\n' "$stage" >&2; exit 1; }
|
||||
[[ ! -e $SANDBOX/credential-state ]] \
|
||||
|| { printf '%s failure left a broker credential behind\n' "$stage" >&2; exit 1; }
|
||||
[[ ! -e $SANDBOX/db-state ]] \
|
||||
|| { printf '%s failure left owner database state behind\n' "$stage" >&2; exit 1; }
|
||||
if [[ $stage == credential ]]; then
|
||||
assert_file_contains "$SANDBOX/docker.log" 'CREDENTIAL_DELETE dave'
|
||||
fi
|
||||
if [[ $stage == db || $stage == acl ]]; then
|
||||
assert_file_contains "$SANDBOX/docker.log" 'DB_ROLLBACK dave'
|
||||
fi
|
||||
if [[ $stage == acl ]]; then
|
||||
compose_count="$(grep -c '^COMPOSE_BACKEND$' "$SANDBOX/docker.log")"
|
||||
[[ $compose_count -ge 2 ]] \
|
||||
|| { printf 'ACL failure did not reapply restored backend config\n' >&2; exit 1; }
|
||||
fi
|
||||
done
|
||||
|
||||
printf 'newuser concurrency and rollback regression tests passed\n'
|
||||
|
||||
Reference in New Issue
Block a user