Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Have PackageVariant set readiness gate on PackageRevisions #156

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

JamesMcDermott
Copy link
Contributor

Implements #615

  • PackageVariant controller now uses a readiness gate to allow a PackageRevision to complete its mutation pipeline before it is allowed to be proposed/approved
  • refactors conversion of Kptfiles to YAML since readiness condition information is stored in the package Kptfile
    • unifies all cases to the same kyaml/yaml-based method (KptFile.ToYamlString() and ToYamlString(*fn.KubeObject))
    • this ensures consistency in the Kptfile YAML (indentation, field order etc.)
    • and reduces the chances of Git conflicts when setting and updating readiness conditions
  • adds more info to error message in case of Git conflict when applying a patch

Copy link
Contributor

nephio-prow bot commented Dec 10, 2024

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: JamesMcDermott
Once this PR has been reviewed and has the lgtm label, please assign henderiw for approval by writing /assign @henderiw in a comment. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@efiacor
Copy link
Collaborator

efiacor commented Dec 10, 2024

/test presubmit-nephio-go-test

@@ -334,6 +350,13 @@ func (r *PackageVariantReconciler) ensurePackageVariant(ctx context.Context,
if err = r.Client.Create(ctx, newPR); err != nil {
return nil, err
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks good. I'd be interested to see how this works in a full test-infra e2e run.
Also, may be somewhat aligned with what @kispaljr was working on?

@efiacor
Copy link
Collaborator

efiacor commented Dec 10, 2024

/test presubmit-nephio-go-test

5 similar comments
@JamesMcDermott
Copy link
Contributor Author

/test presubmit-nephio-go-test

@JamesMcDermott
Copy link
Contributor Author

/test presubmit-nephio-go-test

@JamesMcDermott
Copy link
Contributor Author

/test presubmit-nephio-go-test

@liamfallon
Copy link
Member

/test presubmit-nephio-go-test

@JamesMcDermott
Copy link
Contributor Author

/test presubmit-nephio-go-test

Copy link
Collaborator

@kispaljr kispaljr left a comment

Choose a reason for hiding this comment

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

I welcome this PR, and wholeheartedly agree with the general direction. :)
These are my initial comments, but could you give me also a couple more days to understand the logic a bit better?

ConditionTypeReady = "Ready" // whether or not the reconciliation succeeded
ConditionTypeStalled = "Stalled" // whether or not the packagevariant object is making progress or not
ConditionTypeReady = "Ready" // whether or not the reconciliation succeeded
ConditionTypePipelinePassed = "MutationPipelinePassed" // whether or not the mutation pipeline has completed successufully
Copy link
Collaborator

Choose a reason for hiding this comment

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

I suggest to rename it to PackagePipelinePassed or similar, since the success of the validation pipeline should be checked, as well, not just the mutation pipeline.

Copy link
Collaborator

Choose a reason for hiding this comment

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

This of course also applies to all other places where it is referenced as a "mutation pipeline" (e.g. in conditions)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

pkg/kpt/api/kptfile/v1/types.go Show resolved Hide resolved
if err := r.Client.Get(ctx, types.NamespacedName{Name: newPR.GetName(), Namespace: newPR.GetNamespace()}, &refreshedPR); err != nil {
return nil, err
}
newPR.ResourceVersion = refreshedPR.ResourceVersion
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why are only ResourceVersion and Tasks are copied and every other potential changes are reverted back?
Why aren't we simply Get() the PR into &newPR, set the condition and update?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done - the copy/revert thing with refreshedPR was left over from solving an earlier hurdle and it isn't needed now.

@@ -347,6 +371,29 @@ func (r *PackageVariantReconciler) ensurePackageVariant(ctx context.Context,
}
}

// TODO: remove if OK to exclude PackageRevision from cache of r.Client
Copy link
Collaborator

@kispaljr kispaljr Dec 13, 2024

Choose a reason for hiding this comment

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

remove this comment block if not needed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Copy link
Collaborator

@kispaljr kispaljr Dec 13, 2024

Choose a reason for hiding this comment

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

In the findAndUpdateExistingRevisions() method, at line 473:

			// Save the updated PackageRevisionResources
			if err := r.updatePackageResources(ctx, prr, pv); err != nil {
				return nil, err
			}

The pipeline will also be executed here, so the Condition should be set according to the results.

Copy link
Collaborator

@kispaljr kispaljr Dec 13, 2024

Choose a reason for hiding this comment

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

in updateDraft() at line 736:

	err := r.Client.Update(ctx, draft)
	if err != nil {
		return nil, err
	}

this is tricky, but technically this Update() call will also result in the re-execution of the pipeline, so we should record the results in the Condition. The tricky part is that I don't know how to get the rendering results, and without it, the best we can do is to report the error or success of Update() itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done both:

  • the findAndUpdateExistingRevisions() one could be a bit better by including the initial set of the Condition directly in prr instead of doing a separate r.Client.Update() - I want to look into automated (and a few more manual) tests first though
  • the updateDraft() one took more time to work around to avoid ending up in an endless loop where doing the Update() to set the Condition would trigger the pipeline, resulting in a rendering result which we'd need to record in the Condition by doing an Update(), triggering the pipeline... you get the idea. :)
    • thanks to @liamfallon for suggesting we have the server detect and skip the pipeline when an update only sets the Condition/readiness info
    • works as desired when creating a PackageVariant - unable to test in this update flow due to immediate Git conflicts as seen in #469

- PackageVariant controller now uses a readiness gate to allow
  a PackageRevision to complete its mutation pipeline before it
  is allowed to be proposed/approved
- refactored conversion of Kptfiles to YAML since readiness condition
  information is stored in the package Kptfile
  - unified all cases to the same kyaml/yaml-based method
    (KptFile.ToYamlString() and ToYamlString(*fn.KubeObject))
  - this ensures consistency in the YAML (indentation, field order etc.)
  - and reduces the chances of Git conflicts when setting and updating
    readiness conditions
- added more info to error message in case of Git conflict when applying
  a patch

nephio-project/nephio#615
- previous solution broke existing functionality to copy comments between Kptfile objects
  - resulting in failing unit tests
    - fix for that brought back the Git conflicts caused by indentation, field order etc.
    - re-refactored conversion of Kptfiles to YAML
      - KubeObject-related conversion methods (KubeObject/YAML and YAML/KubeObject)
        now live out in the util package as they aren't Kptfile-specific any more

nephio-project/nephio#615
@JamesMcDermott JamesMcDermott force-pushed the pv-pipeline-readiness-gates branch from 3cff6bb to 60cb107 Compare December 17, 2024 10:30
… pipeline-passed condition

- review comments to increase applicability of pipeline-passed readiness condition
  - to enable this: if an incoming PackageRevision update changes only that
    readiness condition, detect that, skip the pipeline/rendering/etc., and
    only update the Kptfile with the readiness condition update
- other tidy-up/wording comments

nephio-project/nephio#615
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants