# Test Environment for trim_excess_metadata.sh ## Overview This directory contains scripts that take a **Battle School Workshop** lab from its default "Lab 0" baseline to a state where `trim_excess_metadata.sh` can be run and end-to-end tested against a realistic post-divestiture Perforce server. These scripts automate the manual setup that would otherwise take 20–30 minutes of careful interactive work. They are intended for: - Developers and QA engineers iterating on the trim script - Future AI agents re-running tests after a lab reset - Documentation of the exact procedure needed to reproduce test conditions --- ## Dependency: Battle School Workshop Lab Environment **This test harness requires the Battle School Workshop lab.** Battle School is a Perforce-internal training and dev/test environment that provides pre-configured, safe-to-play, non-production lab instances running the full SDP (Server Deployment Package) stack. It is an excellent platform for developing and validating admin scripts that require sophisticated, realistic multi-server topologies — without any risk to production data. ### Lab 0 Topology (5 servers, same subnet) | Host | Role | ServerID | Port | |---------------|--------------------------|--------------------|------| | p4c-bos-01 | Commit (master) | commit.p4demo.1 | 1999 | | p4c-bos-02 | HA standby | p4d_ha_bos | 1999 | | p4c-nyc-03 | DR standby (sacrificed) | p4d_fs_nyc | 1999 | | p4c-syd-04 | Edge | p4d_edge_syd | 1999 | | p4c-syd-05 | Edge HA | p4d_ha_edge_syd | 1999 | All servers are SDP-managed, SSH-accessible as the `perforce` OS user without a password (from bos-01 and among themselves). The lab ships with sample depot data in `//depot/...` (Jam, OpenOffice source, etc.) and a set of standard users, groups, clients, and jobs. **Why nyc-03?** It is the DR standby — the most expendable server in the topology. We transform it into a simulated "divested unit" that was originally a filtered forwarding replica promoted to a standalone commit server. --- ## What the Setup Simulates The scenario is a **filtered-replication divestiture**: 1. A company ran a Perforce filtered forwarding replica that only replicated two depots (`//jam/...` and `//pb/...`) out of many. 2. That replica was promoted to a fully standalone commit server. 3. `trim_excess_metadata.sh` needs to clean up the leftover metadata on that server: users, clients, groups, labels, branches, jobs, server specs, remote specs, typemap, triggers, protections, depot specs, and finally snap the lazy-copy archive links and delete orphaned archive directories. ### Key complexity: lazy-copy archive leakage Perforce uses lazy copy for branching — `//jam/...` files branched from `//depot/Jam/...` share physical archive files. When the replica's RevisionDataFilter keeps `//jam/...` but filters out `//depot/...`, `p4verify` still pulls the `//depot/...` archive files because `//jam/...` needs them. After promotion to standalone, `//depot/...` has 0 db.rev records (looks empty) but `p4 depot -df` refuses to delete it because db.storage still has entries. The correct resolution is: 1. `p4 snap //jam/... //pb/...` — breaks lazy-copy links (gives kept depots their own physical archive copies) 2. Journal patch (`p4d -jr`) — removes the depot spec from db.domain 3. `rm -rf` the orphaned archive directories (Phase 18 output) --- ## Scripts | Script | Runs on | Purpose | |-------------------------|------------|---------| | `setup_lab.sh` | p4c-bos-01 | Full Lab 0 → trim-ready setup (orchestrates all steps, SSHes to nyc-03 as needed) | | `run_trim_test.sh` | p4c-bos-01 | Run trim script: dry run → live → snap; show journal patch apply command | --- ## Quick Start From **p4c-bos-01** as the `perforce` OS user: ```bash # 1. Reset lab to Lab 0 baseline (via Battle School UI or reset tool) # 2. Run setup (takes ~5 minutes; p4verify pulling archives is the slow part) cd /home/perforce/tem/test bash setup_lab.sh # 3. Run the trim test bash run_trim_test.sh ``` After `run_trim_test.sh` completes, it prints the journal patch path and the exact `p4d -jr` command to apply it. The patch file must be copied to nyc-03 before applying: ```bash JNL=/home/perforce/tem/trim_excess_metadata..jnl scp "$JNL" perforce@p4c-nyc-03:/tmp/ ssh perforce@p4c-nyc-03 "sudo systemctl stop p4d_1 && \ p4d -r /p4/1/root -jr /tmp/$(basename $JNL) && \ sudo systemctl start p4d_1" ``` Then verify and clean up orphaned archives (rm -rf commands are in Phase 18 output and the trim script summary): ```bash export P4CONFIG=/home/perforce/tem/.p4config.gf p4 verify //jam/... //pb/... ssh perforce@p4c-nyc-03 'rm -rf /p4/1/depots/depot' ``` --- ## Expected Test Outcomes After a successful `run_trim_test.sh`: | Check | Expected | |-------|----------| | `p4 users` | `perforce` only | | `p4 groups` | `testers` only | | `p4 depots` | `jam`, `pb`, `Perforce` (remote), `spec`, `unload` | | `p4 clients` | `perforce`-owned clients only (or none) | | `p4 servers` | `p4d_commit_gf` only | | `p4 remotes` | none | | `p4 typemap` | empty | | `p4 triggers` | as per `default_triggers.p4s` | | `p4 verify //jam/... //pb/...` | no errors | | Journal patch exit code | 0 | | Trim script exit code (after snap) | 4 (4 shelved CL failures — expected, in filtered depots) | --- ## Keep Files (in /home/perforce/tem/) The trim script uses two keep files, created by `setup_lab.sh`: | File | Contents | Purpose | |------|----------|---------| | `keep_users.gf.txt` | `perforce` | Only the perforce admin survives the trim | | `keep_groups.gf.txt` | `testers` | Tests the last-group-member retry logic (Randall_Scott) | The `testers` group has `Randall_Scott` as its only member. Deleting `Randall_Scott` would fail with "last member of group testers" — a specific error the trim script handles by temporarily adding a placeholder owner, then deleting the user, then cleaning up. --- ## Notes and Gotchas - **Service user password**: After `mkrep.sh` creates `svc_p4d_ffr_gf`, the configurable `dm.user.resetpassword=1` marks the account as requiring a password reset. `setup_lab.sh` sets a known lab password and logs in. - **`p4d` vs `/p4/1/bin/p4d_1`**: Always use the `p4d` SDP wrapper; it calls the correct instance binary based on `$SDP_INSTANCE`. - **Service management**: Use `sudo systemctl start|stop|restart|status p4d_1` — not manual p4d invocations. `systemctl start` returns immediately; the service takes ~2–3 seconds to come online. - **`run.users.authorize=1`**: Do NOT remove this security configurable. The `setup_lab.sh` ensures the perforce user is logged in before running trim. - **Server promotion**: nyc-03 gets a *new* ServerID (`p4d_commit_gf`) rather than reusing `p4d_ffr_gf`. Reusing the old ID would inherit scoped configurables like `db.replication=readonly`. - **auth.id**: After promotion, `auth.id` must be unset so the standalone handles its own authentication. - **journal patch file location**: `p4d -jr FILE` reads FILE from the local filesystem of the machine running p4d. If the trim script runs on bos-01 and p4d is on nyc-03, the .jnl file must be SCP'd to nyc-03 first.