Operate
AgentDataVolume copy / node migration
Local-path and other topology-bound storage pins an AgentDataVolume claim to
one node after first consumer. When that node is full (for example z400 at
99% CPU) but another home-lab node has capacity (acer), create a new
destination volume and stream the contents across.
Claims are immutable. Anvil never mutates spec.claimName in place. Migration
always creates a second AgentDataVolume + PVC, copies bytes, then you switch
harness dataVolumeRefs through reviewed GitOps.
CRD: AgentDataVolumeCopy
Append-only maintenance object (same class as AgentAuthSession):
- not GitOps desired state
- immutable spec
- blocks AgentRuns that mount the source or destination while non-terminal
- phases:
Pending→WaitingForIdle→PreparingDestination→Streaming→Succeeded/Failed
Stream method
- Resolve source PVC node from PV
kubernetes.io/hostnameaffinity. - Ensure destination
AgentDataVolumeexists with the requestednodeSelector. - Start a source Job on the source node that serves
tar | ncon port 9876. - Start a destination Job on the destination node that mounts the new claim (first consumer binds local-path), connects to the source Service, and extracts.
- Refuse non-empty destinations unless
allowNonEmptyDestination: true.
CLI
anvil-agentctl volume copy \
-n hazy-trade \
--from hazy-trade-backlog-worker-hermes-home \
--to hazy-trade-backlog-worker-hermes-home-acer \
--node acer \
--generate-name hermes-to-acer-
Watch:
kubectl -n hazy-trade get agdvcopy -w
kubectl -n hazy-trade get agentdatavolume hazy-trade-backlog-worker-hermes-home-acer
After Succeeded:
- Point the harness
dataVolumeRefsat the destination volume name in GitOps. - Smoke an AgentRun on the new home.
- Keep the source volume until you deliberately retire it (never delete under load).
Example object
apiVersion: control.anvil.hazyforge.io/v1alpha1
kind: AgentDataVolumeCopy
metadata:
generateName: hermes-to-acer-
namespace: hazy-trade
spec:
sourceRef:
name: hazy-trade-backlog-worker-hermes-home
destination:
name: hazy-trade-backlog-worker-hermes-home-acer
nodeSelector:
kubernetes.io/hostname: acer
method: Stream
timeoutSeconds: 1800
Safety
- Source and destination names must differ.
- Active AgentRuns on either volume set phase
WaitingForIdle. - Concurrent copies that share a volume name wait on each other.
- Destination empty-check protects against accidental clobber.
- Credential bytes are never placed in the copy CR.