Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,49 @@
# Changelog

## 2026-06-23 — [#966](https://github.com/cobaltcore-dev/cortex/pull/966)

### cortex v0.1.2 (sha-6daa5050)

Non-breaking changes:
- Pre-allocate PAYG VMs into CR reservation slots on CR creation/modification ([#951](https://github.com/cobaltcore-dev/cortex/pull/951))
- Keep failover allocation if VM missing from postgres but present on hypervisor ([#909](https://github.com/cobaltcore-dev/cortex/pull/909))
- All datasources are synced on restart ([#956](https://github.com/cobaltcore-dev/cortex/pull/956))
- Honor domain restrictions for CR reservation scheduling ([#955](https://github.com/cobaltcore-dev/cortex/pull/955))
- Create InFlightReservation as part of Reservation CRD ([#954](https://github.com/cobaltcore-dev/cortex/pull/954))
- Move committed resource status summary business logic to internal ([#953](https://github.com/cobaltcore-dev/cortex/pull/953))
- Bypass grace period for confirmed VM departure ([#925](https://github.com/cobaltcore-dev/cortex/pull/925))
- Track VM placements in reservations and classify no-host-found ([#847](https://github.com/cobaltcore-dev/cortex/pull/847))
- Refactor reservations: move VMSource to shared package, unify VM data layer ([#930](https://github.com/cobaltcore-dev/cortex/pull/930))
- Add suffix gX to postgresql ([#939](https://github.com/cobaltcore-dev/cortex/pull/939))
- Update External dependencies to v1.9.1 ([#952](https://github.com/cobaltcore-dev/cortex/pull/952)), v1.14.46 ([#959](https://github.com/cobaltcore-dev/cortex/pull/959))
- Update `github.com/sapcc` ([#938](https://github.com/cobaltcore-dev/cortex/pull/938))

### cortex-nova v0.0.76

Includes updated chart cortex v0.1.2.

- Add `keystoneSecretRef` and `ssoSecretRef` config keys for domain resolution in committed resource reservation scheduling ([#955](https://github.com/cobaltcore-dev/cortex/pull/955))

### cortex-crds v0.0.76

Includes updated chart cortex v0.1.2.

### cortex-cinder v0.0.76

Includes updated chart cortex v0.1.2.

### cortex-pods v0.0.76

Includes updated chart cortex v0.1.2.

### cortex-ironcore v0.0.76

Includes updated chart cortex v0.1.2.

### cortex-manila v0.0.76

Includes updated chart cortex v0.1.2.

## 2026-06-08 — [#919](https://github.com/cobaltcore-dev/cortex/pull/919)

### cortex v0.1.0 (sha-a0373875)
Expand Down
39 changes: 38 additions & 1 deletion api/v1alpha1/reservation_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ const (
ReservationTypeCommittedResource ReservationType = "CommittedResourceReservation"
// ReservationTypeFailover is a reservation for failover capacity.
ReservationTypeFailover ReservationType = "FailoverReservation"
// ReservationTypeInFlight is a reservation that blocks capacity for virtual
// machines that are currently being scheduled, to avoid double-booking.
ReservationTypeInFlight ReservationType = "InFlightReservation"
)

// Label keys for Reservation metadata.
Expand All @@ -35,6 +38,7 @@ const (
// Reservation type label values
ReservationTypeLabelCommittedResource = "committed-resource"
ReservationTypeLabelFailover = "failover"
ReservationTypeLabelInFlight = "in-flight"
)

// Annotation keys for Reservation metadata.
Expand Down Expand Up @@ -104,10 +108,30 @@ type FailoverReservationSpec struct {
ResourceGroup string `json:"resourceGroup,omitempty"`
}

// InFlightReservationSpec defines the nature and shape of the virtual machine
// that is expected to land on the designated reservation slot. This spec
// carries information needed for the scheduler to produce a valid placement
// for new virtual machines for the duration the virtual machine is still
// in buildup.
type InFlightReservationSpec struct {
// VMID is the OpenStack server uuid from Nova assigned to the virtual
// machine expected to land on this reservation slot.
VMID string `json:"vmID,omitempty"`
// UserID is the identifier of the user who owns the virtual machine.
UserID string `json:"userID,omitempty"`
// ProjectID is the identifier of the project/tenant that owns
// the virtual machine.
ProjectID string `json:"projectID,omitempty"`
// Intent defines which kind of virtual machine lifecycle operation
// triggered the placement of this in-flight reservation.
// +kubebuilder:validation:Optional
Intent SchedulingIntent `json:"intent"`
}

// ReservationSpec defines the desired state of Reservation.
type ReservationSpec struct {
// Type of reservation.
// +kubebuilder:validation:Enum=CommittedResourceReservation;FailoverReservation
// +kubebuilder:validation:Enum=CommittedResourceReservation;FailoverReservation;InFlightReservation
// +kubebuilder:validation:Required
Type ReservationType `json:"type"`

Expand Down Expand Up @@ -148,6 +172,10 @@ type ReservationSpec struct {
// Only used when Type is FailoverReservation.
// +kubebuilder:validation:Optional
FailoverReservation *FailoverReservationSpec `json:"failoverReservation,omitempty"`

// InFlightReservation specifies which kind of virtual machine is expected
// to land on the reserved slot. Set when Type is InFlightReservation.
InFlightReservation *InFlightReservationSpec `json:"inFlightReservation,omitempty"`
}

const (
Expand Down Expand Up @@ -189,6 +217,10 @@ type FailoverReservationStatus struct {
AcknowledgedAt *metav1.Time `json:"acknowledgedAt,omitempty"`
}

// InFlightReservationStatus defines the status fields specific to
// in-flight reservations.
type InFlightReservationStatus struct{} // No captured state for now.

// ReservationStatus defines the observed state of Reservation.
type ReservationStatus struct {
// The current status conditions of the reservation.
Expand Down Expand Up @@ -219,6 +251,11 @@ type ReservationStatus struct {
// Only used when Type is FailoverReservation.
// +kubebuilder:validation:Optional
FailoverReservation *FailoverReservationStatus `json:"failoverReservation,omitempty"`

// InFlightReservation contains status fields specific to in-flight reservations.
// Only used when Type is InFlightReservation.
// +kubebuilder:validation:Optional
InFlightReservation *InFlightReservationStatus `json:"inFlightReservation,omitempty"`
}

// +kubebuilder:object:root=true
Expand Down
40 changes: 40 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 11 additions & 4 deletions cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ func main() {
switch os.Args[1] {
case "e2e-nova":
novaChecksConfig := conf.GetConfigOrDie[nova.ChecksConfig]()
if len(os.Args) >= 3 {
if err := json.Unmarshal([]byte(os.Args[2]), &novaChecksConfig); err != nil {
slog.Error("invalid json override for e2e-nova", "err", err)
os.Exit(1)
}
}
nova.RunChecks(ctx, client, novaChecksConfig)
return
case "e2e-cinder":
Expand Down Expand Up @@ -598,10 +604,11 @@ func main() {
metrics.Registry.MustRegister(&crControllerMonitor)

if err := (&commitments.CommittedResourceController{
Client: multiclusterClient,
Scheme: mgr.GetScheme(),
Conf: crControllerConf,
Monitor: &crControllerMonitor,
Client: multiclusterClient,
Scheme: mgr.GetScheme(),
Conf: crControllerConf,
Monitor: &crControllerMonitor,
VMSource: commitmentsVMSource,
}).SetupWithManager(mgr, multiclusterClient); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "CommittedResource")
os.Exit(1)
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ require (
github.com/prometheus/client_golang v1.23.2
github.com/prometheus/client_model v0.6.2
github.com/sapcc/go-bits v0.0.0-20260611141223-328f49772fed
go.xyrillian.de/gg v1.9.0
go.xyrillian.de/gg v1.10.1
k8s.io/api v0.36.2
k8s.io/apimachinery v0.36.2
k8s.io/client-go v0.36.2
Expand Down Expand Up @@ -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.45
github.com/mattn/go-sqlite3 v1.14.47
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
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,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.45 h1:6KA/spDguL3KV8rnybG7ezSaE4SeMR3KC9VbUoAQaIk=
github.com/mattn/go-sqlite3 v1.14.45/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ=
github.com/mattn/go-sqlite3 v1.14.47 h1:jOBI62gS7nKeZv+as1oGEy0+1qISgXwH/QBlR6KbfIo=
github.com/mattn/go-sqlite3 v1.14.47/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=
Expand Down Expand Up @@ -259,8 +259,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.9.0 h1:vszip+UjOBaczo/s9tr6Ij2eo39pxWlVZdbBcLkzXBM=
go.xyrillian.de/gg v1.9.0/go.mod h1:dj+ZhCwC6JKWyFvImhVNXQAErrRcYMUkXu6vwWYNrzQ=
go.xyrillian.de/gg v1.10.1 h1:V6oSU+tl25vaRQaMy6Y3jl/0kNoY/a25x4WIk5zQFAw=
go.xyrillian.de/gg v1.10.1/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=
Expand Down
6 changes: 3 additions & 3 deletions helm/bundles/cortex-cinder/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ apiVersion: v2
name: cortex-cinder
description: A Helm chart deploying Cortex for Cinder.
type: application
version: 0.0.75
version: 0.0.76
appVersion: 0.1.0
dependencies:
# from: file://../../library/cortex-postgres
Expand All @@ -16,12 +16,12 @@ dependencies:
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
version: 0.1.1
version: 0.1.2
alias: cortex-knowledge-controllers
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
version: 0.1.1
version: 0.1.2
alias: cortex-scheduling-controllers

# Owner info adds a configmap to the kubernetes cluster with information on
Expand Down
4 changes: 2 additions & 2 deletions helm/bundles/cortex-crds/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ apiVersion: v2
name: cortex-crds
description: A Helm chart deploying Cortex CRDs.
type: application
version: 0.0.75
version: 0.0.76
appVersion: 0.1.0
dependencies:
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
version: 0.1.1
version: 0.1.2

# 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
Expand Down
4 changes: 2 additions & 2 deletions helm/bundles/cortex-ironcore/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ apiVersion: v2
name: cortex-ironcore
description: A Helm chart deploying Cortex for IronCore.
type: application
version: 0.0.75
version: 0.0.76
appVersion: 0.1.0
dependencies:
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
version: 0.1.1
version: 0.1.2

# 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
Expand Down
6 changes: 3 additions & 3 deletions helm/bundles/cortex-manila/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ apiVersion: v2
name: cortex-manila
description: A Helm chart deploying Cortex for Manila.
type: application
version: 0.0.75
version: 0.0.76
appVersion: 0.1.0
dependencies:
# from: file://../../library/cortex-postgres
Expand All @@ -16,12 +16,12 @@ dependencies:
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
version: 0.1.1
version: 0.1.2
alias: cortex-knowledge-controllers
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
version: 0.1.1
version: 0.1.2
alias: cortex-scheduling-controllers

# Owner info adds a configmap to the kubernetes cluster with information on
Expand Down
6 changes: 3 additions & 3 deletions helm/bundles/cortex-nova/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ apiVersion: v2
name: cortex-nova
description: A Helm chart deploying Cortex for Nova.
type: application
version: 0.0.75
version: 0.0.76
appVersion: 0.1.0
dependencies:
# from: file://../../library/cortex-postgres
Expand All @@ -16,12 +16,12 @@ dependencies:
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
version: 0.1.1
version: 0.1.2
alias: cortex-knowledge-controllers
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
version: 0.1.1
version: 0.1.2
alias: cortex-scheduling-controllers

# Owner info adds a configmap to the kubernetes cluster with information on
Expand Down
12 changes: 12 additions & 0 deletions helm/bundles/cortex-nova/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,15 @@ cortex-scheduling-controllers:
allocationGracePeriod: "15m"
# URL of the nova external scheduler API for placement decisions
schedulerURL: "http://localhost:8080/scheduler/nova/external"
# Keystone credentials used to resolve domain IDs to domain names for the
# domain_name scheduler hint consumed by filter_external_customer.
# Must match the credentials used by the commitments syncer.
keystoneSecretRef:
name: cortex-nova-openstack-keystone
namespace: default
# ssoSecretRef:
# name: cortex-nova-openstack-sso
# namespace: default
committedResourceController:
# Back-off interval while CommittedResource placement is pending or failed (base for exponential backoff)
requeueIntervalRetry: "1m"
Expand All @@ -188,6 +197,9 @@ cortex-scheduling-controllers:
slotCreationDelay: "0ms"
# Max Reservation CRDs per CommittedResource on the API path; 0 disables the limit
maxSlotsPerCommitment: 0
# When true, the controller scans the AZ for existing PAYG VMs and pre-allocates them
# into reservation slots before falling back to blind scheduler placement.
enablePaygPreAllocation: false
committedResourceAPI:
# Timeout for watching CommittedResource CRDs before rolling back
watchTimeout: "15s"
Expand Down
Loading