virt: the description is an instance field, not a config key — set it with a PATCH

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 <noreply@anthropic.com>
This commit is contained in:
Mitchell-Johnson
2026-10-09 15:30:10 -07:00
co-authored by Claude Fable 5.1
parent 38675ce9af
commit b790b0c31c
+14 -2
View File
@@ -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)
}