Skip to content

Rewrite/reconcile manager - #337

Open
Tanker2020 wants to merge 34 commits into
IBM:mainfrom
Tanker2020:rewrite/Reconcile_Manager
Open

Rewrite/reconcile manager#337
Tanker2020 wants to merge 34 commits into
IBM:mainfrom
Tanker2020:rewrite/Reconcile_Manager

Conversation

@Tanker2020

@Tanker2020 Tanker2020 commented Aug 11, 2026

Copy link
Copy Markdown

PR-5 — Reconcile Manager

Base branch: rewrite/Resource_Verification (must be merged first — see merge order below)


Summary

This PR ports the core reconciliation engine from Python oper8 to Go, wiring all four previously-merged packages (dag, deploymanager, status, verify) into a working end-to-end reconcile loop.

Files added:

Package File What it is
session/ session.go Per-reconcile context struct — owns CR manifest, DeployManager, component Graph, and current cluster status
component/ component.go Component interface: Name(), Setup(), Deploy(), Verify()
controller/ controller.go Controller interface + BaseController embed with no-op defaults for all optional hooks
rolloutmanager/ rolloutmanager.go 4-phase rollout loop: Deploy graph → AfterDeploy hook → Verify graph → AfterVerify hook
reconcilemanager/ reconcilemanager.go Top-level orchestrator: generates reconcile ID, constructs session, checks preconditions, drives rollout, writes status, manages finalizers

Files modified:

File Change
dag/node.go Added Node.SetFunc(), Node.SetData(), Node.Data() — needed by RolloutManager to wire component functions onto graph nodes
dag/runner.go Removed unused last / inFlight fields (fixes lint failure from previous push); gofmt
deploymanager/dryrun.go gofmt only

Design decisions vs Python

Python Go
Session owned by ReconcileManager, passed everywhere Session is a plain struct created once per Reconcile() call
Component ABC with auto-registration in __init__ Minimal 3-method interface; operators call sess.AddComponent() explicitly in SetupComponents
Controller abstract class properties (group, version, kind) GVK() method returns a plain struct
@precondition decorator []PreconditionFunc slice on Options
ThreadPoolExecutor + sleep-poll dag.Runner goroutines with context.Context cancellation
RolloutManager stored 4 separate callback vars Receives controller.Controller directly; calls hook methods on it
ReconcileManager reimported controllers dynamically Receives a fully-constructed controller.Controller — no reflection

Rollout phases

Phase 1 — Deploy graph runner.Run(ctx) → Setup + Deploy each component in DAG order
Phase 2 — AfterDeploy ctrl.AfterDeploy / ctrl.AfterDeployUnsuccessful hook
Phase 3 — Verify graph runner.Run(ctx) → Verify each deployed component
Phase 4 — AfterVerify ctrl.AfterVerify / ctrl.AfterVerifyUnsuccessful hook

Context cancellation propagates into both Runner executions. A fatal error in Phase 1 skips Phase 3 entirely. Phase 2 returning not-OK prevents VerifyCompleted() from being true even if all nodes verified.


Tests

Package Cases Coverage highlights
session 21 Construction, all CR field accessors, current version from status, empty-status handling, all 5 CR validation errors, AddComponent / AddDependency (ok + error), ScopedName, TruncateName (passthrough, exact boundary, over boundary, uniqueness)
controller 14 GVK fields, HookResult, all BaseController defaults (no-op / OK / false), override behaviour for ShouldRequeue, HasFinalizer, Finalizer
rolloutmanager 18 Empty graph, single component happy path, ordered pair, setup/deploy errors (fatal), deploy error blocks downstream, verify-not-ready (non-fatal + blocks downstream), after-deploy called/not-called/error, after-verify called/not-called/error, 3-component all-verified, independent branch runs despite upstream failure, concurrent execution
reconcilemanager 24 Empty graph, single verified, setup error, deploy error, verify-not-ready, ShouldRequeue true/false, precondition fail/multi-stop/all-pass, finalizer calls finalize-not-setup / error / stamps object, invalid CR (missing kind/apiVersion/metadata), two-component ordering, failed-blocks-dependent, status stable / error / verify-wait, ManageStatus=false writes nothing, ReconcileResult defaults

Total new tests: 77 across 4 packages. All run with -race.


Merge order

PRs must be merged in sequence:

PR-1 (DAG Runner) → PR-2 (Deploy Manager) → PR-3 (Status Management) → PR-4 (Resource Verification) → PR-5 (this PR)


What this PR does NOT include

  • controller-runtime adapter (Reconcile(ctx, req) (ctrl.Result, error)) — that is a thin wrapper and can be added as a follow-up or in PR-6
  • watch_manager port — tracked as PR-6
  • A working main.go / operator binary — see the smoke-test plan in the thread context for how to wire one up once this lands

- Node: name, optional NodeFunc, directed edges to upstream deps
- Edge: carries optional EdgeFunc to gate dependent start
- ResourceNode: embeds Node, adds Manifest/VerifyFunc/DeployMethod
- Graph: root-anchored container; AddNode, AddDependency, Topology
- Cycle detection on every AddChild call (DFS reachability)
- Topology() returns DFS post-order (dependency-first deploy order)

Files: rewrite/dag/node.go, rewrite/dag/graph.go
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
- CompletionState: Verified/Unverified/Failed/Unstarted node buckets
- DeployCompleted(), VerifyCompleted(), AnyFailed() predicates
- HaltError{Fatal bool}: returned by NodeFunc to signal runner halt
  Fatal=true  → node lands in Failed, downstreams become Unstarted
  Fatal=false → node lands in Unverified (deployed, not yet ready)

Files: rewrite/dag/completion_state.go
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
Python used ThreadPoolExecutor + time.sleep(0.05) busy-poll loop.
Go port uses goroutines + buffered results channel; scheduler blocks
on select — zero CPU busy-polling.

- NewRunner(graph, opts...) with functional options
- WithConcurrency(0): serial topology walk, no goroutines (dry-run/test)
- WithConcurrency(n): semaphore-capped parallel execution
- WithVerifyUpstream(bool): gate dependent start on EdgeFunc result
- context.Context cancellation: drains in-flight, marks rest Unstarted
- Independent graph branches continue executing after sibling failure
  (matches Python oper8 intended behaviour; Python had a bug where the
  serial loop broke early on fatalErr)
- stateMap protected by sync.Mutex; scheduler is single writer

Files: rewrite/dag/runner.go
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
23 test cases covering:
  Graph/Node:  empty graph, duplicate node, empty name, cycle detection,
               self-loop, topology order, String()
  Runner serial: all succeed, empty graph, fatal halt (independent branch
               still runs), unverified halt, disabled node, execution order
  Runner concurrent: all succeed, fatal halt, independent nodes verified
               parallel via start-time spread, race detector stress test
               (20 nodes, atomic counter), context cancellation
  EdgeFunc:    blocks dependent when returns false, allows when true
  CompletionState: all predicate combinations
  ResourceNode: construction and field access

Concurrency test uses start-time recording rather than wall-clock
total elapsed — CI-safe on slow runners.

Files: rewrite/dag/runner_test.go
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
- Matrix: Go 1.22 and 1.23
- go test -race -count=1 -timeout=60s ./dag/...
- go build ./... and go vet ./dag/...
- golangci-lint on dag/ package
- Triggered on push to rewrite/DAG_Runner and PRs targeting main
- working-directory: rewrite (module root)

Files: ./.github/workflows/pr1-dag-runner.yml
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
Defines the core abstraction all cluster interactions go through.

Python (bool, bool) return tuples → Go (changed bool, err error):
- success bool dropped; errors are returned as error values
- callers use idiomatic `if err != nil` instead of checking two booleans

watch_objects Python generator → Go channel:
- Watch() returns <-chan WatchEvent; caller ranges over it
- Cancelled via context.Context; channel is closed on cancel

New types vs Python:
- ListOptions struct (replaces positional label_selector/field_selector args)
- EventType string constants (ADDED/MODIFIED/DELETED)
- WatchEvent struct with Timestamp

Files: rewrite/deploymanager/deploymanager.go

Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
Ports deploy_manager/owner_references.py.

- OwnerRef(ownerCR) builds a single ownerReference map entry
- ApplyOwnerRef(owner, child) stamps the reference onto child.metadata
  - No-op when owner == child (same UID)
  - No-op for cross-namespace references (K8s does not support them)
  - Idempotent: will not add duplicate entries
- blockOwnerDeletion: true; controller field intentionally omitted
  (matches Python behaviour and StackOverflow rationale in source)

Files: rewrite/deploymanager/ownerref.go
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
Ports deploy_manager/dry_run_deploy_manager.py.

Primary use: unit-testing controllers without a live cluster.

Key differences from Python:
- Python used nested defaultdict; Go uses typed clusterStore
  (map[ns][kind][apiVersion][name] → object)
- Python RLock on class level; Go sync.RWMutex per instance
- Python watch callbacks were registered functions; Go uses buffered
  channels — consumers range over the channel, cancel via context
- Watch channel is closed when ctx is cancelled (no explicit Unregister)
- deepCopy via JSON marshal/unmarshal (simple, correct for map[string]any)
- matchSelector implements = == != existence operators (sufficient for
  dry-run tests; full set-based selector is future work)

Extra test helpers (not in Python):
- GetStored(ns, kind, av, name) — direct store access for assertions
- ObjectCount() — total objects in store

Files: rewrite/deploymanager/dryrun.go
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
19 test cases covering:
  Deploy:     create, idempotent re-deploy, field update, owner ref stamping
  Get:        not found returns nil, found returns deep copy (mutation check)
  Delete:     existing object, non-existent no-op
  List:       all objects, label selector filtering
  SetStatus:  sets status, returns changed=true; error on missing object
  Watch:      receives ADDED on deploy, DELETED on delete, channel closes
              on context cancel (race-detector safe)
  OwnerRef:   stamps reference, idempotent, cross-namespace skipped

Files: rewrite/deploymanager/dryrun_test.go
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
- Matrix: Go 1.22 and 1.23
- go test -race -count=1 -timeout=60s ./deploymanager/...
- go build ./... and go vet ./deploymanager/...
- golangci-lint on deploymanager/ package
- Triggered on push to rewrite/Deploy_Manager and PRs targeting main

Files: .github/workflows/pr2-deploy-manager.yml
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
…licationStatus

Ports oper8 Python status.py to Go.

Reason types: ReadyReason, UpdatingReason, ServiceStatus string constants.

MakeApplicationStatus(Options) builds a complete status map:
- Ready + Updating conditions from reason/message pairs
- External conditions preserved alongside oper8-managed ones
- ComponentStatus block from dag.CompletionState (sorted node names)
- versions.reconciled / versions.available.versions (IBM CloudPak paths)
- <kind>Status field (e.g. customerStatus) when Kind is set

UpdateApplicationStatus merges new Options onto existing status,
carrying forward current reasons and external conditions when not overridden.

GetCondition, GetVersion, StatusChanged helper functions included.

Python translation notes:
- deepdiff library dropped; StatusChanged uses recursive JSON comparison
  after stripping lastTransactionTime keys — zero external dependencies
- **kwargs replaced by Options struct (compile-time field checking)
- aconfig nested_set/nested_get replaced by nestedSet/nestedGet dot-path helpers

Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
MakeApplicationStatus: Ready/Updating condition status values for all
  reason combinations, empty options, external conditions, version fields,
  componentStatus deployed/verified counts and dependencyGraph, IBM CloudPak
  <kind>Status (Completed/Failed/InProgress/custom preserved)

UpdateApplicationStatus: preserves existing reasons when not overridden,
  overrides when provided, preserves external conditions and top-level fields

StatusChanged: same content + different timestamps not changed, different
  reason changed, nil inputs, added field

GetCondition, GetVersion: found/missing cases
UpdatingReason active/inactive matrix (all 6 reasons)
ComponentStatus node names sorted alphabetically

Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
Matrix Go 1.22 and 1.23, race detector, golangci-lint v1.64.8

Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
…load config

Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
…ondition

Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
…rity tests

Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
…r, ReconcileManager

Ports oper8 Python session.py / component.py / controller.py /
rollout_manager.py / reconcile.py to Go.

New packages
  rewrite/session/          per-reconcile context (CR manifest, DAG, status)
  rewrite/component/        Component interface (Setup / Deploy / Verify)
  rewrite/controller/       Controller interface + BaseController no-op embed
  rewrite/rolloutmanager/   4-phase loop: deploy→after_deploy→verify→after_verify
  rewrite/reconcilemanager/ top-level orchestrator: ID gen, session init,
                            preconditions, rollout, status writes, finalizers

dag/node.go   Node.SetFunc / SetData / Data (needed by RolloutManager)
dag/runner.go Runner.CompletionState(); remove unused inFlight int64 field
gofmt         dag/runner_test.go, deploymanager/dryrun.go

reconcilemanager tests (9 cases, -race):
  EmptyGraph, SingleComponentVerified, SetupError, DeployError,
  VerifyNotReady, Precondition, TwoComponentsOrdered, InvalidCR, Finalizer

CI: .github/workflows/pr5-reconcile.yml — go test -race ./... + golangci-lint
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
dag/runner.go:
  Remove unused struct field  — this was the field
  golangci-lint flagged. The concurrent scheduler uses a local variable
   inside runConcurrent; the struct field was never read
  or written and should never have been there.

session/session_test.go:       21 tests (lost in branch switch, recreated)
controller/controller_test.go: 14 tests (lost in branch switch, recreated)
rolloutmanager/rolloutmanager_test.go: 18 tests (lost in branch switch, recreated)

Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
…0:00)

nishanthk  ttys002                         Thu Jul 30 11:30 - 11:30  (00:00)
nishanthk  ttys002                         Thu Jul 30 11:30 - 11:30  (00:00)
nishanthk  ttys002                         Thu Jul 30 11:30 - 11:30  (00:00)
nishanthk  ttys002                         Thu Jul 30 11:30 - 11:30  (00:00)
nishanthk  ttys002                         Thu Jul 30 11:29 - 11:29  (00:00)
nishanthk  ttys002                         Thu Jul 30 11:29 - 11:29  (00:00)
nishanthk  ttys002                         Thu Jul 30 11:28 - 11:28  (00:00)
nishanthk  ttys002                         Thu Jul 30 11:23 - 11:23  (00:00)
nishanthk  ttys001                         Thu Jul 30 11:19   still logged in
nishanthk  ttys000                         Thu Jul 30 11:19   still logged in
nishanthk  console                         Thu Jul 30 11:19   still logged in
reboot time                                Thu Jul 30 11:00
shutdown time                              Thu Jul 30 10:59
nishanthk  ttys001                         Fri Jul 24 15:26 - 15:26  (00:00)
nishanthk  ttys000                         Fri Jul 24 15:26 - 15:26  (00:00)
nishanthk  console                         Fri Jul 24 15:26 - 10:59 (5+19:33)
reboot time                                Fri Jul 24 15:25
shutdown time                              Fri Jul 24 15:24
nishanthk  ttys001                         Wed Jul 22 00:37 - 00:37  (00:00)
nishanthk  ttys000                         Wed Jul 22 00:37 - 00:37  (00:00)
nishanthk  console                         Wed Jul 22 00:37 - 15:24 (2+14:47)
reboot time                                Wed Jul 22 00:35
shutdown time                              Wed Jul 22 00:31
root       console                         Wed Jul 22 00:30 - shutdown  (00:00)
nishanthk  ttys001                         Fri Jul 17 16:28 - 16:28  (00:00)
nishanthk  ttys001                         Thu Jul  9 13:25 - 13:25  (00:00)
nishanthk  ttys001                         Mon Jul  6 14:14 - 14:14  (00:00)
nishanthk  ttys005                         Mon Jul  6 14:14 - 14:14  (00:00)
nishanthk  ttys006                         Mon Jul  6 14:14 - 14:14  (00:00)
nishanthk  ttys003                         Mon Jun 29 14:47 - 14:47  (00:00)
nishanthk  ttys002                         Mon Jun 29 14:47 - 14:47  (00:00)
nishanthk  ttys001                         Mon Jun 29 14:47 - 14:47  (00:00)
nishanthk  ttys006                         Mon Jun 29 14:21 - 14:21  (00:00)
nishanthk  ttys006                         Mon Jun 29 14:21 - 14:21  (00:00)
nishanthk  ttys003                         Mon Jun 29 13:36 - 13:36  (00:00)
nishanthk  ttys005                         Mon Jun 22 02:32 - 02:32  (00:00)
nishanthk  ttys004                         Mon Jun 22 02:30 - 02:30  (00:00)
nishanthk  ttys003                         Mon Jun 22 01:16 - 01:16  (00:00)
nishanthk  ttys002                         Thu Jun 18 16:23 - 16:23  (00:00)
nishanthk  ttys001                         Thu Jun 18 16:23 - 16:23  (00:00)
nishanthk  ttys000                         Thu Jun 18 16:23 - 16:23  (00:00)
nishanthk  console                         Thu Jun 18 16:23 - 00:30 (33+08:07)
reboot time                                Thu Jun 18 16:23
nishanthk  ttys002                         Wed Jun 17 12:32 - crash (1+03:50)
nishanthk  ttys001                         Mon Jun 15 13:30 - crash (3+02:52)
nishanthk  ttys000                         Mon Jun 15 13:30 - crash (3+02:53)
nishanthk  ttys003                         Mon Jun 15 13:17 - 13:17  (00:00)
nishanthk  ttys003                         Mon Jun 15 13:17 - 13:17  (00:00)
nishanthk  ttys002                         Mon Jun 15 13:16 - 13:16  (00:00)
nishanthk  ttys003                         Mon Jun 15 13:14 - 13:14  (00:00)
nishanthk  ttys002                         Mon Jun 15 13:12 - 13:12  (00:00)
nishanthk  ttys002                         Mon Jun 15 13:11 - 13:11  (00:00)
nishanthk  ttys003                         Mon Jun 15 13:07 - 13:07  (00:00)
nishanthk  ttys002                         Fri Jun 12 13:02 - 13:02  (00:00)
nishanthk  ttys002                         Thu Jun 11 12:44 - 12:44  (00:00)
nishanthk  ttys004                         Mon Jun  8 13:56 - 13:56  (00:00)
nishanthk  ttys002                         Mon Jun  8 13:56 - 13:56  (00:00)
nishanthk  ttys003                         Mon Jun  8 13:56 - 13:56  (00:00)
nishanthk  ttys004                         Fri Jun  5 09:34 - 09:34  (00:00)
nishanthk  ttys002                         Fri Jun  5 09:34 - 09:34  (00:00)
nishanthk  ttys003                         Fri Jun  5 09:34 - 09:34  (00:00)
nishanthk  ttys020                         Thu Jun  4 11:20 - 11:20  (00:00)
nishanthk  ttys004                         Wed Jun  3 16:42 - 16:42  (00:00)
nishanthk  ttys003                         Wed Jun  3 00:06 - 00:06  (00:00)
nishanthk  ttys002                         Wed Jun  3 00:06 - 00:06  (00:00)
nishanthk  ttys001                         Wed Jun  3 00:06 - 00:06  (00:00)
nishanthk  ttys000                         Wed Jun  3 00:06 - 00:06  (00:00)
nishanthk  console                         Wed Jun  3 00:06 - crash (15+16:17)
reboot time                                Wed Jun  3 00:04
shutdown time                              Tue Jun  2 23:59
root       console                         Tue Jun  2 23:57 - shutdown  (00:02)
nishanthk  ttys003                         Mon Jun  1 21:50 - 21:50  (00:00)
nishanthk  ttys002                         Mon Jun  1 21:50 - 21:50  (00:00)
nishanthk  ttys001                         Mon Jun  1 21:50 - 21:50  (00:00)
nishanthk  ttys000                         Mon Jun  1 21:50 - 21:50  (00:00)
nishanthk  console                         Mon Jun  1 21:50 - 23:57 (1+02:07)
reboot time                                Mon Jun  1 21:49
shutdown time                              Mon Jun  1 21:49
root       console                         Mon Jun  1 21:49 - shutdown  (00:00)
nishanthk  ttys003                         Mon Jun  1 10:57 - 10:57  (00:00)
nishanthk  ttys009                         Mon Jun  1 10:21 - 10:21  (00:00)
nishanthk  ttys000                         Mon Jun  1 10:15 - 10:15  (00:00)
nishanthk  ttys004                         Fri May 29 15:11 - 15:11  (00:00)
nishanthk  ttys003                         Fri May 29 12:56 - 12:56  (00:00)
nishanthk  ttys002                         Wed May 27 16:07 - 16:07  (00:00)
nishanthk  ttys001                         Wed May 27 16:05 - 16:05  (00:00)
nishanthk  ttys001                         Wed May 27 11:31 - 11:32  (00:00)
nishanthk  ttys001                         Wed May 27 11:31 - 11:31  (00:00)
nishanthk  ttys002                         Tue May 26 17:36 - 17:36  (00:00)
nishanthk  ttys001                         Tue May 26 17:24 - 17:24  (00:00)
nishanthk  ttys001                         Tue May 26 15:48 - 15:48  (00:00)
nishanthk  ttys001                         Tue May 26 15:47 - 15:47  (00:00)
nishanthk  ttys000                         Tue May 26 15:46 - 15:46  (00:00)
nishanthk  ttys001                         Tue May 26 15:42 - 15:42  (00:00)
nishanthk  ttys001                         Tue May 26 15:31 - 15:31  (00:00)
nishanthk  ttys000                         Tue May 26 14:44 - 14:44  (00:00)
nishanthk  ttys002                         Tue May 26 14:43 - 14:43  (00:00)
nishanthk  ttys002                         Tue May 26 14:43 - 14:43  (00:00)
nishanthk  ttys002                         Tue May 26 14:43 - 14:43  (00:00)
nishanthk  ttys002                         Tue May 26 14:43 - 14:43  (00:00)
nishanthk  ttys002                         Tue May 26 14:43 - 14:43  (00:00)
nishanthk  ttys002                         Tue May 26 14:43 - 14:43  (00:00)
nishanthk  ttys002                         Tue May 26 14:43 - 14:43  (00:00)
nishanthk  ttys002                         Tue May 26 14:43 - 14:43  (00:00)
nishanthk  ttys002                         Tue May 26 14:43 - 14:43  (00:00)
nishanthk  ttys002                         Tue May 26 14:43 - 14:43  (00:00)
nishanthk  ttys002                         Tue May 26 14:43 - 14:43  (00:00)
nishanthk  ttys001                         Tue May 26 14:42 - 14:42  (00:00)
nishanthk  ttys000                         Tue May 26 14:31 - 14:31  (00:00)
nishanthk  console                         Tue May 26 13:42 - 21:49 (6+08:07)
_mbsetupuser console                         Tue May 26 13:27 - 13:42  (00:14)
root       console                         Tue May 26 13:27 - 13:27  (00:00)
reboot time                                Tue May 26 13:26
shutdown time                              Thu May 21 02:12
reboot time                                Thu May 21 02:03
reboot time                                Tue Mar  3 22:23
reboot time                                Tue Mar  3 22:18

wtmp begins Tue Mar  3 22:18:14 CST 2026 struct field to pass golangci-lint

The  field on Runner was written but never read
externally — Run() already returns *CompletionState directly. The
 linter correctly flags any struct field that is never read.
Removing it fixes the CI lint failure.

Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
…efault

- Add Disabled() bool to Component interface; RolloutManager skips
  Setup/Deploy/Verify for disabled components (no-op DAG success)
- Fix requeue: ReconcileManager now uses !VerifyCompleted()||ShouldRequeue
  instead of ShouldRequeue alone; BaseController.ShouldRequeue → false
- Fix addFinalizer/removeFinalizer: DeployMethodUpdate → DeployMethodDefault
  (existing-wins merge was silently dropping the mutated finalizer list)
- Expand reconcilemanager tests 9→24 cases; add 2 disabled-component
  tests to rolloutmanager

Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
… dead code

- rolloutmanager: fix append aliasing bug in CompletionState assembly;
  deployedAll now uses make+copy instead of append on a shared backing array
- rolloutmanager: remove redundant second unverifiedNodes loop (verifyState.Unverified
  is a strict subset of deployedAll; second loop could never add anything)
- rolloutmanager: correct stale package doc (Disabled() is now first-class)
- reconcilemanager: fix nil-map panic in updateCompletionStatus; GetCondition
  returns nil on a fresh CR — guard before map index
- reconcilemanager: fix ManageStatus doc comment ("Default true" → zero value is false)
- controller: fix ShouldRequeue interface doc (claimed "(true, 0)" multi-return
  for a method that returns bool)
- reconcilemanager_test: collapse two duplicate RequeueAfter tests into one;
  remove time import kept alive only by _ = time.Second

Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
- session: add GetComponent(name) (*dag.Node, bool) — thin wrapper over
  Graph.GetNode so controller hook implementations can look up components
  without reaching into the DAG API directly; 2 tests added

- reconcilemanager: add PauseAnnotation constant (oper8.org/pause-reconciliation)
  and isPaused() check as step 2 of Reconcile — if the annotation is present
  and non-empty, return immediately with Requeue=false, skipping finalizers,
  status, preconditions, and rollout; 3 tests added (present, empty, absent)

- reconcilemanager: renumber inline step comments 1–9 to reflect the new
  pause check sitting between session construction and finalizer management

Signed-off-by: Nishanth Kolakalapudi <Nishanth.Kol@ibm.com>
@Tanker2020
Tanker2020 marked this pull request as ready for review August 13, 2026 16:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant