An action on a name that is no app answers 404, not 'settings cannot be saved' (found walking capability map B2 on 9202)
gates / gates (push) Successful in 27s
gates / gates (push) Successful in 27s
Test TestAnActionOnANameThatIsNoAppIsA404 red first. Commit only.
This commit is contained in:
1 parent
eed23e7594
commit
20c5877056
4 files changed
+44
-1
No files matched your search
@@ -40,6 +40,11 @@ night report (`audits/night-2026-10-28/`).
|
|||||||
and said once; no agent (9202) = Docker's flag only, as before. The inspect now reads `{{.Id}}` too. Tests
|
and said once; no agent (9202) = Docker's flag only, as before. The inspect now reads `{{.Id}}` too. Tests
|
||||||
`TestR528_*` (stacks, cmd/controller), red before the fix (the host-counted kill was not seen) or red-proved by
|
`TestR528_*` (stacks, cmd/controller), red before the fix (the host-counted kill was not seen) or red-proved by
|
||||||
mutation (the back-off, the wiring).
|
mutation (the back-off, the wiring).
|
||||||
|
- **Found walking the capability map's B2 on 9202 (small, fixed in the session):** a Stop/Start of a name that is no
|
||||||
|
app on the box (the bootstrap-managed `felhom-controller`) answered 500 „…az alkalmazás beállításai nem menthetők." —
|
||||||
|
the desired-state write's „not found" read as a save failure. `stacks.SetDesiredState` returns the
|
||||||
|
`ErrStackNotFound` kind with the household's sentence (`err.stacks.alkalmazas_nem_talalhato`); `actionStack` answers
|
||||||
|
404 before recording any intent. Nothing was ever stopped. Test `TestAnActionOnANameThatIsNoAppIsA404` (red first).
|
||||||
- **H8 — `internal/backup/restore_copy_sweep.go`:** an unused restore copy goes after 14 days. Every 6 hours
|
- **H8 — `internal/backup/restore_copy_sweep.go`:** an unused restore copy goes after 14 days. Every 6 hours
|
||||||
(`restore-copy-sweep`) a copy is removed only when the app has no restore hold of any kind, the app-stop marker is
|
(`restore-copy-sweep`) a copy is removed only when the app has no restore hold of any kind, the app-stop marker is
|
||||||
readable and does not name the app, no restore runs, and the copy is older than 14 days. Tests `TestR1256_H8_*`
|
readable and does not name the app, no restore runs, and the copy is older than 14 days. Tests `TestR1256_H8_*`
|
||||||
|
|||||||
@@ -771,6 +771,12 @@ func (r *Router) actionStack(w http.ResponseWriter, req *http.Request, action, n
|
|||||||
// above, so nothing is recorded for an action that was never going to happen.
|
// above, so nothing is recorded for an action that was never going to happen.
|
||||||
if desired, ok := desiredStateForAction(action); ok {
|
if desired, ok := desiredStateForAction(action); ok {
|
||||||
if derr := r.stackMgr.SetDesiredState(name, desired); derr != nil {
|
if derr := r.stackMgr.SetDesiredState(name, desired); derr != nil {
|
||||||
|
if errors.Is(derr, stacks.ErrStackNotFound) {
|
||||||
|
// no app by that name on this box (e.g. the bootstrap-managed controller): a 404, not a save failure
|
||||||
|
r.logger.Printf("[WARN] [api] %s for %s refused: no such app", action, name)
|
||||||
|
writeJSON(w, stackOpStatusFor(derr), apiResponse{OK: false, Error: r.errText(req, derr)})
|
||||||
|
return
|
||||||
|
}
|
||||||
r.logger.Printf("[ERROR] [api] %s for %s refused: could not record desired state: %v", action, name, derr)
|
r.logger.Printf("[ERROR] [api] %s for %s refused: could not record desired state: %v", action, name, derr)
|
||||||
writeJSON(w, http.StatusInternalServerError, apiResponse{
|
writeJSON(w, http.StatusInternalServerError, apiResponse{
|
||||||
OK: false,
|
OK: false,
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Found walking the capability map's B2 („App lifecycle") on 9202, 2026-10-28 night: a Stop of a name that is no app
|
||||||
|
// on this box (`felhom-controller` — bootstrap-managed, not a stack) answered 500 „…az alkalmazás beállításai nem
|
||||||
|
// menthetők." — the desired-state write's „not found" read as a save failure. It is a 404 now, before any intent is
|
||||||
|
// recorded. RED-PROOF: drop the ErrStackNotFound branch in actionStack → 500 → FAILS.
|
||||||
|
func TestAnActionOnANameThatIsNoAppIsA404(t *testing.T) {
|
||||||
|
r, _, _, _ := newSlice4Router(t)
|
||||||
|
for _, action := range []string{"stop", "start"} {
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
r.actionStack(w, httptest.NewRequest("POST", "/api/stacks/nosuchapp/"+action, nil), action, "nosuchapp")
|
||||||
|
var resp apiResponse
|
||||||
|
_ = json.Unmarshal(w.Body.Bytes(), &resp)
|
||||||
|
if w.Code != http.StatusNotFound {
|
||||||
|
t.Fatalf("%s of a name that is no app: %d %q — want 404", action, w.Code, resp.Error)
|
||||||
|
}
|
||||||
|
if strings.Contains(strings.ToLower(resp.Error), "mentheto") || strings.Contains(resp.Error, "menthetők") {
|
||||||
|
t.Fatalf("%s: the answer still blames a save: %q", action, resp.Error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,8 @@ package stacks
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"gitea.dooplex.hu/admin/felhom-controller/internal/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Desired-state values for AppConfig.DesiredState (R-166, decision D-b).
|
// Desired-state values for AppConfig.DesiredState (R-166, decision D-b).
|
||||||
@@ -57,7 +59,8 @@ func (m *Manager) SetDesiredState(name, desired string) error {
|
|||||||
|
|
||||||
stack, ok := m.GetStack(name)
|
stack, ok := m.GetStack(name)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("stack %q not found", name)
|
// a KIND (404 at the API) and the household's sentence — not a save failure
|
||||||
|
return util.MsgErrorf(ErrStackNotFound, "err.stacks.alkalmazas_nem_talalhato", name)
|
||||||
}
|
}
|
||||||
stackDir := filepath.Dir(stack.ComposePath)
|
stackDir := filepath.Dir(stack.ComposePath)
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user