mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Valery Kharseko
20 hours ago a887d5fe9697eb70447b654c7d63f59f9f0a031a
Wait for the background join to end before looking for the root password it leaves (#1193)

## Problem

Since #1184, `build-docker` and `build-docker-alpine` fail every time,
on master too (run 38390334148) and on every PR (e.g. #1190, run
38382364790):

```
=== [2608 s] pre-roles srs volume
##[error]the root password is left in /dev/shm/opendj-join.4444.YKR3cc of dj-1
```

The phase "pre-roles srs volume"
(`.github/scripts/docker-test-replication.sh`) recreates dj-1 on its
kept volume, which has neither `.initialize-pending` nor
`.rejoin-pending`. So `run.sh` writes the health marker at once and
starts `join.sh` in the background. The test waits for "already a member
of the replication topology" and for `healthy`, which both hold at once,
and runs the password check straight away. At that point `join.sh` is
still in `joined()` (`cleanup_departed`, `publish_state`,
`repair_replication_servers`) and keeps its password file in `/dev/shm`.
Its EXIT trap removes the file only when it ends. The dj-1 log in CI
does not even show "the health check may probe it" yet.

The image itself is fine: the file goes away when the join ends. The
test checks too early. It slipped through because only the role phases,
not the whole script, ran locally in round 4 of #1184.

## Fix

- `bootstrap_ended <container>`: true once no `bootstrap/join.sh` or
`bootstrap/replicate.sh` process is left in the container. It looks for
them in `/proc/*/cmdline`; the bracket in `[j]oin` keeps the pattern
from matching the `sh -c` that greps for it.
- The password check waits up to 300 s for it on each container. A join
that never ends still fails the test, by timeout.

## Testing

- `bash -n` passes.
- The helper was run against a stand-in `bootstrap/join.sh` /
`bootstrap/replicate.sh` (`sleep 8`) in `ubuntu:24.04`, `alpine:3.20`
and the OpenDJ image: "running" while the script runs, "ended" after it.
The image's PID 1 is `/opt/opendj/run.sh`, which does not match.
- The whole Docker replication test was not run locally. The
`build-docker` jobs of this PR are the check.
1 files modified
9 ■■■■■ changed files
.github/scripts/docker-test-replication.sh 9 ●●●●● patch | view | raw | blame | history
.github/scripts/docker-test-replication.sh
@@ -175,6 +175,14 @@
  docker exec "$1" cat /opt/opendj/data/.replication-role 2>/dev/null
}
# no join.sh or replicate.sh runs in the container any more. A volume that holds the data
# reports itself healthy from the start while its join still runs, and the join keeps its
# password file until it ends. The bracket keeps the pattern from matching the command line
# of the sh that greps for it
bootstrap_ended() { # <container>
  ! docker exec "$1" sh -c "grep -qs -e 'bootstrap/[j]oin\.sh' -e 'bootstrap/[r]eplicate\.sh' /proc/[0-9]*/cmdline"
}
# the writability-mode the backend of dc=example,dc=com is configured with, empty where its
# entry sets none
backend_mode() { # <container>
@@ -770,6 +778,7 @@
# the root password shows in no container log, and the files the tools read it from are gone
for c in dj-0 dj-1 dj-2 dj-sdsr; do
  wait_until 300 "the bootstrap scripts of $c end" bootstrap_ended $c
  if docker logs $c 2>&1 | grep -F -- "$ROOT_PASSWORD"; then fail "the root password is in the log of $c"; fi
  left=$(docker exec $c grep -rlsF -- "$ROOT_PASSWORD" /tmp /dev/shm || true)
  [ -z "$left" ] || fail "the root password is left in $left of $c"