Three minimal edits to close the orphan-OVS-port failure mode that
survives PR1a's systemd ordering fix (host crash, OOM-kill of ovsdb,
operator manually stopping OVS on a live host) and the
terminate-during-pending race that leaks taps when a user aborts a
slow launch.
1. SetupTapDevice (network.go): unconditional `ovs-vsctl --if-exists
del-port br-int <tap>` + separately-gated kernel `ip tuntap del`.
The previous kernel-side-gated cleanup missed orphan OVS ports
because OVS conf.db survives reboot while kernel taps don't.
Rejected `--may-exist add-port`: it would silently keep stale
external_ids:iface-id/attached-mac from a prior launch.
2. stopInstance mgmt-tap branch (daemon.go) + CleanupMgmtTapDevice
(network.go): derive the mgmt tap name from instance.ID rather
than reading instance.MgmtTap, since that field is set only after
SetupMgmtTapDevice returns and a terminate racing mid-launch
would skip cleanup. CleanupMgmtTapDevice gains a kernel-presence
short-circuit so unconditional invocation doesn't log spurious
"Device does not exist" errors for instances that never reached
SetupMgmtTapDevice.
3. LaunchInstance (daemon.go): `launchStillValid` helper re-checks
instance status before StartInstance and TransitionState, in
addition to the entry guard. On detection of shutting-down /
terminated, log Info and return nil — the concurrent terminate
goroutine owns cleanup; this is an expected race outcome, not an
error. Removes the spurious "Failed to transition instance to
running" ERROR that surfaced on every legitimate
terminate-during-pending. Plus the entry path now returns nil
instead of an error for the same reason.
Also lands `scripts/start-then-terminate-pending.sh` (added during
investigation) which reproduces the runtime race for manual
verification.
Bead: mulga-siv-20.2
Plan: docs/development/bugs/orphan-tap-on-launch-race.md (PR1b)