v0.236.0: "delete my data too" deletes the data, or says that it could not (R-442)
gates / gates (push) Successful in 13s
gates / gates (push) Successful in 13s
Removal resolves the drive from the app's own app.yaml HDD_PATH (the 07 ~L437 rule), never the global cfg.Paths.HDDPath which no box sets. A data removal that cannot be resolved, or whose drive is absent, is refused with a typed RemoveRefusedError -> 409 + exact Hungarian sentence, before compose down, and the app is kept. SSD app -> hdd_paths_removed: [] never null; missing folders stated; backup-path refusals reach the response. 15 tests, two red-proofs run (pre-fix fallback -> C fails with err=nil and the handler 200s; "no drive refuses" -> D fails). Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@@ -827,6 +828,13 @@ func (r *Router) removeStack(w http.ResponseWriter, req *http.Request, name stri
|
||||
resp, err := r.stackMgr.RemoveStack(name, body.RemoveHDDData, backupPaths)
|
||||
if err != nil {
|
||||
r.logger.Printf("[ERROR] [api] Remove failed for %s: %v", name, err)
|
||||
// R-442: a refused data removal is a first-class, non-2xx answer with the exact customer
|
||||
// sentence — never a 200 with empty lists. The app was not removed either.
|
||||
var refused *stacks.RemoveRefusedError
|
||||
if errors.As(err, &refused) {
|
||||
writeJSON(w, http.StatusConflict, apiResponse{OK: false, Error: refused.Message})
|
||||
return
|
||||
}
|
||||
status := http.StatusInternalServerError
|
||||
if strings.Contains(err.Error(), "protected") {
|
||||
status = http.StatusForbidden
|
||||
@@ -883,6 +891,11 @@ func (r *Router) deleteStack(w http.ResponseWriter, req *http.Request, name stri
|
||||
resp, err := r.stackMgr.DeleteStack(name, body.RemoveHDDData)
|
||||
if err != nil {
|
||||
r.logger.Printf("[ERROR] [api] Delete failed for %s: %v", name, err)
|
||||
var refused *stacks.RemoveRefusedError // R-442, same as removeStack
|
||||
if errors.As(err, &refused) {
|
||||
writeJSON(w, http.StatusConflict, apiResponse{OK: false, Error: refused.Message})
|
||||
return
|
||||
}
|
||||
status := http.StatusInternalServerError
|
||||
if strings.Contains(err.Error(), "protected") {
|
||||
status = http.StatusForbidden
|
||||
|
||||
Reference in New Issue
Block a user