Repository navigation
feat: provider-runtime v1.8.2 — set Ready on every successful Observe - #31
Merged
Merged
Conversation
provider-runtime v1.8.0 makes Ready the provider's to set. When Connect or Observe fails, the runtime sets Ready=Unknown/NotObserved, unless Ready is Deleting or the error is wrapped with reconciler.ReadyAssessed. Every successful Observe must then set Ready again, or NotObserved stays and the runtime emits a ReadyNotSetAfterObserve Warning. Repo Observe: - deletion after a ReconcileError: Deleting (the object is being released) - nothing pushed yet: Unavailable - pushed commit no longer on the target branch, enableUpdate=true: Unavailable, as on the enableUpdate=false branch - origin ahead, enableUpdate=true: Available; the drift is carried by ResourceUpToDate=false - the enableUpdate=false unreachable-commit error is wrapped with ReadyAssessed, so the Unavailable failSync sets survives LocalResource Observe: - deletion after a ReconcileError: Deleting - nothing committed yet: Unavailable - an older spec committed: Available, also when syncEnabled=false makes Update a no-op Tests call reconcilertest.AssertObserveSetsReady once per success path, against local git repositories (new internal/clients/git/gittest), and check the ReadyAssessed error and that a could-not-tell error stays plain. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016RAxvnK22nQGNMCWkPMj9z
…s during deletion v1.8.1 stops requiring Ready from a successful Observe on a resource being deleted, because the runtime's deletion branch sets Deleting itself. The Deleting writes on the deletion returns stay: they are allowed and keep every path taken while deleting on the same Ready. That exemption covers successes only. On an Observe error the runtime writes NotObserved unless Deleting is already on the object. So Observe now wraps the old body (observe) and sets Deleting before returning an error for a resource being deleted. This includes the unreachable-commit error, where failSync had set Unavailable. Tests cover both controllers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016RAxvnK22nQGNMCWkPMj9z
…ndant v1.8.2 sets Ready=Deleting itself when Connect or Observe fails on a resource with a deletion timestamp. That makes the observe() wrapper, which set Deleting before any such error, redundant, so it is removed from both controllers along with LocalResource's test of it. One case is still the provider's: the runtime checks ReadyAssessed before deletion, so it leaves a ReadyAssessed Ready alone even on a resource being deleted. Repo's unreachable-commit error is ReadyAssessed (failSync set Unavailable), so that call site now sets Deleting itself when the Repo is being deleted. Its test is kept, narrowed to this case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016RAxvnK22nQGNMCWkPMj9z
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Warning
Do not release or roll this to a cluster until core-provider 2.13.56 is live on that cluster. That's the core-provider rollup release that maps
NotObserved(krateo-platformops/core-provider#310). It's released, but a cluster still on an older core-provider would read the newReady=Unknown/NotObservedwrong. Merging is fine. Cutting a git-provider release or rolling it to a cluster is not, until 2.13.56 is live there.The contract
This PR bumps
github.com/krateo-platformops/provider-runtimefrom v1.7.2 to v1.8.2. v1.8.0 makesReadythe provider's to set (runtimedocs/overview.md, "The Ready contract"):Observethat returns a nil error setsReady, including theResourceExists: falseandResourceUpToDate: falsepaths. v1.8.1 makes one exception: a resource being deleted. The runtime's deletion branch setsReady=Deletingitself, so a successfulObserveowes nothing there. Setting it anyway is allowed.ConnectorObservefails, the runtime setsReady=Unknown/NotObserved. There are two exceptions. If the error is wrapped withreconciler.ReadyAssessed("I setReadymyself in this call"), the runtime leavesReadyas the provider set it. This is checked first. Otherwise, if the resource is being deleted, the runtime setsReady=Deleting(since v1.8.2).ObserveleavesNotObservedin place, the runtime keeps it and emits aReadyNotSetAfterObserveWarning. Since v1.8.1 this never happens for a resource being deleted.Bumping alone would leave some paths stuck on
NotObserved. For example, a drifted LocalResource withsyncEnabled: falsewould stayNotObservedforever, because Update does nothing there. That's why the bump and the fixes come in one PR. v1.8.0 through v1.8.2 change only this contract (provider-runtime#22, #23, and v1.8.2's Deleting-on-error).Paths changed
An
Observeerror while being deletedSince v1.8.2, the runtime answers a plain
ConnectorObserveerror on a resource being deleted withReady=Deleting, so neither controller handles it. The runtime checksReadyAssessedfirst, so it leaves aReadyAssessedReadyalone even during deletion. Repo's unreachable-commit error is the one such error (failSyncsetsUnavailable). For a Repo being deleted, that call site now setsDeletingover it (repo.go:233).Deletingholds whatever the target answers. WithDeletingon the object, the nextObservetakes the existingReady=Deletingshortcut and the runtime releases the object. Neither controller removes anything from the target on delete (Deleteis a no-op), so nothing is skipped.Repo (
internal/controllers/repo/repo.go)ReconcileError, delete allowed (:152)Ready.:172)Creating. This follows the runtime's greeting-controller example.enableUpdate=true(:240)enableUpdate=falsebranch, which already reportsUnavailablethroughfailSync.enableUpdate=true(:255)ResourceUpToDate=falsecarries the drift. This matches theenableUpdate=falsebranch, which already falls through toAvailable. Before, this path relied on Update settingCreating, but Update does nothing when the policy blocks updates, and the reconciler skips Update under!ShouldUpdate.enableUpdate=false(:236)failSyncsetsUnavailable+ReconcileErrorand returns the error. That's a finding, not a failure to observe: the target was read and the commit isn't on it. The error is now wrapped withreconciler.ReadyAssessed, soUnavailablesurvives and the message is unchanged (#23). On a Repo being deleted,Deletingreplaces it (see above).The other paths are unchanged. The
Ready=Deletingearly return (:138) has nothing new to report. Up to date and "origin ahead,enableUpdate=false" already setAvailable(:264). The remote-read errors (:189,:202) stay plain, because they mean "could not tell" andNotObservedis the right answer there.LocalResource (
internal/controllers/localresource/localresource.go)ReconcileError, delete allowed (:199):246)ResourceUpToDate=falsecarries the drift. Update commits the current spec, unlesssyncEnabled: falseor the policy blocks updates. In those cases the file stays as it is, and so doesAvailable.:264)The rest is unchanged. The up-to-date path, and the path where Create recorded the branch head without a footer commit, already set
Available(:271). No LocalResource error follows aReadywrite, so nothing there is wrapped.Connect
Both controllers read secrets in
Connect. AConnectfailure (for example a missing credentials secret) now showsReady=Unknown/NotObservednext toSynced=False/ReconcileError, whereReadyused to keep its last value. That's intended (contract rule 2), soConnectis unchanged.Tests
internal/clients/git/gittest: a new test-only helper that creates git repositories int.TempDir(), so Observe reads real history from a local path. It needs no network or git server, butgitmust be onPATH, because go-git serves a local path throughgit-upload-pack.repo/observe_ready_test.go:TestObserveSetsReadycallsreconcilertest.AssertObserveSetsReadyonce per success path: deletion, not synced, unreachable commit with updates, origin ahead with and without updates, up to date. Each case first checks that Observe returns theExternalObservationfor the path it names, then checks theReadyreason.TestObserveUnreachableTargetCommitIsReadyAssessed: the error isIsReadyAssessed, its message is unchanged,Ready=False/Unavailable,Synced=ReconcileError.TestObserveUnreadableRemoteIsNotReadyAssessed: a could-not-tell error stays plain.TestObserveUnreachableTargetCommitWhileDeletingSetsDeleting: on a Repo being deleted, the error staysReadyAssessedandReady=Deleting. That's the one deleting case the runtime doesn't cover. Plain errors during deletion are covered by provider-runtime's own tests.localresource/observe_ready_test.go: the same pattern. Its cases are deletion, not committed, drifted withsyncEnabled: false, up to date, and recorded without a footer, plus the plain-error check.On
main's controller code, the new tests fail on exactly the paths this PR changes and pass on the rest. With the Deleting write at repo.go:233 removed, the deleting test fails.Verification
go build ./...go vet ./...andgo vet -tags=unit,integration ./...go test -race -count=1 ./...ok-tags=integration)No Makefile in this repo. No release is cut by this PR.
🤖 Generated with Claude Code
https://claude.ai/code/session_016RAxvnK22nQGNMCWkPMj9z