From b790b0c31c3b93b2e4dbd2123389d31ecf224cfc Mon Sep 17 00:00:00 2001 From: Mitchell-Johnson Date: Fri, 9 Oct 2026 15:30:10 -0700 Subject: [PATCH] =?UTF-8?q?virt:=20the=20description=20is=20an=20instance?= =?UTF-8?q?=20field,=20not=20a=20config=20key=20=E2=80=94=20set=20it=20wit?= =?UTF-8?q?h=20a=20PATCH?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found on the first live test on grid: incus config set refused 'description' and the whole limits save with it. Co-Authored-By: Claude Fable 5.1 --- internal/api/virt.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/internal/api/virt.go b/internal/api/virt.go index 56b2467..a997c41 100644 --- a/internal/api/virt.go +++ b/internal/api/virt.go @@ -388,6 +388,12 @@ func (s *Server) virtConfig(w http.ResponseWriter, r *http.Request) { return } var set, unset []string + desc, hasDesc := body["description"] + delete(body, "description") + if hasDesc && (len(desc) > 200 || strings.ContainsAny(desc, "\n\r")) { + jsonErr(w, 400, "bad value for description") + return + } for k, v := range body { v = strings.TrimSpace(v) ok := false @@ -400,8 +406,6 @@ func (s *Server) virtConfig(w http.ResponseWriter, r *http.Request) { ok = incus.ValidCron(v) case "snapshots.expiry": ok = incus.ValidExpiry(v) - case "description": - ok = len(v) <= 200 && !strings.ContainsAny(v, "\n\r") case "boot.autostart": ok = v == "" || v == "true" || v == "false" } @@ -429,6 +433,14 @@ func (s *Server) virtConfig(w http.ResponseWriter, r *http.Request) { for _, k := range unset { _, _ = s.virt.Cmd(ctx, "config", "unset", name, k).CombinedOutput() // unsetting what isn't set is fine } + if hasDesc { + // the description is a field of the instance, not a config key, so it goes in through the API + patch, _ := json.Marshal(map[string]string{"description": strings.TrimSpace(desc)}) + if out, err := s.virt.Cmd(ctx, "query", "-X", "PATCH", "-d", string(patch), "/1.0/instances/"+name).CombinedOutput(); err != nil { + jsonErr(w, 409, strings.TrimPrefix(strings.TrimSpace(string(out)), "Error: ")) + return + } + } log.Printf("virt: config %s set %v unset %v (from %s)", name, set, unset, clientIP(r)) w.WriteHeader(204) }