diff --git a/.github/renovate.json b/.github/renovate.json index fc9ca5ece..7a238cb48 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -64,11 +64,12 @@ "managerFilePatterns": [ "/^postgres/Dockerfile$/" ], - "matchStrings": ["ENV PG_VERSION (?[\\d]+\\.[\\d]+)-[^\\n]+"], - "depNameTemplate": "postgres", - "datasourceTemplate": "docker", - "versioningTemplate": "semver-coerced", - "autoReplaceStringTemplate": "ENV PG_VERSION {{{newValue}}}-1.pgdg13+1" + "matchStrings": ["ENV PG_VERSION (?\\d+\\.\\d+-\\d+\\.pgdg\\d+\\+\\d+)"], + "depNameTemplate": "postgresql-18", + "datasourceTemplate": "deb", + "registryUrlTemplate": "https://apt.postgresql.org/pub/repos/apt?suite=trixie-pgdg&components=main&binaryArch=amd64", + "versioningTemplate": "deb", + "autoReplaceStringTemplate": "ENV PG_VERSION {{{newValue}}}" } ], "packageRules": [ @@ -80,12 +81,11 @@ }, { "matchPackageNames": [ - "postgres" + "postgresql-18" ], "matchFileNames": [ "postgres/Dockerfile" ], - "allowedVersions": "18.x", "groupName": "postgres Dockerfile" }, { @@ -114,7 +114,7 @@ { "matchPackageNames": [ "!/^github\\.com\\/sapcc\\/.*/", - "!postgres", + "!postgresql-18", "/.*/" ], "matchUpdateTypes": [ diff --git a/CHANGELOG.md b/CHANGELOG.md index b63bb230d..97d962776 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,63 @@ # Changelog +## 2026-08-24 — [#1154](https://github.com/cobaltcore-dev/cortex/pull/1154) + +### cortex v0.3.8 (sha-1742e3ee) + +New features: +- Apply jitter to failover revalidation requeue interval — adds a randomized jitter within [base/2, 3*base/2] to the failover reservation controller's revalidation interval, preventing thundering-herd effects when many reservations revalidate simultaneously ([#1147](https://github.com/cobaltcore-dev/cortex/pull/1147)) + +Bug fixes: +- Include response body in scheduler client error on non-200 status — the SchedulerClient now reads and includes the response body (capped at 1024 bytes) in error messages when the external scheduler returns a non-200 status code, improving debuggability of failover scheduling failures ([#1113](https://github.com/cobaltcore-dev/cortex/pull/1113)) +- Fix quota hardware version key in extraSpecs — corrects the key used to look up the hardware version in flavor extra specs for quota enforcement and capacity filtering ([#1149](https://github.com/cobaltcore-dev/cortex/pull/1149)) + +Non-breaking changes: +- Fix issues introduced with new linter version ([#1150](https://github.com/cobaltcore-dev/cortex/pull/1150)) +- Fix inaccurate live migration bullet in CR reservations docs ([#1138](https://github.com/cobaltcore-dev/cortex/pull/1138)) +- Fix renovate PG_VERSION matching to use debian deb datasource ([#1144](https://github.com/cobaltcore-dev/cortex/pull/1144)) +- Update `github.com/gophercloud/gophercloud/v2` to v2.14.0 ([#1151](https://github.com/cobaltcore-dev/cortex/pull/1151)) +- Update `k8s.io/api`, `k8s.io/apimachinery`, `k8s.io/client-go` to v0.36.4 ([#1151](https://github.com/cobaltcore-dev/cortex/pull/1151)) +- Update `github.com/sapcc` dependencies ([#1146](https://github.com/cobaltcore-dev/cortex/pull/1146)) +- Update `github.com/mattn/go-sqlite3` to v1.14.50 ([#1143](https://github.com/cobaltcore-dev/cortex/pull/1143)) +- Update `golangci-lint` to v2.13.1 ([#1148](https://github.com/cobaltcore-dev/cortex/pull/1148), [#1151](https://github.com/cobaltcore-dev/cortex/pull/1151)) +- Update `kube-prometheus-stack` to v88.5.2 ([#1145](https://github.com/cobaltcore-dev/cortex/pull/1145), [#1151](https://github.com/cobaltcore-dev/cortex/pull/1151)) + +### cortex-shim v0.1.14 (sha-1742e3ee) + +Includes updated dependencies (k8s.io v0.36.4, gophercloud v2.14.0). + +### cortex-postgres v0.6.14 + +Includes updated renovate configuration for PG_VERSION matching. + +### cortex-nova v0.0.88 + +Includes updated charts cortex v0.3.8 and cortex-postgres v0.6.14. + +### cortex-cinder v0.0.88 + +Includes updated charts cortex v0.3.8 and cortex-postgres v0.6.14. + +### cortex-manila v0.0.88 + +Includes updated charts cortex v0.3.8 and cortex-postgres v0.6.14. + +### cortex-crds v0.0.88 + +Includes updated chart cortex v0.3.8. + +### cortex-ironcore v0.0.88 + +Includes updated chart cortex v0.3.8. + +### cortex-pods v0.0.88 + +Includes updated chart cortex v0.3.8. + +### cortex-placement-shim v0.1.14 + +Includes updated chart cortex-shim v0.1.14. + ## 2026-08-17 — [#1139](https://github.com/cobaltcore-dev/cortex/pull/1139) ### cortex v0.3.7 (sha-67daed47) diff --git a/Makefile b/Makefile index e940d6453..5c58fa58f 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint GOTESTSUM = $(LOCALBIN)/gotestsum CONTROLLER_TOOLS_VERSION ?= v0.21.0 -GOLANGCI_LINT_VERSION ?= v2.12.2 +GOLANGCI_LINT_VERSION ?= v2.13.1 GOTESTSUM_VERSION ?= v1.13.0 .PHONY: controller-gen diff --git a/go.mod b/go.mod index 39642d8e9..df4fbc723 100644 --- a/go.mod +++ b/go.mod @@ -5,15 +5,15 @@ go 1.26.0 require ( github.com/cobaltcore-dev/openstack-hypervisor-operator v1.2.3 github.com/go-gorp/gorp v2.2.0+incompatible - github.com/gophercloud/gophercloud/v2 v2.13.0 + github.com/gophercloud/gophercloud/v2 v2.14.0 github.com/ironcore-dev/ironcore v0.5.0 github.com/prometheus/client_golang v1.24.1 github.com/prometheus/client_model v0.6.2 - github.com/sapcc/go-bits v0.0.0-20260813170327-ea1a14435d35 - go.xyrillian.de/gg v1.13.3 - k8s.io/api v0.36.3 - k8s.io/apimachinery v0.36.3 - k8s.io/client-go v0.36.3 + github.com/sapcc/go-bits v0.0.0-20260818140528-75bdd20c7867 + go.xyrillian.de/gg v1.14.0 + k8s.io/api v0.36.4 + k8s.io/apimachinery v0.36.4 + k8s.io/client-go v0.36.4 sigs.k8s.io/controller-runtime v0.24.1 ) @@ -33,7 +33,7 @@ require ( github.com/gofrs/uuid/v5 v5.5.1 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect - k8s.io/streaming v0.36.3 // indirect + k8s.io/streaming v0.36.4 // indirect ) require ( @@ -73,7 +73,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/lib/pq v1.12.3 - github.com/mattn/go-sqlite3 v1.14.49 + github.com/mattn/go-sqlite3 v1.14.50 github.com/moby/sys/user v0.4.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect @@ -87,7 +87,7 @@ require ( github.com/poy/onpar v0.3.5 // indirect github.com/prometheus/common v0.70.1 // indirect github.com/prometheus/procfs v0.21.1 // indirect - github.com/sapcc/go-api-declarations v1.24.0 + github.com/sapcc/go-api-declarations v1.25.0 github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/cobra v1.10.2 // indirect github.com/spf13/pflag v1.0.10 // indirect @@ -108,7 +108,7 @@ require ( go.yaml.in/yaml/v3 v3.0.4 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect - golang.org/x/net v0.57.0 // indirect + golang.org/x/net v0.58.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sync v0.22.0 golang.org/x/sys v0.47.0 // indirect diff --git a/go.sum b/go.sum index 9c4e7ac38..bf1971e7d 100644 --- a/go.sum +++ b/go.sum @@ -111,8 +111,8 @@ github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 h1:EwtI+Al+DeppwYX2oX github.com/google/pprof v0.0.0-20260402051712-545e8a4df936/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gophercloud/gophercloud/v2 v2.13.0 h1:yEyJG+kABd8x2ttTqLsomihU6Kg2YheJSZhvP/QSx+8= -github.com/gophercloud/gophercloud/v2 v2.13.0/go.mod h1:KZRLVs6gcoy/pEFdkZqFjdYqnS0emMHv66UqdM5lMjU= +github.com/gophercloud/gophercloud/v2 v2.14.0 h1:xGxKCvyaOxJDc5FqrnKDNqtdYn43ocQPuJ2Cm4KX/cs= +github.com/gophercloud/gophercloud/v2 v2.14.0/go.mod h1:4fs5I9VH6Wg2LyocDL9xf0ASb8VD63tyLA8sgAX/69U= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI= @@ -141,8 +141,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lib/pq v1.12.3 h1:tTWxr2YLKwIvK90ZXEw8GP7UFHtcbTtty8zsI+YjrfQ= github.com/lib/pq v1.12.3/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= -github.com/mattn/go-sqlite3 v1.14.49 h1:B8jBHC3xhxZgxztrgruTuLucebnULQnx4W7cF7SAE9w= -github.com/mattn/go-sqlite3 v1.14.49/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w= +github.com/mattn/go-sqlite3 v1.14.50 h1:dmdFvo1XG4MPzA4IkAmE9upVz/Nj31uRoM5+jC8hYbY= +github.com/mattn/go-sqlite3 v1.14.50/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w= github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs= github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -183,10 +183,10 @@ github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIj github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sapcc/go-api-declarations v1.24.0 h1:sGBvOMVSM1olJlyvNoQSk7NX5uatXHKkztGDBPnTWMs= -github.com/sapcc/go-api-declarations v1.24.0/go.mod h1:ZWRTijvgF8o8aHg5stgg7u4DF6jFrd0X97le/uGlZsA= -github.com/sapcc/go-bits v0.0.0-20260813170327-ea1a14435d35 h1:pTo+tUdMlRJRGY+MsAPeicedx58QYdnne8uWWufHA68= -github.com/sapcc/go-bits v0.0.0-20260813170327-ea1a14435d35/go.mod h1:oxx7AA+bHudahaXHEcg/Xk4avBckWR/rOOa0SAsuSgg= +github.com/sapcc/go-api-declarations v1.25.0 h1:vLkSVV8oaZExoBMEkwX31AqUjZIjwxKkxXr4q2sAAOg= +github.com/sapcc/go-api-declarations v1.25.0/go.mod h1:7NrwidCCv/MxwBpb/qqYLbQb/eY6rlnYkXwWMGx/wlI= +github.com/sapcc/go-bits v0.0.0-20260818140528-75bdd20c7867 h1:5cyIp5P6NKhmmvL3sXbgdYKwWtwKbPDzE1rzMzZvaH4= +github.com/sapcc/go-bits v0.0.0-20260818140528-75bdd20c7867/go.mod h1:rF/e0K3R9qDS3xqDl4nMAGOoelSkUumR4BNwuhSMgZk= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= @@ -231,8 +231,8 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo= go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q= -go.xyrillian.de/gg v1.13.3 h1:Ulz3+eZnO2OUl7Bv+SWaA5ufDmjeLwwmICPP4dCurxA= -go.xyrillian.de/gg v1.13.3/go.mod h1:DoO4fQSWIrBRlNlCjVyrYM0kAEBt/Jg2GkMH+cGRZ0k= +go.xyrillian.de/gg v1.14.0 h1:S19Jk3V1dcF9WdXQi7OGWjboVj8/40I4+/G1lZ6i4TI= +go.xyrillian.de/gg v1.14.0/go.mod h1:DoO4fQSWIrBRlNlCjVyrYM0kAEBt/Jg2GkMH+cGRZ0k= go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= @@ -243,8 +243,8 @@ golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1i golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk= golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40= -golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= -golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= +golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= +golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= @@ -285,24 +285,24 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -k8s.io/api v0.36.3 h1:NxB+05W2UGqXWFXcLO0RB5cnqnUPP5v5sVlaOH0Iz4w= -k8s.io/api v0.36.3/go.mod h1:JzLQKqRHC5+I8RVj/lS3lCg0mg6nWI9Fo/Sk3ElxHzg= +k8s.io/api v0.36.4 h1:RxrvqCL6vgH5/+UnTeu1IIFqYmGfy0hnyrod1rn35Oo= +k8s.io/api v0.36.4/go.mod h1:S2B3orCFBDhrgyWbLeuKcT2QdHIpQesBkCYSlWtwUOw= k8s.io/apiextensions-apiserver v0.36.0 h1:Wt7E8J+VBCbj4FjiBfDTK/neXDDjyJVJc7xfuOHImZ0= k8s.io/apiextensions-apiserver v0.36.0/go.mod h1:kGDjH0msuiIB3tgsYRV0kS9GqpMYMUsQ3GHv7TApyug= -k8s.io/apimachinery v0.36.3 h1:PkzMRBRG8joFD8EhCuQAtNPvJlxb82FwplP26HIzvAM= -k8s.io/apimachinery v0.36.3/go.mod h1:cTSjBWgPe/6CQyBKzY/hDIRWCQQQeK0mfLbml0UYFHE= +k8s.io/apimachinery v0.36.4 h1:PT2UzkupGuAx/+xT5XjiMJ1WGpY3fn9/hdAvjweRet4= +k8s.io/apimachinery v0.36.4/go.mod h1:p2I2dipt7JHG+quVwQ1d02d28O4GdDi77RByQ13MTpk= k8s.io/apiserver v0.36.0 h1:Jg5OFAENUACByUCg15CmhZAYrr5ZyJ+jodyA1mHl3YE= k8s.io/apiserver v0.36.0/go.mod h1:mHvwdHf+qKEm+1/hYm756SV+oREOKSPnsjagOpx6Vho= -k8s.io/client-go v0.36.3 h1:M4JdVzXxYcZk4fGpfDdYnxSwhLKWCFoQsHW6t+z8Hfg= -k8s.io/client-go v0.36.3/go.mod h1:gcPwr0c87vjjG6HB6pWEqOeuYVoXSsREjzux2j6GF30= +k8s.io/client-go v0.36.4 h1:MDvfDNvMSt0Br94SK8neviVlwL9qifw9B26hJCpD1K0= +k8s.io/client-go v0.36.4/go.mod h1:pNK4WKELbwlEDvtbE8l22lEZL5THYF61H5EealokZmA= k8s.io/component-base v0.36.0 h1:hFjEktssxiJhrK1zfybkH4kJOi8iZuF+mIDCqS5+jRo= k8s.io/component-base v0.36.0/go.mod h1:JZvIfcNHk+uck+8LhJzhSBtydWXaZNQwX2OdL+Mnwsk= k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hkbPJgdATINPMAxaynU2Ovg= k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0= -k8s.io/streaming v0.36.3 h1:9rAaqBk0C0Pc7+/fqGekj07NV+/Xrew58p647A0JT8w= -k8s.io/streaming v0.36.3/go.mod h1:z6fV3D+NVkoeqRMtWwlUZK6U17SY/LqNzOxWL6GyR/s= +k8s.io/streaming v0.36.4 h1:RS5YlhrdBN2pKGVjgygGntdu6SNdsduyjGWGe3cX0vo= +k8s.io/streaming v0.36.4/go.mod h1:tJ6S2bZa2HxIBauguBbCWSCYyd93Grfz1+z3tcOvlDE= k8s.io/utils v0.0.0-20260507154919-ff6756f316d2 h1:wU4tMEhLGgIbLvXQb1cfN+EcM0wf7zC6CPF+C79jroc= k8s.io/utils v0.0.0-20260507154919-ff6756f316d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec= diff --git a/helm/bundles/cortex-cinder/Chart.yaml b/helm/bundles/cortex-cinder/Chart.yaml index 259df2f77..92270d81f 100644 --- a/helm/bundles/cortex-cinder/Chart.yaml +++ b/helm/bundles/cortex-cinder/Chart.yaml @@ -5,23 +5,23 @@ apiVersion: v2 name: cortex-cinder description: A Helm chart deploying Cortex for Cinder. type: application -version: 0.0.87 +version: 0.0.88 appVersion: 0.1.0 dependencies: # from: file://../../library/cortex-postgres - name: cortex-postgres repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.6.13 + version: 0.6.14 # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.7 + version: 0.3.8 alias: cortex-knowledge-controllers # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.7 + version: 0.3.8 alias: cortex-scheduling-controllers # Owner info adds a configmap to the kubernetes cluster with information on diff --git a/helm/bundles/cortex-crds/Chart.yaml b/helm/bundles/cortex-crds/Chart.yaml index 639351774..08bbdb859 100644 --- a/helm/bundles/cortex-crds/Chart.yaml +++ b/helm/bundles/cortex-crds/Chart.yaml @@ -5,13 +5,13 @@ apiVersion: v2 name: cortex-crds description: A Helm chart deploying Cortex CRDs. type: application -version: 0.0.87 +version: 0.0.88 appVersion: 0.1.0 dependencies: # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.7 + version: 0.3.8 # Owner info adds a configmap to the kubernetes cluster with information on # the service owner. This makes it easier to find out who to contact in case diff --git a/helm/bundles/cortex-ironcore/Chart.yaml b/helm/bundles/cortex-ironcore/Chart.yaml index e72b63e3e..934ca3a57 100644 --- a/helm/bundles/cortex-ironcore/Chart.yaml +++ b/helm/bundles/cortex-ironcore/Chart.yaml @@ -5,13 +5,13 @@ apiVersion: v2 name: cortex-ironcore description: A Helm chart deploying Cortex for IronCore. type: application -version: 0.0.87 +version: 0.0.88 appVersion: 0.1.0 dependencies: # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.7 + version: 0.3.8 # Owner info adds a configmap to the kubernetes cluster with information on # the service owner. This makes it easier to find out who to contact in case diff --git a/helm/bundles/cortex-manila/Chart.yaml b/helm/bundles/cortex-manila/Chart.yaml index 73c6279a2..1c63ed8c4 100644 --- a/helm/bundles/cortex-manila/Chart.yaml +++ b/helm/bundles/cortex-manila/Chart.yaml @@ -5,23 +5,23 @@ apiVersion: v2 name: cortex-manila description: A Helm chart deploying Cortex for Manila. type: application -version: 0.0.87 +version: 0.0.88 appVersion: 0.1.0 dependencies: # from: file://../../library/cortex-postgres - name: cortex-postgres repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.6.13 + version: 0.6.14 # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.7 + version: 0.3.8 alias: cortex-knowledge-controllers # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.7 + version: 0.3.8 alias: cortex-scheduling-controllers # Owner info adds a configmap to the kubernetes cluster with information on diff --git a/helm/bundles/cortex-nova/Chart.yaml b/helm/bundles/cortex-nova/Chart.yaml index ffd98375f..7d1a29f9d 100644 --- a/helm/bundles/cortex-nova/Chart.yaml +++ b/helm/bundles/cortex-nova/Chart.yaml @@ -5,23 +5,23 @@ apiVersion: v2 name: cortex-nova description: A Helm chart deploying Cortex for Nova. type: application -version: 0.0.87 +version: 0.0.88 appVersion: 0.1.0 dependencies: # from: file://../../library/cortex-postgres - name: cortex-postgres repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.6.13 + version: 0.6.14 # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.7 + version: 0.3.8 alias: cortex-knowledge-controllers # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.7 + version: 0.3.8 alias: cortex-scheduling-controllers # Owner info adds a configmap to the kubernetes cluster with information on diff --git a/helm/bundles/cortex-placement-shim/Chart.yaml b/helm/bundles/cortex-placement-shim/Chart.yaml index ea9c69c2a..25e5915c5 100644 --- a/helm/bundles/cortex-placement-shim/Chart.yaml +++ b/helm/bundles/cortex-placement-shim/Chart.yaml @@ -5,13 +5,13 @@ apiVersion: v2 name: cortex-placement-shim description: A Helm chart deploying the Cortex placement shim. type: application -version: 0.1.13 +version: 0.1.14 appVersion: 0.1.0 dependencies: # from: file://../../library/cortex-shim - name: cortex-shim repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.1.13 + version: 0.1.14 # Owner info adds a configmap to the kubernetes cluster with information on # the service owner. This makes it easier to find out who to contact in case # of issues. See: https://github.com/sapcc/helm-charts/pkgs/container/helm-charts%2Fowner-info diff --git a/helm/bundles/cortex-pods/Chart.yaml b/helm/bundles/cortex-pods/Chart.yaml index 6ca4f7af1..7fdee3167 100644 --- a/helm/bundles/cortex-pods/Chart.yaml +++ b/helm/bundles/cortex-pods/Chart.yaml @@ -5,13 +5,13 @@ apiVersion: v2 name: cortex-pods description: A Helm chart deploying Cortex for Pods. type: application -version: 0.0.87 +version: 0.0.88 appVersion: 0.1.0 dependencies: # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.7 + version: 0.3.8 # Owner info adds a configmap to the kubernetes cluster with information on # the service owner. This makes it easier to find out who to contact in case diff --git a/helm/dev/cortex-prometheus-operator/Chart.yaml b/helm/dev/cortex-prometheus-operator/Chart.yaml index 110034136..6f1aeaee1 100644 --- a/helm/dev/cortex-prometheus-operator/Chart.yaml +++ b/helm/dev/cortex-prometheus-operator/Chart.yaml @@ -10,4 +10,4 @@ dependencies: # CRDs of the prometheus operator, such as PrometheusRule, ServiceMonitor, etc. - name: kube-prometheus-stack repository: oci://ghcr.io/prometheus-community/charts - version: 88.3.0 + version: 88.5.2 diff --git a/helm/library/cortex-postgres/Chart.yaml b/helm/library/cortex-postgres/Chart.yaml index 3445e5a1b..71bed9014 100644 --- a/helm/library/cortex-postgres/Chart.yaml +++ b/helm/library/cortex-postgres/Chart.yaml @@ -5,5 +5,5 @@ apiVersion: v2 name: cortex-postgres description: Postgres setup for Cortex. type: application -version: 0.6.13 +version: 0.6.14 appVersion: "sha-9f10115a" diff --git a/helm/library/cortex-shim/Chart.yaml b/helm/library/cortex-shim/Chart.yaml index a19fa31a0..4bbe67390 100644 --- a/helm/library/cortex-shim/Chart.yaml +++ b/helm/library/cortex-shim/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: cortex-shim description: A Helm chart to distribute cortex shims. type: application -version: 0.1.13 -appVersion: "sha-5809e5f3" +version: 0.1.14 +appVersion: "sha-1742e3ee" icon: "https://example.com/icon.png" dependencies: [] diff --git a/helm/library/cortex/Chart.yaml b/helm/library/cortex/Chart.yaml index be711e880..50907159c 100644 --- a/helm/library/cortex/Chart.yaml +++ b/helm/library/cortex/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: cortex description: A Helm chart to distribute cortex. type: application -version: 0.3.7 -appVersion: "sha-67daed47" +version: 0.3.8 +appVersion: "sha-77225628" icon: "https://example.com/icon.png" dependencies: [] diff --git a/internal/knowledge/datasources/plugins/openstack/controller_test.go b/internal/knowledge/datasources/plugins/openstack/controller_test.go index a809e099b..5e0bb69d1 100644 --- a/internal/knowledge/datasources/plugins/openstack/controller_test.go +++ b/internal/knowledge/datasources/plugins/openstack/controller_test.go @@ -9,7 +9,6 @@ import ( "github.com/cobaltcore-dev/cortex/api/v1alpha1" - "github.com/cobaltcore-dev/cortex/internal/knowledge/datasources" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -29,10 +28,9 @@ func TestOpenStackDatasourceReconciler_Creation(t *testing.T) { client := fake.NewClientBuilder().WithScheme(scheme).Build() reconciler := &OpenStackDatasourceReconciler{ - Client: client, - Scheme: scheme, - Monitor: datasources.Monitor{}, - conf: config{SchedulingDomain: "test-operator"}, + Client: client, + Scheme: scheme, + conf: config{SchedulingDomain: "test-operator"}, } if reconciler.Client == nil { diff --git a/internal/knowledge/datasources/plugins/prometheus/controller_test.go b/internal/knowledge/datasources/plugins/prometheus/controller_test.go index 9dfba9f3e..af2f32c0c 100644 --- a/internal/knowledge/datasources/plugins/prometheus/controller_test.go +++ b/internal/knowledge/datasources/plugins/prometheus/controller_test.go @@ -29,10 +29,9 @@ func TestPrometheusDatasourceReconciler_Creation(t *testing.T) { client := fake.NewClientBuilder().WithScheme(scheme).Build() reconciler := &PrometheusDatasourceReconciler{ - Client: client, - Scheme: scheme, - conf: config{SchedulingDomain: "test-operator"}, - Monitor: datasources.Monitor{}, + Client: client, + Scheme: scheme, + conf: config{SchedulingDomain: "test-operator"}, } if reconciler.Client == nil { diff --git a/internal/scheduling/nova/cr_metrics_test.go b/internal/scheduling/nova/cr_metrics_test.go index 6402950e9..2aa7a2cce 100644 --- a/internal/scheduling/nova/cr_metrics_test.go +++ b/internal/scheduling/nova/cr_metrics_test.go @@ -235,14 +235,12 @@ func TestLogNoHostFound(t *testing.T) { reg.MustRegister(counter) controller := &FilterWeigherPipelineController{ - BasePipelineController: lib.BasePipelineController[lib.FilterWeigherPipeline[api.ExternalSchedulerRequest]]{ - Client: fakeClient, - }, CRRecorder: crs.Recorder{ Client: fakeClient, NoHostFoundCounter: counter, }, } + controller.Client = fakeClient requestFlavorName := flavorName if tt.payg { diff --git a/internal/scheduling/nova/external_scheduler_api.go b/internal/scheduling/nova/external_scheduler_api.go index 5773da9c7..4464c46a0 100644 --- a/internal/scheduling/nova/external_scheduler_api.go +++ b/internal/scheduling/nova/external_scheduler_api.go @@ -134,7 +134,7 @@ func shuffleTopHosts(hosts []string, k int) []string { } result := make([]string, len(hosts)) copy(result, hosts) - rand.Shuffle(n, func(i, j int) { + rand.Shuffle(n, func(i, j int) { //nolint:gosec // non-crypto shuffle for load balancing result[i], result[j] = result[j], result[i] }) slog.Info("shuffled top hosts for evacuation", "k", n, "hosts", result[:n]) diff --git a/internal/scheduling/nova/integration_test.go b/internal/scheduling/nova/integration_test.go index 1b84601a7..64a9bb35a 100644 --- a/internal/scheduling/nova/integration_test.go +++ b/internal/scheduling/nova/integration_test.go @@ -142,7 +142,7 @@ func newNovaRequest(instanceUUID, projectID, flavorName, flavorGroup string, vcp extraSpecs := map[string]string{ "capabilities:hypervisor_type": "qemu", - "hw_version": flavorGroup, + "quota:hw_version": flavorGroup, } var schedulerHints map[string]any diff --git a/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity.go b/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity.go index a66166fa4..7bcdf614c 100644 --- a/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity.go +++ b/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity.go @@ -166,7 +166,7 @@ func (s *FilterHasEnoughCapacity) Run(traceLog *slog.Logger, request api.Externa // For committed resource reservations: unlock resources only if: // 1. Project ID matches // 2. ResourceGroup matches the flavor's hw_version - reservation.Spec.CommittedResourceReservation.MatchesGroup(request.Spec.Data.ProjectID, request.Spec.Data.Flavor.Data.ExtraSpecs["hw_version"]): + reservation.Spec.CommittedResourceReservation.MatchesGroup(request.Spec.Data.ProjectID, request.Spec.Data.Flavor.Data.ExtraSpecs["quota:hw_version"]): traceLog.Info("unlocking resources reserved by matching committed resource reservation with allocation", "reservation", reservation.Name, "instanceUUID", request.Spec.Data.InstanceUUID, diff --git a/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity_test.go b/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity_test.go index b1b659e59..dea74d093 100644 --- a/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity_test.go +++ b/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity_test.go @@ -262,7 +262,7 @@ func newNovaRequestWithIntent(instanceUUID, projectID, flavorName, flavorGroup s extraSpecs := map[string]string{ "capabilities:hypervisor_type": "qemu", - "hw_version": flavorGroup, + "quota:hw_version": flavorGroup, } var schedulerHints map[string]any diff --git a/internal/scheduling/nova/plugins/filters/filter_quota_enforcement.go b/internal/scheduling/nova/plugins/filters/filter_quota_enforcement.go index 2278d526f..9f84d80cb 100644 --- a/internal/scheduling/nova/plugins/filters/filter_quota_enforcement.go +++ b/internal/scheduling/nova/plugins/filters/filter_quota_enforcement.go @@ -112,7 +112,7 @@ func (s *FilterQuotaEnforcement) Run(traceLog *slog.Logger, request api.External // field is in the trace log. projectID := request.Spec.Data.ProjectID az := request.Spec.Data.AvailabilityZone - hwVersion := request.Spec.Data.Flavor.Data.ExtraSpecs["hw_version"] + hwVersion := request.Spec.Data.Flavor.Data.ExtraSpecs["quota:hw_version"] if projectID == "" { traceLog.Warn("no project ID in request, skipping quota enforcement") diff --git a/internal/scheduling/nova/plugins/filters/filter_quota_enforcement_test.go b/internal/scheduling/nova/plugins/filters/filter_quota_enforcement_test.go index 688b5381d..2960cc71b 100644 --- a/internal/scheduling/nova/plugins/filters/filter_quota_enforcement_test.go +++ b/internal/scheduling/nova/plugins/filters/filter_quota_enforcement_test.go @@ -27,7 +27,7 @@ func makeQuotaEnforcementRequest(projectID, az, hwVersion string, memoryMB, numI VCPUs: 4, } if hwVersion != "" { - flavor.ExtraSpecs = map[string]string{"hw_version": hwVersion} + flavor.ExtraSpecs = map[string]string{"quota:hw_version": hwVersion} } else { flavor.ExtraSpecs = map[string]string{} } diff --git a/internal/scheduling/reservations/commitments/reservation_controller.go b/internal/scheduling/reservations/commitments/reservation_controller.go index a5fd5cd2d..6541d143a 100644 --- a/internal/scheduling/reservations/commitments/reservation_controller.go +++ b/internal/scheduling/reservations/commitments/reservation_controller.go @@ -199,8 +199,8 @@ func (r *CommitmentReservationController) Reconcile(ctx context.Context, req ctr } logger.Info("marked pre-allocated reservation as ready", "host", res.Status.Host) - // Requeue immediately to run verification in next reconcile loop - return ctrl.Result{Requeue: true}, nil + // The status patch triggers a re-reconcile via the Reservation watch; allocation verification runs in that cycle. + return ctrl.Result{}, nil } // Sync Spec values to Status fields for non-pre-allocated reservations diff --git a/internal/scheduling/reservations/failover/controller.go b/internal/scheduling/reservations/failover/controller.go index 73e471f1d..c9bd443ba 100644 --- a/internal/scheduling/reservations/failover/controller.go +++ b/internal/scheduling/reservations/failover/controller.go @@ -18,6 +18,7 @@ import ( "github.com/cobaltcore-dev/cortex/pkg/multicluster" hv1 "github.com/cobaltcore-dev/openstack-hypervisor-operator/api/v1" "github.com/google/uuid" + "github.com/sapcc/go-bits/jobloop" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" @@ -94,7 +95,7 @@ func (c *FailoverReservationController) Reconcile(ctx context.Context, req ctrl. // Skip if no failover status (reservation not yet initialized by periodic controller) if res.Status.FailoverReservation == nil { logger.V(1).Info("skipping reservation without failover status") - return ctrl.Result{RequeueAfter: c.Config.RevalidationInterval.Duration}, nil + return ctrl.Result{RequeueAfter: jobloop.DefaultJitter(c.Config.RevalidationInterval.Duration)}, nil } // Validate and acknowledge the reservation @@ -126,7 +127,7 @@ func (c *FailoverReservationController) reconcileValidateAndAcknowledge(ctx cont return ctrl.Result{}, patchErr } - return ctrl.Result{RequeueAfter: c.Config.RevalidationInterval.Duration}, nil + return ctrl.Result{RequeueAfter: jobloop.DefaultJitter(c.Config.RevalidationInterval.Duration)}, nil } // Validate the reservation @@ -134,7 +135,7 @@ func (c *FailoverReservationController) reconcileValidateAndAcknowledge(ctx cont if validationErr != nil { logger.Error(validationErr, "transient error during reservation validation, will retry", "host", res.Status.Host) - return ctrl.Result{RequeueAfter: c.Config.RevalidationInterval.Duration}, nil + return ctrl.Result{RequeueAfter: jobloop.DefaultJitter(c.Config.RevalidationInterval.Duration)}, nil } if !valid { @@ -172,7 +173,7 @@ func (c *FailoverReservationController) reconcileValidateAndAcknowledge(ctx cont logger.V(1).Info("reservation validation passed (no new changes to acknowledge)", "host", res.Status.Host) } - return ctrl.Result{RequeueAfter: c.Config.RevalidationInterval.Duration}, nil + return ctrl.Result{RequeueAfter: jobloop.DefaultJitter(c.Config.RevalidationInterval.Duration)}, nil } // validateReservation validates that a reservation is still valid for all its allocated VMs. diff --git a/internal/scheduling/reservations/scheduler_client.go b/internal/scheduling/reservations/scheduler_client.go index a03f9cd72..e5ee2c3ee 100644 --- a/internal/scheduling/reservations/scheduler_client.go +++ b/internal/scheduling/reservations/scheduler_client.go @@ -8,6 +8,7 @@ import ( "context" "encoding/json" "fmt" + "io" "net/http" "time" @@ -196,8 +197,13 @@ func (c *SchedulerClient) ScheduleReservation(ctx context.Context, req ScheduleR // Check response status if response.StatusCode != http.StatusOK { - logger.Error(nil, "external scheduler returned non-OK status", "statusCode", response.StatusCode) - return nil, fmt.Errorf("external scheduler returned status %d", response.StatusCode) + body, err := io.ReadAll(io.LimitReader(response.Body, 1024)) + if err != nil { + logger.Error(err, "failed to read error response body", "statusCode", response.StatusCode) + return nil, fmt.Errorf("external scheduler returned status %d", response.StatusCode) + } + logger.Error(nil, "external scheduler returned non-OK status", "statusCode", response.StatusCode, "body", string(body)) + return nil, fmt.Errorf("external scheduler returned status %d: %s", response.StatusCode, string(body)) } // Decode the response