diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index c80eb5e6..ecc8c928 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -198,6 +198,10 @@ func (cad *cadEngine) CreatePackageRevision(ctx context.Context, repositoryObj * } pkgRevMeta, err = cad.metadataStore.Create(ctx, pkgRevMeta, repositoryObj.Name, repoPkgRev.UID()) if err != nil { + if (apierrors.IsUnauthorized(err) || apierrors.IsForbidden(err)) && repository.AnyBlockOwnerDeletionSet(obj) { + return nil, fmt.Errorf("failed to create internal PackageRev object, because blockOwnerDeletion is enabled for some ownerReference "+ + "(it is likely that the serviceaccount of porch-server does not have the rights to update finalizers in the owner object): %w", err) + } return nil, err } repoPkgRev.SetMeta(pkgRevMeta) @@ -318,6 +322,10 @@ func (cad *cadEngine) UpdatePackageRevision(ctx context.Context, version string, err = cad.updatePkgRevMeta(ctx, repoPkgRev, newObj) if err != nil { + if (apierrors.IsUnauthorized(err) || apierrors.IsForbidden(err)) && repository.AnyBlockOwnerDeletionSet(newObj) { + return nil, fmt.Errorf("failed to update internal PackageRev object, because blockOwnerDeletion is enabled for some ownerReference "+ + "(it is likely that the serviceaccount of porch-server does not have the rights to update finalizers in the owner object): %w", err) + } return nil, err } diff --git a/pkg/repository/util.go b/pkg/repository/util.go index 01b7cb23..4677f8f0 100644 --- a/pkg/repository/util.go +++ b/pkg/repository/util.go @@ -26,6 +26,7 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/trace" "golang.org/x/mod/semver" + "sigs.k8s.io/controller-runtime/pkg/client" ) var tracer = otel.Tracer("repository/util") @@ -136,3 +137,14 @@ func ValidateWorkspaceName(workspace api.WorkspaceName) error { return nil } + +// AnyBlockOwnerDeletionSet checks whether there are any ownerReferences in the Object +// which have blockOwnerDeletion enabled (meaning either nil or true). +func AnyBlockOwnerDeletionSet(obj client.Object) bool { + for _, owner := range obj.GetOwnerReferences() { + if owner.BlockOwnerDeletion == nil || *owner.BlockOwnerDeletion { + return true + } + } + return false +}