Newer
Older
openstack-caracal-dc-dc / docs / audit / destroy-model-blast-radius-20260802.txt
destroy-model-blast-radius-20260802.txt
=======================================
Pre-mutation verification of `juju destroy-model vr1-dc0`, requested by the operator:
"We have had issues previously when a destroy has had a larger blast radius then
intended. Review and confirm that the command will only destroy what is intended."

Well-founded: this repo has a logged cascade (2026-07-21, a MAAS pod delete taking its
linked machine records with it). Everything below is MEASURED on the live controller
from the dc0 rack (D-138), not reasoned from the man page.

--------------------------------------------------------------------------------------
1. FLAG SEMANTICS -- `juju help destroy-model`, juju 3.6.27, THIS controller
--------------------------------------------------------------------------------------
Summary line: "Terminate all machines/containers and resources for a NON-CONTROLLER
model."  -> the controller model is out of scope BY DESIGN, not by our care.
  --no-prompt       EXISTS. (Confirmed -- the Details prose still says "-y", which is
                    STALE; the flag list is authoritative. Do not use -y.)
  --destroy-storage "Destroy all storage instances in the model"
  --release-storage "Release ... without destroying them"
  --force           "removes all units ... and, potentially, machines without giving
                    them the opportunity to shutdown cleanly"
  --no-wait         "Rush through model destruction without waiting for each step"
  --timeout         WARNING in help: --force WITH --timeout continues "without
                    consideration or respect for clean shutdown or resource cleanup"

--------------------------------------------------------------------------------------
2. WHAT IS ACTUALLY IN THE MODEL
--------------------------------------------------------------------------------------
  juju storage -m vr1-dc0      -> "No storage to display."   ZERO storage instances
  juju storage -m controller   -> "No storage to display."
  juju offers  -m vr1-dc0      -> EMPTY (no cross-model offers)
  juju models                  -> controller (1 machine) + vr1-dc0 (36 machines/45 units)

>>> FINDING A -- `--destroy-storage` IS A NO-OP HERE AND IS BEING DROPPED. <<<
The model has NO juju-managed storage, so the flag destroys nothing. I proposed the
DESTRUCTIVE storage flag for a model with no storage. ceph-osd's `osd-devices` are RAW
BLOCK DEVICES set by charm config, not juju storage instances -- which is exactly why
`juju storage` is empty. They are re-partitioned by MAAS at re-image. Neither storage
flag is required: juju only demands one when persistent storage exists.

>>> FINDING B -- NO CROSS-MODEL BLAST RADIUS. <<<
Zero offers means no other model consumes a relation from vr1-dc0, so nothing outside
this model loses an endpoint. The `controller` model is a separate model and is
explicitly out of destroy-model's scope.

--------------------------------------------------------------------------------------
3. WHAT HAPPENS TO THE NINE MAAS NODES
--------------------------------------------------------------------------------------
  maas dc0 maas get-config name=enable_disk_erasing_on_release -> false

So release does NOT trigger a disk-erase cycle; the nodes return to `Ready` promptly and
are re-imaged by the redeploy. (`disk_erase_with_secure_erase=true` /
`disk_erase_with_quick_erase=false` are the modes that WOULD apply if erasing were on --
they are inert while the master switch is false.)

MEASURED CORRECTION, recorded because a future session would guess it wrong: on the dc0
REGION VM the MAAS CLI profile is **`dc0`**, NOT `vr1-dc0-region`. The tool's own error
enumerated the valid choices. Profile names are PER HOST -- assert, never assume.

--------------------------------------------------------------------------------------
4. THE COMMAND, AS APPROVED FOR REVIEW
--------------------------------------------------------------------------------------
  juju destroy-model vr1-dc0 --force --no-prompt

DELIBERATELY NOT PASSED:
  --destroy-storage  no-op (Finding A) and it is the destructive one
  --release-storage  also unnecessary -- there is no storage to release
  --no-wait          help says it rushes steps; let each step complete
  --timeout          help warns --force + --timeout abandons clean shutdown

IN SCOPE:  the vr1-dc0 model only -- 45 units, 36 machines/containers.
OUT OF SCOPE, and none of it is touched: the `controller` model and the juju controller
VM, the MAAS region and its database, the 9 MAAS machine RECORDS (released to Ready, not
deleted), the rack host, the OPNsense edge, the apt caching proxy, the snap proxy, the
tofu substrate, and dc1 in its entirety.

POST-CHECKS (run immediately after, before recreating the model):
  (a) `juju models` shows ONLY `controller`
  (b) MAAS machine COUNT is unchanged and the 9 role nodes read `Ready` -- a DROP in
      count is the cascade signature from the 2026-07-21 incident and means STOP
  (c) `dc-cache-proxy.sh check dc0` and `dc-snap-proxy.sh check dc0` still PASS

--------------------------------------------------------------------------------------
5. CORRECTED BY PRIOR-RUN EVIDENCE THE REPO ALREADY HELD (operator direction)
--------------------------------------------------------------------------------------
Operator: "You have that information from previous teardowns for the juju release path
as we have run those commands many times ... find the previously logged information in
the repo. Log the commands and steps for future reference."

I said in section 4 that the release path was "the one thing I can't prove in advance".
THAT WAS WRONG -- it was already proven and logged, in docs/CURRENT-STATE.md under
"MODEL TEARDOWN 2026-07-31". Two corrections follow from it:

>>> CORRECTION 1 -- `--no-wait` BELONGS IN THE COMMAND. I had EXCLUDED it. <<<
I reasoned from `juju help` ("Rush through model destruction without waiting for each
individual step") that it was reckless. MEASURED 2026-07-31: the plain `destroy-model`
STALLED terminally -- "attempt 30 to destroy model failed (will retry): model not empty,
found 26 machines, 37 applications", flat ~19 minutes, application set byte-identical.
ALL 26 agents were `stopped`, so NO teardown hook could execute; units already in `error`
could never run their stop hooks. `--force --no-wait` cleared it (18 -> 5 -> 2, then
"Model destroyed."). On a model whose agents are stopped there is nothing to wait FOR.
The help text talks you out of the flag that actually works.

>>> CORRECTION 2 -- THE RELEASE PATH IS PROVEN, NOT UNKNOWN. <<<
After the 07-31 forced destroy: ALL NINE role nodes read `Ready / owner=None`, ZERO
stranded, and NO `maas machine release` was needed or run. enable_disk_erasing_on_release
=false, so no erase cycle. EXPECTED POST-STATE IS 9 Ready + 1 Deployed -- the controller
VM (`subtle-grouse`) stays Deployed because it lives in the `controller` model. A session
expecting 10 Ready raises a false alarm.

>>> ALSO RECOVERED: THE MODEL-CONFIG TRAP, WHICH IS LIVE FOR THIS REBUILD. <<<
`destroy-model` takes the model config with it. On 07-31 that silently removed Step 3.5's
`apt-mirror` and the spaces work, and "NOTHING in the repo would have caught it".
MEASURED 2026-08-02: this controller's model-defaults carry `apt-mirror =
http://10.12.8.4/ubuntu` AND NOTHING ELSE. Post-convergence that value is WRONG, and the
three settings this deploy needs -- apt-http-proxy, snap-http-proxy, snap-https-proxy --
were set at MODEL level and will be destroyed. Defaults are inherited by NEW models only,
so they must be corrected BEFORE `add-model`.

>>> AND THE VR0 POD WARNING DOES NOT APPLY. <<<
runbooks/phase-00-teardown-maas-reset.md:24-25 records that on VR0's virsh-POD MAAS,
"destroy-model DECOMPOSES the pod-composed machines (observed 3x)". VR1 uses per-machine
power_type=virsh, NOT pods (D-103/D-123), so there is nothing to decompose -- confirmed by
both VR1 teardowns. Do not import the VR0 procedure into a VR1 teardown.

ALL OF THE ABOVE IS NOW A REUSABLE PROCEDURE: runbooks/dc-dc-teardown-rollback.md,
"Path M -- JUJU MODEL teardown", M.0 through M.6.

--------------------------------------------------------------------------------------
6. FINAL COMMAND (supersedes section 4)
--------------------------------------------------------------------------------------
  juju destroy-model vr1-dc0 --force --no-wait --no-prompt

BLOCKED BY THE PERMISSION LAYER on 2026-08-02 and NOT RUN. No workaround attempted.