Disruptive tasks corrupt shared state (static pod manifests, kubelet
config, CoreDNS) keyed by a "breaks" target, but a session's setup only
touches the questions it actually contains. If a task isn't re-picked in
a later session, its damage lingers indefinitely - e.g. Q39 wrecking W1's
kubelet config persisted across two unrelated TSHOOT drills that never
included Q39 again.
Add restore_baseline(), run unconditionally in begin_session() before
seeding, that repairs every known "breaks" target (scheduler,
controller-manager, CoreDNS, all three worker kubelets, W1's demo
taints) regardless of which questions are in the new session. Hard-mode-
only breaks (etcd, certs, apiserver) aren't covered yet.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The Q02/Q102 seeds tried to copy etcdctl out of the running etcd pod with
`kubectl exec -- cat`, which cannot work: registry.k8s.io/etcd is distroless
(no cat, no sh, no tar). The copy failed, stderr went to /dev/null and seeding
still printed a green tick, so the snapshot task had no etcdctl on the node.
Q102 was worse: it also ran `exec -- sh -c 'etcdctl ... snapshot save'` inside
that container, so its /opt/cka/backup.db was never created at all.
- etcd-tools.sh installs both binaries on the control-plane node, taking them
from the etcd image already in the node's containerd (offline, exactly the
server version), falling back to the upstream release tarball, then apt.
- setup.sh runs it at bootstrap; ensure_etcd_tools in the exam prelude installs
them through CKA_NODE_ACCESS when a task is seeded, so ssh/vagrant clusters
get them too, and both etcd setups now fail with a reason instead of hiding it.
- Q102 takes its snapshot with the node's etcdctl; Q02 no longer documents a
kubectl cp fallback that cannot work on a distroless image.
Co-authored-by: Junie <junie@jetbrains.com>