Skip to content

fix(operator): bound lazy storage-gate dial by step timeout#8

Merged
imlach merged 2 commits into
fix/lazy-storage-gatefrom
fix/storage-gate-review-fixes
Jul 2, 2026
Merged

fix(operator): bound lazy storage-gate dial by step timeout#8
imlach merged 2 commits into
fix/lazy-storage-gatefrom
fix/storage-gate-review-fixes

Conversation

@imlach

@imlach imlach commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Summary

Addresses the review on #7: #7 (comment)

  • Bound the TrueNAS dial by the step timeout: lazyStorageGate's closure in internal/operate/operate.go now defaults a <=0 timeout to 5 minutes (mirroring waitPowerOff in internal/lifecycle/drainshutdown.go) and always wraps ctx in context.WithTimeout(ctx, timeout) before calling BuildStorageGate, so the unbounded dial+auth (truenas.New has no internal deadline) shares one coherent budget with WaitDetached instead of only the wait being bounded. This also fixes the timeout=0 case (reachable via the unvalidated --storage-timeout flag), which previously meant "unbounded dial, instantly-expired wait" because iscsi.Gate.WaitClear applies WithTimeout unconditionally.
  • Fixed three stale comments left over from the eager storage-gate lifecycle: Config's doc comment, Backends.Close's doc comment (both in internal/operate/operate.go), and the reconciler's defer be.Close() comment in internal/controller/elasticnode_controller.go — all now describe the lazy dial / close-inside-the-gate-call behavior instead of the old eager-TrueNAS-websocket one.
  • Deduplicated the TrueNAS env-presence check: added operate.TrueNASConfigured() bool and used it in lazyStorageGate, BuildStorageGate, and cmd/nightwatch/drainshutdown.go's plan display, replacing three independent copies of host == "" || user == "" || key == "". lazyStorageGate and BuildStorageGate still return a nil gate/interface when unconfigured — only the presence check itself moved behind the helper.

Follow-up (second commit, from review on this PR): also removed the dead buildStorageGate wrapper from cmd/nightwatch/drainshutdown.go (nothing called it since the run path moved to operate.RealBuilder); its no-creds test moved to the operate package next to BuildStorageGate.

Not addressed here: the same review raised a question about eager validation of iscsi_initiator_addr on the drain path (nodes missing that field currently drain fully before the storage-gate step surfaces the config error). That's a behavior-change decision, not a bug fix, and is intentionally left for a separate PR.

Tests

  • gofmt -l . — clean
  • go build ./... — clean
  • go vet ./... — clean
  • go test ./... — all packages pass

imlach added 2 commits July 2, 2026 08:18
Addresses review findings on #7's lazy storage-gate change
(#7 (comment)):

- lazyStorageGate's closure now wraps ctx in context.WithTimeout(timeout)
  before calling BuildStorageGate, so the unbounded TrueNAS dial+auth
  (truenas.New has no internal deadline) shares the step's timeout budget
  with WaitDetached instead of only bounding the wait. Guarded on
  timeout > 0 so a zero/unset StorageTimeout degrades to "unbounded,
  ctx-only" rather than an instantly-expired context, matching how other
  steps (e.g. waitPowerOff) treat <=0 as "no override".
- Reworded three comments left over from the eager storage-gate lifecycle
  (Config's env-at-build-time doc, Backends.Close's TrueNAS-websocket
  mention, and the reconciler's Close comment) to describe the current
  lazy dial/close-inside-the-gate-call behavior.
- Added operate.TrueNASConfigured(), deduplicating the three copies of the
  TrueNAS env-presence check (lazyStorageGate, BuildStorageGate, and the
  CLI's drain-shutdown plan display). lazyStorageGate and BuildStorageGate
  still return a nil gate when unconfigured; only the presence check moved.

The drain-path eager-identity-validation question raised in the same
review is intentionally not addressed here, pending a design decision.
Review follow-ups on #8:

- lazyStorageGate now defaults timeout<=0 to 5 minutes (mirroring
  waitPowerOff) and always bounds ctx with context.WithTimeout, instead
  of guarding on timeout>0. The previous comment mis-cited waitPowerOff
  as treating <=0 as "no override" (it defaults to 5m), and leaving ctx
  unbounded for <=0 was incoherent anyway: iscsi.Gate.WaitClear applies
  WithTimeout unconditionally, so timeout=0 (reachable via the
  unvalidated --storage-timeout flag) meant "unbounded dial,
  instantly-expired wait". Now dial + wait share one coherent budget.
- drop the dead buildStorageGate CLI wrapper from
  cmd/nightwatch/drainshutdown.go (nothing calls it since the run path
  moved to operate.RealBuilder) and its unused lifecycle import; its
  no-creds test moves to the operate package, next to BuildStorageGate.
@imlach imlach marked this pull request as ready for review July 2, 2026 08:37
@imlach imlach merged commit 8102a7e into fix/lazy-storage-gate Jul 2, 2026
2 checks passed
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