v0.318.0: the internal data place, partitions, an honest whole-box backup offer (R-1084), sys_drive never offered (R-1082)
gates / gates (push) Successful in 46s

felhom.eu architecture/16 §4-§6 (build B). MinAgent 0.157.0 — the internal place and the partitions appear only when
agent >= 0.158.0 reports them. Tests red-proved; four parity fixtures refreshed (only the new lines).

Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
This commit is contained in:
2026-10-16 03:57:49 +02:00
parent 123d2d553f
commit a43d0423d5
28 changed files with 913 additions and 26 deletions
@@ -86,6 +86,14 @@ func resolveEnrollUUID(ctx context.Context, agent diskAgent, device string) stri
return rest
}
}
// `16` §6 (agent ≥ 0.158.0): a formatted PART reports its new filesystem under the disk's partitions.
for _, p := range c.Partitions {
if p.Device == device {
if rest, ok := strings.CutPrefix(p.DurableID, "uuid:"); ok {
return rest
}
}
}
}
return ""
}
@@ -503,6 +511,9 @@ func (s *Server) handleStorageDecommission(w http.ResponseWriter, r *http.Reques
if s.refuseNetworkLifecycle(w, req.Where) {
return
}
if s.refuseInternalLifecycle(w, r, req.Where) { // v0.318.0 `16` §5
return
}
switch req.Mode {
case "migrate":
@@ -651,6 +662,14 @@ func (s *Server) handleStorageInit(w http.ResponseWriter, r *http.Request) {
writeDiskJSON(w, http.StatusBadRequest, false, s.msg(r, "disk.err.device_required"), nil)
return
}
// `16` §6 (v0.318.0): never format a device that backs a REGISTERED drive — the whole disk under a registered part
// included. The list (dropRegisteredDrives) already hides it; this is the server-side half, so a stale page or a
// direct call cannot reach it. A FREE part next to the registered one is allowed (the agent and its root wrapper
// re-check, as root).
if deviceBacksRegistered(req.Device, s.mountTable(), s.registeredStoragePaths()) {
writeDiskJSON(w, http.StatusConflict, false, s.msg(r, "err.web.meghajto_hasznalatban_formazas"), nil)
return
}
agent, err := s.agentClient()
if err != nil {
writeDiskJSON(w, http.StatusServiceUnavailable, false, s.errText(r, err), nil)
@@ -764,6 +783,9 @@ func (s *Server) handleStorageWipe(w http.ResponseWriter, r *http.Request) {
if s.refuseNetworkLifecycle(w, req.Where) {
return
}
if s.refuseInternalLifecycle(w, r, req.Where) { // v0.318.0 `16` §5
return
}
// Server-side type-to-confirm: the typed name must match the mount's basename exactly.
if strings.TrimSpace(req.MountName) != path.Base(req.Where) {
writeDiskJSON(w, http.StatusBadRequest, false, s.msg(r, "disk.err.name_mismatch"), nil)
@@ -982,6 +1004,9 @@ func (s *Server) handleStorageEject(w http.ResponseWriter, r *http.Request) {
if s.refuseNetworkLifecycle(w, req.Where) {
return
}
if s.refuseInternalLifecycle(w, r, req.Where) { // v0.318.0 `16` §5
return
}
agent, err := s.agentClient()
if err != nil {
writeDiskJSON(w, http.StatusServiceUnavailable, false, s.errText(r, err), nil)