Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
e5230e1
feat(nova): improve virtual machine creation logging
PhilippMatthes Oct 15, 2026
8ea290b
Fix broken feature gate configuration in nova bundle
PhilippMatthes Oct 15, 2026
900e6ef
fix: CRs confirm superseded/expired CRs correctly within CR transacti…
mblos Oct 16, 2026
5a36b82
Renovate: Update External dependencies (#1371)
renovate[bot] Oct 16, 2026
ebdf905
Populate cortex intent and explanation on VM spec (#1373)
PhilippMatthes Oct 16, 2026
d711e99
Fix scheduling intent in decision being set to Unknown always (#1374)
PhilippMatthes Oct 16, 2026
a1856d7
Default scheduling intent to create for nova api (#1376)
PhilippMatthes Oct 16, 2026
200d896
Fix VM status condition being wiped on create path
PhilippMatthes Oct 16, 2026
7268037
chore: remove history crd (#1375)
SoWieMarkus Oct 16, 2026
9718212
Renovate: Update External dependencies (#1377)
renovate[bot] Oct 16, 2026
c8ddf4c
feat(cr): prune aged committed-resource reservations (#1382)
mblos Oct 19, 2026
debd875
docs: correct Decision CRD section — Decision is transient, not persi…
cortex-ai-agents[bot] Oct 19, 2026
bdcadcc
fix: use decision intent in VM handler instead of re-deriving from re…
cortex-ai-agents[bot] Oct 19, 2026
e168eb5
chore: Add edge cases to explanation (#1383)
SoWieMarkus Oct 19, 2026
c682470
Renovate: Update kube-prometheus-stack Docker tag to v92.10.1 (#1378)
renovate[bot] Oct 19, 2026
335e6a5
fix: change execution order (#1384)
mblos Oct 19, 2026
4eb4491
bump app version [skip ci] (#1353)
github-actions[bot] Oct 19, 2026
b4cf3be
fix: update Perses dashboard annotation to label in alerts (#1370)
SoWieMarkus Oct 19, 2026
bf33b83
bump app version [skip ci] (#1387)
github-actions[bot] Oct 19, 2026
bbc24e0
Release cortex 0.7.0 (#1386)
cortex-ai-agents[bot] Oct 19, 2026
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
60 changes: 60 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,65 @@
# Changelog

## cortex v0.7.0 (2026-10-19)

### ⚠️ Breaking Changes

- **History CRD removed:** The `cortex.cloud_histories` CRD and all associated controllers/tasks have been deleted. Any tooling relying on `kubectl get histories` or the history client library must migrate to `spec.cortex.explanation` on the `VirtualMachine` CRD.
- **CRD schema changes:** `Decision` and `VirtualMachine` CRDs updated with new `explanation` and `intent` fields.

### Features

- **Improve virtual machine creation logging** — Replaced the opaque boolean `createVM` gate with a `switch` that logs a specific skip reason (including `instanceUUID`) for each unmet precondition, plus logs successful VM create/update events for end-to-end traceability.
- **Populate cortex intent and explanation on VM spec** ([#1373](https://github.com/cobaltcore-dev/cortex/pull/1373)) — Bumped `vm-operator` to v0.2.8 and writes the new `Explanation` and `Intent` fields into the `VirtualMachine` CRD spec during scheduling, replacing the now-removed `History` CRD as the explanation surface.
- **Prune aged committed-resource reservations** ([#1382](https://github.com/cobaltcore-dev/cortex/pull/1382)) — The syncer now detects and deletes stale CR-backed Reservations that exceed a configurable max age (capped per run), so the reconciler can rebuild fresh slots rather than accumulating stale ones.

### Bug Fixes

- **Fix broken feature gate configuration in nova bundle** — Feature gate keys (`committedResourceTracking`, `virtualMachineCreation`, `virtualMachineCreationMandatory`) were incorrectly nested under a `featureGates:` block; moved to the correct nesting level.
- **CRs confirm superseded/expired CRs correctly within CR transactions** ([#1372](https://github.com/cobaltcore-dev/cortex/pull/1372)) — Superseded/expired CR transitions are no longer added to the poll-watch list, eliminating `CortexNovaCommittedResourceTimeoutsTooHigh` alerts. Also adds a generation-advance hang guard and wraps reservation deletes in `IgnoreNotFound`.
- **Fix scheduling intent set to Unknown always** ([#1374](https://github.com/cobaltcore-dev/cortex/pull/1374)) — Fixed a bug that caused VM resources to never be generated because intent was always `Unknown`.
- **Default scheduling intent to Create for Nova API** ([#1376](https://github.com/cobaltcore-dev/cortex/pull/1376)) — When intent cannot be determined, it now defaults to `CreateIntent` instead of `Unknown`; removes redundant intent derivation that overrode the fallback.
- **Fix VM status condition being wiped on create path** — Snapshots conditions before `Create` and restores them before the status sub-resource update so the `Scheduled` condition is preserved.
- **Use decision intent in VM handler instead of re-deriving from request** ([#1379](https://github.com/cobaltcore-dev/cortex/pull/1379)) — Reads intent from `decision.Spec.Intent` (which already incorporates the API's fallback logic) rather than re-calling `GetIntent()` on the request, fixing initial VM create failures.
- **Change execution order** ([#1384](https://github.com/cobaltcore-dev/cortex/pull/1384)) — Corrected execution ordering in the reservations path.

### Chores & Refactoring

- **Remove History CRD** ([#1375](https://github.com/cobaltcore-dev/cortex/pull/1375)) — Deleted the `History` custom resource definition, the history client, and all history cleanup tasks across Nova, Cinder, and Manila schedulers. Explanation data is now embedded directly on the `VirtualMachine` CRD.
- **Add edge cases to explanation** ([#1383](https://github.com/cobaltcore-dev/cortex/pull/1383)) — Hardened the plain-text explanation generator with additional edge-case handling.

### Documentation

- **Correct Decision CRD section** ([#1381](https://github.com/cobaltcore-dev/cortex/pull/1381)) — Clarified that `Decision` is a transient in-memory CRD (not persisted to etcd); replaced the misleading `kubectl get decisions` example with `kubectl get virtualmachines` showing `spec.cortex.*` fields.

### Dependency Updates

| Dependency | Old | New |
|---|---|---|
| `vm-operator` | v0.1.2-pre | v0.2.9 |
| `kube-prometheus-stack` | 92.7.0 | 92.10.1 |
| `controller-tools` | v0.22.0 | v0.23.0 |
| `golangci-lint` | v2.14.0 | v2.15.0 |

### Package Versions

| Package | Version |
|---|---|
| cortex | 0.7.0 |
| cortex-postgres | 0.6.28 |
| cortex-shim | 0.1.33 |
| bundles | 0.0.107 |
| cortex-placement-shim | 0.1.33 |

### Operational Notes

- **Alert resolution:** This release fixes the `CortexNovaCommittedResourceTimeoutsTooHigh` alert by no longer polling superseded/expired CR transitions.
- **Stale reservation pruning:** CR-backed Reservations are now automatically pruned past a configurable max age — verify the default threshold is appropriate for your deployment.

**Contributors:** @PhilippMatthes, @mblos, @SoWieMarkus, @cortex-ai-agents[bot], @renovate[bot], @github-actions[bot]

**PR:** [#1385](https://github.com/cobaltcore-dev/cortex/pull/1385) | **Commits:** 19 | **Files changed:** 79 | **Test coverage:** 71.4%

## Release 2026-10-15 — PR [#1367](https://github.com/cobaltcore-dev/cortex/pull/1367)

### Bumped Versions
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
GOLANGCI_LINT = $(LOCALBIN)/golangci-lint
GOTESTSUM = $(LOCALBIN)/gotestsum

CONTROLLER_TOOLS_VERSION ?= v0.22.0
GOLANGCI_LINT_VERSION ?= v2.14.0
CONTROLLER_TOOLS_VERSION ?= v0.23.0
GOLANGCI_LINT_VERSION ?= v2.15.0
GOTESTSUM_VERSION ?= v1.13.0

.PHONY: controller-gen
Expand Down
9 changes: 2 additions & 7 deletions api/scheduling/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import (
// These are distinct from per-step YAML options (FilterWeigherPipelineStepOpts),
// which are static and set when the pipeline is initialized.
type Options struct {
// ReadOnly means the pipeline run does not modify shared scheduling state (reservations,
// history, ...). Cortex may run read-only runs concurrently.
// ReadOnly means the pipeline run does not modify shared scheduling state (reservations, ...).
// Cortex may run read-only runs concurrently.
ReadOnly bool `json:"read_only,omitempty"`

// AssumeEmptyHosts ignores running instances on hosts, considering them as empty.
Expand All @@ -27,8 +27,6 @@ type Options struct {
// MaxCandidates limits the number of candidates (hosts) returned after weighing. 0 means no limit.
MaxCandidates int `json:"max_candidates,omitempty"`

// SkipHistory skips recording the placement decision in placement history.
SkipHistory bool `json:"skip_history,omitempty"`
// SkipInflight skips creating pessimistic blocking reservations for returned candidates.
SkipInflight bool `json:"skip_inflight,omitempty"`
// SkipCommittedResourceTracking skips writing the placed VM UUID into the matching
Expand All @@ -39,9 +37,6 @@ type Options struct {

// Validate checks for mutually exclusive or inconsistent option combinations.
func (o Options) Validate() error {
if o.ReadOnly && !o.SkipHistory {
return errors.New("read-only runs must not write scheduling history: set SkipHistory=true")
}
if o.ReadOnly && !o.SkipInflight {
return errors.New("read-only runs cannot create inflight reservations")
}
Expand Down
7 changes: 3 additions & 4 deletions api/scheduling/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ func TestOptions_Validate(t *testing.T) {
wantErr bool
}{
{"zero value is valid", Options{}, false},
{"read-only run, skipping all writes", Options{ReadOnly: true, SkipHistory: true, SkipInflight: true, SkipCommittedResourceTracking: true}, false},
{"ReadOnly without SkipHistory is invalid", Options{ReadOnly: true}, true},
{"ReadOnly without SkipInflight is invalid", Options{ReadOnly: true, SkipHistory: true}, true},
{"ReadOnly without SkipCommittedResourceTracking is invalid", Options{ReadOnly: true, SkipHistory: true, SkipInflight: true}, true},
{"read-only run, skipping all writes", Options{ReadOnly: true, SkipInflight: true, SkipCommittedResourceTracking: true}, false},
{"ReadOnly without SkipInflight is invalid", Options{ReadOnly: true}, true},
{"ReadOnly without SkipCommittedResourceTracking is invalid", Options{ReadOnly: true, SkipInflight: true}, true},
}

for _, tt := range tests {
Expand Down
3 changes: 2 additions & 1 deletion api/v1alpha1/decision_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ type DecisionStatus struct {

// Currently the Decision CRD is an in-memory scheduling object used by the external scheduler API
// and filter-weigher pipelines to compute a placement result. It is currently NOT persisted
// to etcd — the scheduling outcome is recorded in the History CRD instead.
// to etcd — the scheduling outcome (including a human-readable explanation) is written onto the
// scheduled resource instead, e.g. the nova VM's spec.cortex fields.
// The long-term shape of this CRD is still under discussion; until that is
// settled the Decision serves only as a transient carrier within a single
// scheduling run.
Expand Down
128 changes: 0 additions & 128 deletions api/v1alpha1/history_types.go

This file was deleted.

Loading
Loading