diff --git a/.claude/agents/pull-request-creator.md b/.claude/agents/pull-request-creator.md index 94bd2d596..f5223ea40 100644 --- a/.claude/agents/pull-request-creator.md +++ b/.claude/agents/pull-request-creator.md @@ -61,9 +61,11 @@ If `git stash pop` reports conflicts, abort and surface them — something on th ``` git add -A -git commit -m "" +git commit -s -m "" ``` +Note: the `-s` adds a Signed-off-by trailer to the commit message. This is required for all commits in this project. + ## Step 5: Push ``` diff --git a/CHANGELOG.md b/CHANGELOG.md index a4c302df4..60edd20e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,49 @@ # Changelog +## 2026-07-23 — [#1080](https://github.com/cobaltcore-dev/cortex/pull/1080) + +### cortex v0.3.3 (sha-4eba8400) + +Non-breaking changes: +- Skip image property filtering for internal scheduling intents — the FilterImageProperties Nova scheduling filter now skips image-property-based filtering for Cortex-internal intents (reserve_for_failover, reuse_failover_reservation, reserve_for_committed_resource, capacity_probe) which schedule based on flavor metadata independent of the image ([#1078](https://github.com/cobaltcore-dev/cortex/pull/1078)) +- Bump `google.golang.org/grpc` from 1.82.0 to 1.82.1 — security patch addressing HTTP/2 flood protection and xds/rbac fixes ([#1079](https://github.com/cobaltcore-dev/cortex/pull/1079)) + +### cortex-shim v0.1.9 (sha-378ee2f5) + +Includes updated image sha-378ee2f5. + +### cortex-postgres v0.6.11 (sha-e06153f8) + +Includes updated image sha-e06153f8. + +### cortex-nova v0.0.83 + +Includes updated charts cortex v0.3.3, cortex-postgres v0.6.11. + +### cortex-cinder v0.0.83 + +Includes updated charts cortex v0.3.3, cortex-postgres v0.6.11. + +### cortex-manila v0.0.83 + +Includes updated charts cortex v0.3.3, cortex-postgres v0.6.11. + +### cortex-crds v0.0.83 + +Includes updated chart cortex v0.3.3. + +### cortex-ironcore v0.0.83 + +Includes updated chart cortex v0.3.3. + +### cortex-pods v0.0.83 + +Includes updated chart cortex v0.3.3. + +### cortex-placement-shim v0.1.9 + +Includes updated chart cortex-shim v0.1.9. + ## 2026-07-22 — [#1068](https://github.com/cobaltcore-dev/cortex/pull/1068) ### cortex v0.3.2 (sha-378ee2f5) diff --git a/go.mod b/go.mod index 2ca48a470..baf3e312b 100644 --- a/go.mod +++ b/go.mod @@ -119,7 +119,7 @@ require ( gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect - google.golang.org/grpc v1.82.0 // indirect + google.golang.org/grpc v1.82.1 // indirect google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/go.sum b/go.sum index 32aea00c9..84c655a6e 100644 --- a/go.sum +++ b/go.sum @@ -295,8 +295,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1: google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.82.0 h1:vguDnZUPjE26w09A63VoxZPnvPjB5Riyc0mkXPFmAIU= -google.golang.org/grpc v1.82.0/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= +google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI= google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/helm/bundles/cortex-cinder/Chart.yaml b/helm/bundles/cortex-cinder/Chart.yaml index ce7cd6675..2aa7b027f 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.82 +version: 0.0.83 appVersion: 0.1.0 dependencies: # from: file://../../library/cortex-postgres - name: cortex-postgres repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.6.10 + version: 0.6.11 # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.2 + version: 0.3.3 alias: cortex-knowledge-controllers # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.2 + version: 0.3.3 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 f911120d7..7c3cadeab 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.82 +version: 0.0.83 appVersion: 0.1.0 dependencies: # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.2 + version: 0.3.3 # 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 8ee47cd11..7ce01100e 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.82 +version: 0.0.83 appVersion: 0.1.0 dependencies: # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.2 + version: 0.3.3 # 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 74f5be1bc..146cc82ae 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.82 +version: 0.0.83 appVersion: 0.1.0 dependencies: # from: file://../../library/cortex-postgres - name: cortex-postgres repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.6.10 + version: 0.6.11 # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.2 + version: 0.3.3 alias: cortex-knowledge-controllers # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.2 + version: 0.3.3 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 9ae708704..832cd56c1 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.82 +version: 0.0.83 appVersion: 0.1.0 dependencies: # from: file://../../library/cortex-postgres - name: cortex-postgres repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.6.10 + version: 0.6.11 # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.2 + version: 0.3.3 alias: cortex-knowledge-controllers # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.2 + version: 0.3.3 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 6be1a1b69..d58bb6054 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.8 +version: 0.1.9 appVersion: 0.1.0 dependencies: # from: file://../../library/cortex-shim - name: cortex-shim repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.1.8 + version: 0.1.9 # 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 a7c1047aa..a08c74900 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.82 +version: 0.0.83 appVersion: 0.1.0 dependencies: # from: file://../../library/cortex - name: cortex repository: oci://ghcr.io/cobaltcore-dev/cortex/charts - version: 0.3.2 + version: 0.3.3 # 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/library/cortex-postgres/Chart.yaml b/helm/library/cortex-postgres/Chart.yaml index 5925db38f..2a765a364 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.10 +version: 0.6.11 appVersion: "sha-e06153f8" diff --git a/helm/library/cortex-shim/Chart.yaml b/helm/library/cortex-shim/Chart.yaml index 2729d7145..51f77277f 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.8 -appVersion: "sha-378ee2f5" +version: 0.1.9 +appVersion: "sha-38f37225" icon: "https://example.com/icon.png" dependencies: [] diff --git a/helm/library/cortex/Chart.yaml b/helm/library/cortex/Chart.yaml index 9cd948d99..579d7d35a 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.2 -appVersion: "sha-4eba8400" +version: 0.3.3 +appVersion: "sha-38f37225" icon: "https://example.com/icon.png" dependencies: [] diff --git a/internal/scheduling/nova/plugins/filters/filter_image_properties.go b/internal/scheduling/nova/plugins/filters/filter_image_properties.go index 7ce083f87..2fe1ada44 100644 --- a/internal/scheduling/nova/plugins/filters/filter_image_properties.go +++ b/internal/scheduling/nova/plugins/filters/filter_image_properties.go @@ -6,8 +6,10 @@ package filters import ( "context" "log/slog" + "slices" api "github.com/cobaltcore-dev/cortex/api/external/nova" + "github.com/cobaltcore-dev/cortex/api/v1alpha1" "github.com/cobaltcore-dev/cortex/internal/scheduling/lib" hv1 "github.com/cobaltcore-dev/openstack-hypervisor-operator/api/v1" ) @@ -19,6 +21,26 @@ type FilterImagePropertiesStep struct { // Filter hosts based on image properties given in the request spec. func (s *FilterImagePropertiesStep) Run(traceLog *slog.Logger, request api.ExternalSchedulerRequest) (*lib.FilterWeigherPipelineStepResult, error) { result := s.IncludeAllHostsFromRequest(request) + + // Apply this filter to all requests, unless we know from the request's + // intent that image metadata is expected to not be set. + if intent, err := request.GetIntent(); err == nil { + intentsExpectedToNotHaveImageMeta := []v1alpha1.SchedulingIntent{ + // Cortex-internal intents in which scheduling requests are sent + // mainly based on flavor-related metadata, independent of the + // image that'll land there. + api.ReserveForFailoverIntent, + api.ReuseFailoverReservationIntent, + api.ReserveForCommittedResourceIntent, + api.CapacityProbeIntent, + } + if slices.Contains(intentsExpectedToNotHaveImageMeta, intent) { + traceLog.Debug("skipping filter: expected to have no image metadata", + "intent", intent) + return result, nil + } + } + // If the image properties indicate any other hypervisor type than kvm, // we filter out all known kvm hypervisors. hvType, err := request.Spec.Data.Image.Data.GetHypervisorType() @@ -32,6 +54,7 @@ func (s *FilterImagePropertiesStep) Run(traceLog *slog.Logger, request api.Exter result.Events = append(result.Events, "image_properties_hv_type_undetermined") return result, nil } + if hvType != api.NovaImageMetaHVTypeKVM { traceLog.Info("filtering out all known kvm hypervisors since image properties indicate a different hypervisor type", "image_hypervisor_type", hvType) @@ -45,6 +68,7 @@ func (s *FilterImagePropertiesStep) Run(traceLog *slog.Logger, request api.Exter traceLog.Debug("filtering host which is kvm hypervisor", "host", hv.Name) } } + return result, nil } diff --git a/internal/scheduling/nova/plugins/filters/filter_image_properties_test.go b/internal/scheduling/nova/plugins/filters/filter_image_properties_test.go index c4370e79e..64dd4bb26 100644 --- a/internal/scheduling/nova/plugins/filters/filter_image_properties_test.go +++ b/internal/scheduling/nova/plugins/filters/filter_image_properties_test.go @@ -27,6 +27,15 @@ func requestWith(hosts []string, properties map[string]any) api.ExternalSchedule return request } +// requestWithIntent builds an ExternalSchedulerRequest like requestWith, but +// additionally sets the _nova_check_type scheduler hint so GetIntent resolves +// to the given intent. +func requestWithIntent(hosts []string, properties map[string]any, checkType string) api.ExternalSchedulerRequest { + request := requestWith(hosts, properties) + request.Spec.Data.SchedulerHints = map[string]any{"_nova_check_type": checkType} + return request +} + func TestFilterImagePropertiesStep_Run(t *testing.T) { scheme := runtime.NewScheme() if err := hv1.AddToScheme(scheme); err != nil { @@ -81,6 +90,36 @@ func TestFilterImagePropertiesStep_Run(t *testing.T) { expectedHosts: []string{}, filteredHosts: []string{}, }, + { + name: "reserve_for_failover intent skips filter and keeps all hosts", + request: requestWithIntent([]string{"host1", "host2", "host3"}, map[string]any{"hypervisor_type": "vmware"}, "reserve_for_failover"), + expectedHosts: []string{"host1", "host2", "host3"}, + filteredHosts: []string{}, + }, + { + name: "reuse_failover_reservation intent skips filter and keeps all hosts", + request: requestWithIntent([]string{"host1", "host2", "host3"}, map[string]any{"hypervisor_type": "vmware"}, "reuse_failover_reservation"), + expectedHosts: []string{"host1", "host2", "host3"}, + filteredHosts: []string{}, + }, + { + name: "reserve_for_committed_resource intent skips filter and keeps all hosts", + request: requestWithIntent([]string{"host1", "host2", "host3"}, map[string]any{"hypervisor_type": "vmware"}, "reserve_for_committed_resource"), + expectedHosts: []string{"host1", "host2", "host3"}, + filteredHosts: []string{}, + }, + { + name: "capacity_probe intent skips filter and keeps all hosts", + request: requestWithIntent([]string{"host1", "host2", "host3"}, map[string]any{"hypervisor_type": "vmware"}, "capacity_probe"), + expectedHosts: []string{"host1", "host2", "host3"}, + filteredHosts: []string{}, + }, + { + name: "create intent still filters out known kvm hypervisors", + request: requestWithIntent([]string{"host1", "host2", "host3"}, map[string]any{"hypervisor_type": "vmware"}, "create"), + expectedHosts: []string{"host3"}, + filteredHosts: []string{"host1", "host2"}, + }, } for _, tt := range tests {