From 865744926b9669f794114355944223373fad9951 Mon Sep 17 00:00:00 2001 From: Timofey Kirillov Date: Wed, 14 Sep 2022 19:36:15 +0300 Subject: [PATCH] fix(dismiss): rework uninstall-with-namespace procedure * Better logging when checking existance of release and namespace. * Fix case when release not exists, but namespace exists and --with-namespace option specified (previously namespace was not removed in such case). * Do not create namespace when it was not existed before running werf-dismiss. Refs https://github.com/werf/3p-helm/pull/218/commits Signed-off-by: Timofey Kirillov --- cmd/werf/dismiss/dismiss.go | 10 ++++++++ go.mod | 2 +- go.sum | 4 ++-- pkg/deploy/helm/init.go | 3 +++ pkg/deploy/lock_manager/lock_manager.go | 32 +++++++++++++++++++++---- 5 files changed, 43 insertions(+), 8 deletions(-) diff --git a/cmd/werf/dismiss/dismiss.go b/cmd/werf/dismiss/dismiss.go index b4229fe583..e5ffc5977c 100644 --- a/cmd/werf/dismiss/dismiss.go +++ b/cmd/werf/dismiss/dismiss.go @@ -2,12 +2,14 @@ package dismiss import ( "context" + "errors" "fmt" "time" "github.com/spf13/cobra" helm_v3 "helm.sh/helm/v3/cmd/helm" "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/storage/driver" "github.com/werf/kubedog/pkg/kube" "github.com/werf/logboek" @@ -240,10 +242,18 @@ func runDismiss(ctx context.Context) error { DontFailIfNoRelease: &dontFailIfNoRelease, }) + logboek.Context(ctx).Default().LogFDetails("Using namespace: %s\n", namespace) + logboek.Context(ctx).Default().LogFDetails("Using release: %s\n", releaseName) + if cmdData.WithNamespace { // TODO: solve lock release + delete-namespace case return helmUninstallCmd.RunE(helmUninstallCmd, []string{releaseName}) } else { + if _, err := actionConfig.Releases.History(releaseName); errors.Is(err, driver.ErrReleaseNotFound) { + logboek.Context(ctx).Default().LogFDetails("No such release %q\n", releaseName) + return nil + } + return command_helpers.LockReleaseWrapper(ctx, releaseName, lockManager, func() error { return helmUninstallCmd.RunE(helmUninstallCmd, []string{releaseName}) }) diff --git a/go.mod b/go.mod index c7d669e54b..07836de1d6 100644 --- a/go.mod +++ b/go.mod @@ -314,6 +314,6 @@ replace k8s.io/helm => github.com/werf/helm v0.0.0-20210202111118-81e74d46da0f replace github.com/deislabs/oras => github.com/werf/third-party-oras v0.9.1-0.20210927171747-6d045506f4c8 -replace helm.sh/helm/v3 => github.com/werf/3p-helm/v3 v3.0.0-20220902145201-6265178e3c32 +replace helm.sh/helm/v3 => github.com/werf/3p-helm/v3 v3.0.0-20220914162629-ff5881b99e90 replace github.com/go-git/go-git/v5 => github.com/ZauberNerd/go-git/v5 v5.4.3-0.20220315170230-29ec1bc1e5db diff --git a/go.sum b/go.sum index 29e6137ffd..7ba6f43f78 100644 --- a/go.sum +++ b/go.sum @@ -2050,8 +2050,8 @@ github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59b github.com/weppos/publicsuffix-go v0.4.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= github.com/weppos/publicsuffix-go v0.5.0 h1:rutRtjBJViU/YjcI5d80t4JAVvDltS6bciJg2K1HrLU= github.com/weppos/publicsuffix-go v0.5.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= -github.com/werf/3p-helm/v3 v3.0.0-20220902145201-6265178e3c32 h1:Z3XL0banUFF7IkIzY82onwWA2qiTvuQ0pBMERA/scis= -github.com/werf/3p-helm/v3 v3.0.0-20220902145201-6265178e3c32/go.mod h1:NxtE2KObf2PrzDl6SIamPFPKyAqWi10iWuvKlQn/Yao= +github.com/werf/3p-helm/v3 v3.0.0-20220914162629-ff5881b99e90 h1:Gsp+PghpTAj8vVIt68f6kEr+4qtbQsMi2/rCCSuV4ic= +github.com/werf/3p-helm/v3 v3.0.0-20220914162629-ff5881b99e90/go.mod h1:NxtE2KObf2PrzDl6SIamPFPKyAqWi10iWuvKlQn/Yao= github.com/werf/copy-recurse v0.2.4 h1:kEyGUKhgS8WdEOjInNQKgk4lqPWzP2AgR27F3dcGsVc= github.com/werf/copy-recurse v0.2.4/go.mod h1:KVHSQ90p19xflWW0B7BJhLBwmSbEtuxIaBnjlUYRPhk= github.com/werf/helm v0.0.0-20210202111118-81e74d46da0f h1:81YscYTF9mmTf0ULOsCmm42YWQp+qWDzWi1HjWniZrg= diff --git a/pkg/deploy/helm/init.go b/pkg/deploy/helm/init.go index 963bf4406d..aec26360d4 100644 --- a/pkg/deploy/helm/init.go +++ b/pkg/deploy/helm/init.go @@ -64,6 +64,9 @@ func InitActionConfig(ctx context.Context, kubeInitializer KubeInitializer, name kubeClient.Extender = NewHelmKubeClientExtender() actionConfig.RegistryClient = registryClient + actionConfig.Log = func(f string, a ...interface{}) { + logboek.Context(ctx).Default().LogFDetails(fmt.Sprintf("%s\n", f), a...) + } return nil } diff --git a/pkg/deploy/lock_manager/lock_manager.go b/pkg/deploy/lock_manager/lock_manager.go index 589d6a2ac6..b84d6dbe38 100644 --- a/pkg/deploy/lock_manager/lock_manager.go +++ b/pkg/deploy/lock_manager/lock_manager.go @@ -20,12 +20,33 @@ type LockManager struct { LockerWithRetry *locker_with_retry.LockerWithRetry } -func NewLockManager(namespace string) (*LockManager, error) { - configMapName := "werf-synchronization" +type ConfigMapLocker struct { + ConfigMapName, Namespace string + + Locker lockgate.Locker +} + +func NewConfigMapLocker(configMapName, namespace string, locker lockgate.Locker) *ConfigMapLocker { + return &ConfigMapLocker{ + ConfigMapName: configMapName, + Namespace: namespace, + Locker: locker, + } +} - if _, err := kubeutils.GetOrCreateConfigMapWithNamespaceIfNotExists(kube.Client, namespace, configMapName); err != nil { - return nil, err +func (locker *ConfigMapLocker) Acquire(lockName string, opts lockgate.AcquireOptions) (bool, lockgate.LockHandle, error) { + if _, err := kubeutils.GetOrCreateConfigMapWithNamespaceIfNotExists(kube.Client, locker.Namespace, locker.ConfigMapName); err != nil { + return false, lockgate.LockHandle{}, fmt.Errorf("unable to prepare kubernetes cm/%s in ns/%s: %w", locker.Namespace, locker.ConfigMapName, err) } + return locker.Locker.Acquire(lockName, opts) +} + +func (locker *ConfigMapLocker) Release(lock lockgate.LockHandle) error { + return locker.Locker.Release(lock) +} + +func NewLockManager(namespace string) (*LockManager, error) { + configMapName := "werf-synchronization" locker := distributed_locker.NewKubernetesLocker( kube.DynamicClient, schema.GroupVersionResource{ @@ -34,7 +55,8 @@ func NewLockManager(namespace string) (*LockManager, error) { Resource: "configmaps", }, configMapName, namespace, ) - lockerWithRetry := locker_with_retry.NewLockerWithRetry(context.Background(), locker, locker_with_retry.LockerWithRetryOptions{MaxAcquireAttempts: 10, MaxReleaseAttempts: 10}) + cmLocker := NewConfigMapLocker(configMapName, namespace, locker) + lockerWithRetry := locker_with_retry.NewLockerWithRetry(context.Background(), cmLocker, locker_with_retry.LockerWithRetryOptions{MaxAcquireAttempts: 10, MaxReleaseAttempts: 10}) return &LockManager{ Namespace: namespace,