Skip to content

fix(ops): support operations for flat-ordinal instances - #10709

Open
leon-ape wants to merge 26 commits into
mainfrom
bugfix/10704-flat-ordinal-ops
Open

fix(ops): support operations for flat-ordinal instances#10709
leon-ape wants to merge 26 commits into
mainfrom
bugfix/10704-flat-ordinal-ops

Conversation

@leon-ape

@leon-ape leon-ape commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

What changed

  • support Operations on flat-ordinal InstanceSets by reading identities and template assignments from status.instanceStatus instead of reproducing InstanceSet name allocation
  • make status.instanceStatus the single identity source for Start, Stop, VerticalScaling, and VolumeExpansion in both ordinal modes; an incomplete status view remains waiting instead of falling back to name generation
  • keep the existing Pod, PVC, revision, readiness, availability, failure, and Component-phase checks for operation progress and completion
  • add only a minimal sourceInstanceAssignments record for ordinary HorizontalScaling and flat-ordinal non-in-place RebuildInstance; no generic source/target snapshot, UID, generation, or frozen participant protocol
  • make Start and Stop use the current desired-state identities without storing historical assignments
  • select VerticalScaling and VolumeExpansion participants by Active state and template while preserving their existing Pod/PVC completion checks
  • compute ordinary HorizontalScaling created/deleted identities in both ordinal modes from the saved source allocation and the current authoritative Active allocation; cancellation waits for the source allocation to be restored
  • isolate the legacy deterministic-name planner to non-flat-ordinal ScaleOut.FromBackup; reject flatInstanceOrdinal + FromBackup before Action because future identities do not exist yet
  • resolve RebuildInstance templates and replacement identities from InstanceStatus, including in-place rebuilds with names that cannot be parsed
  • reject non-in-place flat-ordinal rebuild with targetNodeName, because placement would require a future identity before InstanceSet allocates it
  • remove the previous participant snapshot implementation and name-planning/PVC-label fallbacks from all InstanceStatus-based paths
  • regenerate deepcopy code, CRDs, Helm CRDs, and API documentation

Dependency

#10758 is merged into main and provides the richer InstanceStatus API consumed here.

Validation

  • scripts/codex-go-test.sh ./pkg/operations -count=1
  • make lint

Fixes #10704

@apecloud-bot

Copy link
Copy Markdown
Collaborator

Auto Cherry-pick Instructions

Usage:
  - /nopick: Not auto cherry-pick when PR merged.
  - /pick: release-x.x [release-x.x]: Auto cherry-pick to the specified branch when PR merged.

Example:
  - /nopick
  - /pick release-1.1

CLA Recheck Instructions

Usage:
  - /recheck-cla: Trigger a re-check of CLA status for this pull request.
Example:
  - /recheck-cla

@github-actions github-actions Bot added the size/L Denotes a PR that changes 100-499 lines. label Jul 22, 2026
@leon-ape leon-ape added the pick-1.1 Auto cherry-pick to release-1.1 when PR merged label Jul 22, 2026
Comment thread pkg/operations/horizontal_scaling.go Outdated
lastCompSpec.Replicas = *lastCompConfiguration.Replicas
lastCompSpec.Instances = lastCompConfiguration.Instances
lastCompSpec.OfflineInstances = lastCompConfiguration.OfflineInstances
lastPlan, err := runtime.GenerateInstanceNamePlan(opsRes.Cluster.Namespace, clusterName, fullCompName, lastCompSpec)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Do not reconstruct both the historical and desired participant sets from the current assignedOrdinals. getCreateAndDeletePodSet runs on every reconcile, while GenerateInstanceNamePlan seeds both plans from the live InstanceSet status. For example, with flat ordinals {0,2}, scaling 2 -> 3 initially identifies -1 as the new instance; after status converges to {0,1,2}, reconstructing the old 2-replica plan yields {0,1}, so the computed new instance changes to the already-existing -2. Because this path does not wait for the Component final state, Ops can report success while the actual new -1 is not ready. Participant identities must remain stable rather than being recomputed from an eventually changing workload status.

Comment thread pkg/operations/rebuild_instance.go Outdated
}
for _, ins := range rebuildInstance.Instances {
insTplName := appsv1.GetInstanceTemplateName(opsRes.Cluster.Name, rebuildInstance.ComponentName, ins.Name)
insTplName, ok := plan.TemplateByName[ins.Name]

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] This rejects a retained-PVC-only/offline target that the Rebuild contract explicitly accepts. Action resolves such a target through GetInstance, and the later progress path has dedicated handling for an already-offline original instance. However, the name plan excludes every entry in OfflineInstances, so this lookup cannot find the target and returns a fatal error before the non-in-place rebuild starts. This affects both flat and non-flat naming and is a regression for the existing offline rebuild path.

Comment thread pkg/operations/ops_runtime.go Outdated
func (r *opsRuntime) GenerateTemplateInstanceNames(clusterName, compName, templateName string, replicas int32, offlineInstances []string, ordinals appsv1.Ordinals) ([]string, error) {
workloadName := constant.GenerateWorkloadNamePattern(clusterName, compName)
ordinalList, err := instanceset.ConvertOrdinalsToSortedList(ordinals)
itsExt, err := instancetemplate.BuildInstanceSetExt(protoITS, nil)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] This moves the workloads controller authoritative instance-plan construction into Ops. The new Ops runtime synthesizes a partial InstanceSet, copies live status.assignedOrdinals, and directly invokes the internal instancetemplate planner. The base code already had deprecated name-generation debt, but this PR expands that dependency to workloads runtime state and allocation behavior. Ops should consume an explicit authoritative instance identity/template contract exposed by the owner API/status; it should not rerun the workloads plan builder.

Comment thread pkg/operations/ops_runtime.go Outdated
offlineTemplateByName := make(map[string]string, len(compSpec.OfflineInstances))
if compSpec.FlatInstanceOrdinal && len(compSpec.OfflineInstances) > 0 {
offlineNames := sets.New(compSpec.OfflineInstances...)
volumes, err := r.loadVolumes(namespace, clusterName, compName)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Retained PVC labels are not a complete contract for an offline instance template identity. A flat-ordinal offline instance may have no PVC, an older PVC without this label, or retained resources that have been removed; the public OfflineInstances API does not require this lookup to succeed. In those cases OfflineTemplateByName remains incomplete and offlineInstancesToOnline later fails fatally. The template association needs to be represented explicitly by the authoritative workloads/apps API instead of inferred from storage artifacts.

@shanshanying shanshanying added this to the Release 1.1.0 milestone Aug 7, 2026
@leon-ape
leon-ape marked this pull request as ready for review August 10, 2026 03:13
@leon-ape
leon-ape requested review from a team and wangyelei as code owners August 10, 2026 03:13
@codecov

codecov Bot commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 35.96774% with 397 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.89%. Comparing base (f2bf8c6) to head (438a1bc).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
pkg/operations/rebuild_instance.go 26.73% 122 Missing and 15 partials ⚠️
pkg/operations/instance_status.go 41.66% 99 Missing and 13 partials ⚠️
pkg/operations/horizontal_scaling.go 27.90% 82 Missing and 11 partials ⚠️
pkg/operations/vertical_scaling.go 57.14% 12 Missing and 3 partials ⚠️
pkg/operations/volume_expansion.go 31.81% 13 Missing and 2 partials ⚠️
pkg/operations/stop.go 27.77% 11 Missing and 2 partials ⚠️
pkg/operations/start.go 25.00% 10 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #10709      +/-   ##
==========================================
- Coverage   65.13%   64.89%   -0.25%     
==========================================
  Files         510      511       +1     
  Lines       64007    64562     +555     
==========================================
+ Hits        41694    41898     +204     
- Misses      18574    18882     +308     
- Partials     3739     3782      +43     
Flag Coverage Δ
unittests 64.89% <35.96%> (-0.25%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions github-actions Bot added size/XXL Denotes a PR that changes 1000+ lines. and removed size/L Denotes a PR that changes 100-499 lines. labels Aug 19, 2026
@leon-ape
leon-ape changed the base branch from main to support/richer-its-instance-status August 19, 2026 04:19
@leon-ape
leon-ape marked this pull request as draft August 19, 2026 04:25
Base automatically changed from support/richer-its-instance-status to main August 20, 2026 04:28
…inal-ops

# Conflicts:
#	apis/workloads/v1/instanceset_types.go
#	config/crd/bases/workloads.kubeblocks.io_instancesets.yaml
#	deploy/helm/crds/workloads.kubeblocks.io_instancesets.yaml
#	docs/developer_docs/api-reference/cluster.md
#	pkg/controller/instance/reconciler_status.go
#	pkg/controller/instance/reconciler_status_test.go
#	pkg/controller/instanceset/reconciler_status.go
#	pkg/controller/instanceset2/reconciler_status.go
#	pkg/controller/instancetemplate/status_allocation.go
#	pkg/controller/instancetemplate/status_allocation_test.go
#	pkg/controller/workloads/instancestatus/builder.go
#	pkg/controller/workloads/instancestatus/builder_test.go
@leon-ape leon-ape changed the title fix(ops): support flat ordinal instance names fix(ops): track operation participants from InstanceSet status Aug 20, 2026
@leon-ape leon-ape changed the title fix(ops): track operation participants from InstanceSet status fix(ops): use InstanceStatus for flat-ordinal operations Aug 20, 2026
@leon-ape leon-ape changed the title fix(ops): use InstanceStatus for flat-ordinal operations fix(ops): support operations for flat-ordinal instances Aug 20, 2026
@leon-ape leon-ape changed the title fix(ops): support operations for flat-ordinal instances fix(ops): support flat-ordinal instances Aug 21, 2026
@leon-ape leon-ape changed the title fix(ops): support flat-ordinal instances fix(ops): support operations for flat-ordinal instances Aug 28, 2026
@leon-ape
leon-ape marked this pull request as ready for review September 1, 2026 06:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pick-1.1 Auto cherry-pick to release-1.1 when PR merged size/XXL Denotes a PR that changes 1000+ lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpsRequest progress tracking never converges when FlatInstanceOrdinal is enabled

3 participants