Skip to content

Commit

Permalink
Retry Update() operations in CLI commands
Browse files Browse the repository at this point in the history
  • Loading branch information
kispaljr committed Aug 23, 2024
1 parent fb8917b commit a508832
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 87 deletions.
23 changes: 12 additions & 11 deletions internal/kpt/util/porch/approval.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,25 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
)

func UpdatePackageRevisionApproval(ctx context.Context, client client.Client, key client.ObjectKey, new v1alpha1.PackageRevisionLifecycle) error {

var pr v1alpha1.PackageRevision
if err := client.Get(ctx, key, &pr); err != nil {
return err
}
func UpdatePackageRevisionApproval(ctx context.Context, client client.Client, pr *v1alpha1.PackageRevision, new v1alpha1.PackageRevisionLifecycle) error {

switch lifecycle := pr.Spec.Lifecycle; lifecycle {
case v1alpha1.PackageRevisionLifecycleProposed, v1alpha1.PackageRevisionLifecycleDeletionProposed:
// ok
case v1alpha1.PackageRevisionLifecycleProposed:
// Approve - change the package revision kind to 'final'.
if new != v1alpha1.PackageRevisionLifecyclePublished && new != v1alpha1.PackageRevisionLifecycleDraft {
return fmt.Errorf("cannot change approval from %s to %s", lifecycle, new)
}
case v1alpha1.PackageRevisionLifecycleDeletionProposed:
if new != v1alpha1.PackageRevisionLifecyclePublished {
return fmt.Errorf("cannot change approval from %s to %s", lifecycle, new)
}
case new:
// already correct value
return nil
default:
return fmt.Errorf("cannot change approval from %s to %s", lifecycle, new)
}
// Approve - change the package revision kind to "final".
pr.Spec.Lifecycle = new
return client.SubResource("approval").Update(ctx, &pr)

pr.Spec.Lifecycle = new
return client.SubResource("approval").Update(ctx, pr)
}
14 changes: 11 additions & 3 deletions pkg/cli/commands/rpkg/approve/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/nephio-project/porch/pkg/cli/commands/rpkg/docs"
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/util/retry"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand Down Expand Up @@ -83,17 +84,24 @@ func (r *runner) runE(_ *cobra.Command, args []string) error {
namespace := *r.cfg.Namespace

for _, name := range args {
if err := porch.UpdatePackageRevisionApproval(r.ctx, r.client, client.ObjectKey{
key := client.ObjectKey{
Namespace: namespace,
Name: name,
}, v1alpha1.PackageRevisionLifecyclePublished); err != nil {
}
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
var pr v1alpha1.PackageRevision
if err := r.client.Get(r.ctx, key, &pr); err != nil {
return err
}
return porch.UpdatePackageRevisionApproval(r.ctx, r.client, &pr, v1alpha1.PackageRevisionLifecyclePublished)
})
if err != nil {
messages = append(messages, err.Error())
fmt.Fprintf(r.Command.ErrOrStderr(), "%s failed (%s)\n", name, err)
} else {
fmt.Fprintf(r.Command.OutOrStdout(), "%s approved\n", name)
}
}

if len(messages) > 0 {
return errors.E(op, fmt.Errorf("errors:\n %s", strings.Join(messages, "\n ")))
}
Expand Down
46 changes: 24 additions & 22 deletions pkg/cli/commands/rpkg/propose/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/nephio-project/porch/pkg/cli/commands/rpkg/docs"
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/util/retry"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand Down Expand Up @@ -83,33 +84,34 @@ func (r *runner) runE(_ *cobra.Command, args []string) error {
namespace := *r.cfg.Namespace

for _, name := range args {
pr := &v1alpha1.PackageRevision{}
if err := r.client.Get(r.ctx, client.ObjectKey{
key := client.ObjectKey{
Namespace: namespace,
Name: name,
}, pr); err != nil {
return errors.E(op, err)
}

switch pr.Spec.Lifecycle {
case v1alpha1.PackageRevisionLifecycleDraft:
// ok
case v1alpha1.PackageRevisionLifecycleProposed:
fmt.Fprintf(r.Command.OutOrStderr(), "%s is already proposed\n", name)
continue
default:
msg := fmt.Sprintf("cannot propose %s package", pr.Spec.Lifecycle)
messages = append(messages, msg)
fmt.Fprintln(r.Command.ErrOrStderr(), msg)
continue
}

pr.Spec.Lifecycle = v1alpha1.PackageRevisionLifecycleProposed
if err := r.client.Update(r.ctx, pr); err != nil {
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
var pr v1alpha1.PackageRevision
if err := r.client.Get(r.ctx, key, &pr); err != nil {
return err
}

switch pr.Spec.Lifecycle {
case v1alpha1.PackageRevisionLifecycleDraft:
pr.Spec.Lifecycle = v1alpha1.PackageRevisionLifecycleProposed
err := r.client.Update(r.ctx, &pr)
if err == nil {
fmt.Fprintf(r.Command.OutOrStdout(), "%s proposed\n", name)
}
return err
case v1alpha1.PackageRevisionLifecycleProposed:
fmt.Fprintf(r.Command.OutOrStderr(), "%s is already proposed\n", name)
return nil
default:
return fmt.Errorf("cannot propose %s package", pr.Spec.Lifecycle)
}
})
if err != nil {
messages = append(messages, err.Error())
fmt.Fprintf(r.Command.ErrOrStderr(), "%s failed (%s)\n", name, err)
} else {
fmt.Fprintf(r.Command.OutOrStdout(), "%s proposed\n", name)
}
}

Expand Down
48 changes: 25 additions & 23 deletions pkg/cli/commands/rpkg/proposedelete/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/nephio-project/porch/pkg/cli/commands/rpkg/docs"
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/util/retry"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand Down Expand Up @@ -83,39 +84,40 @@ func (r *runner) runE(_ *cobra.Command, args []string) error {
namespace := *r.cfg.Namespace

for _, name := range args {
pr := &v1alpha1.PackageRevision{}
if err := r.client.Get(r.ctx, client.ObjectKey{
key := client.ObjectKey{
Namespace: namespace,
Name: name,
}, pr); err != nil {
return errors.E(op, err)
}

switch pr.Spec.Lifecycle {
case v1alpha1.PackageRevisionLifecyclePublished:
// ok
case v1alpha1.PackageRevisionLifecycleDeletionProposed:
fmt.Fprintf(r.Command.OutOrStderr(), "%s is already proposed for deletion\n", name)
continue
default:
msg := fmt.Sprintf("can only propose published packages for deletion; package %s is not published", name)
messages = append(messages, msg)
fmt.Fprintln(r.Command.ErrOrStderr(), msg)
continue
}

pr.Spec.Lifecycle = v1alpha1.PackageRevisionLifecycleDeletionProposed
if err := r.client.Update(r.ctx, pr); err != nil {
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
var pr v1alpha1.PackageRevision
if err := r.client.Get(r.ctx, key, &pr); err != nil {
return err
}

switch pr.Spec.Lifecycle {
case v1alpha1.PackageRevisionLifecyclePublished:
pr.Spec.Lifecycle = v1alpha1.PackageRevisionLifecycleDeletionProposed
err := r.client.Update(r.ctx, &pr)
if err == nil {
fmt.Fprintf(r.Command.OutOrStdout(), "%s proposed for deletion\n", name)
}
return err
case v1alpha1.PackageRevisionLifecycleDeletionProposed:
fmt.Fprintf(r.Command.OutOrStderr(), "%s is already proposed for deletion\n", name)
return nil
default:
return fmt.Errorf("can only propose published packages for deletion; package %s is not published", name)
}

})
if err != nil {
messages = append(messages, err.Error())
fmt.Fprintf(r.Command.ErrOrStderr(), "%s failed (%s)\n", name, err)
} else {
fmt.Fprintf(r.Command.OutOrStdout(), "%s proposed for deletion\n", name)
}
}

if len(messages) > 0 {
return errors.E(op, fmt.Errorf("errors:\n %s", strings.Join(messages, "\n ")))
}

return nil
}
51 changes: 24 additions & 27 deletions pkg/cli/commands/rpkg/reject/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/nephio-project/porch/pkg/cli/commands/rpkg/docs"
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/util/retry"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand Down Expand Up @@ -85,41 +86,37 @@ func (r *runner) runE(_ *cobra.Command, args []string) error {
var messages []string

namespace := *r.cfg.Namespace

var proposedFor string
for _, name := range args {
pr := &v1alpha1.PackageRevision{}
if err := r.client.Get(r.ctx, client.ObjectKey{
key := client.ObjectKey{
Namespace: namespace,
Name: name,
}, pr); err != nil {
return errors.E(op, err)
}
switch pr.Spec.Lifecycle {
case v1alpha1.PackageRevisionLifecycleProposed:
if err := porch.UpdatePackageRevisionApproval(r.ctx, r.client, client.ObjectKey{
Namespace: namespace,
Name: name,
}, v1alpha1.PackageRevisionLifecycleDraft); err != nil {
messages = append(messages, err.Error())
fmt.Fprintf(r.Command.ErrOrStderr(), "%s failed (%s)\n", name, err)
} else {
fmt.Fprintf(r.Command.OutOrStdout(), "%s rejected\n", name)
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
var pr v1alpha1.PackageRevision
if err := r.client.Get(r.ctx, key, &pr); err != nil {
return err
}
case v1alpha1.PackageRevisionLifecycleDeletionProposed:
pr.Spec.Lifecycle = v1alpha1.PackageRevisionLifecyclePublished
if err := r.client.Update(r.ctx, pr); err != nil {
messages = append(messages, err.Error())
fmt.Fprintf(r.Command.ErrOrStderr(), "%s failed (%s)\n", name, err)
} else {
fmt.Fprintf(r.Command.OutOrStdout(), "%s no longer proposed for deletion\n", name)
switch pr.Spec.Lifecycle {
case v1alpha1.PackageRevisionLifecycleProposed:
proposedFor = "approval"
return porch.UpdatePackageRevisionApproval(r.ctx, r.client, &pr, v1alpha1.PackageRevisionLifecycleDraft)
case v1alpha1.PackageRevisionLifecycleDeletionProposed:
proposedFor = "deletion"
// NOTE(kispaljr): should we use UpdatePackageRevisionApproval() here?
pr.Spec.Lifecycle = v1alpha1.PackageRevisionLifecyclePublished
return r.client.Update(r.ctx, &pr)
default:
return fmt.Errorf("cannot reject %s with lifecycle '%s'", name, pr.Spec.Lifecycle)
}
default:
msg := fmt.Sprintf("cannot reject %s with lifecycle '%s'", name, pr.Spec.Lifecycle)
messages = append(messages, msg)
fmt.Fprintln(r.Command.ErrOrStderr(), msg)
})
if err != nil {
messages = append(messages, err.Error())
fmt.Fprintf(r.Command.ErrOrStderr(), "%s failed (%s)\n", name, err)
} else {
fmt.Fprintf(r.Command.OutOrStdout(), "%s no longer proposed for %s\n", name, proposedFor)
}
}

if len(messages) > 0 {
return errors.E(op, fmt.Errorf("errors:\n %s", strings.Join(messages, "\n ")))
}
Expand Down
11 changes: 10 additions & 1 deletion pkg/cli/commands/rpkg/update/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/nephio-project/porch/pkg/cli/commands/rpkg/docs"
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/util/retry"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand Down Expand Up @@ -114,7 +115,15 @@ func (r *runner) runE(cmd *cobra.Command, args []string) error {
if pr == nil {
return errors.E(op, fmt.Errorf("could not find package revision %s", args[0]))
}
if err := r.doUpdate(pr); err != nil {
key := client.ObjectKeyFromObject(pr)
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
var pr porchapi.PackageRevision
if err := r.client.Get(r.ctx, key, &pr); err != nil {
return err
}
return r.doUpdate(&pr)
})
if err != nil {
return errors.E(op, err)
}
if _, err := fmt.Fprintf(cmd.OutOrStdout(), "%s updated\n", pr.Name); err != nil {
Expand Down

0 comments on commit a508832

Please sign in to comment.