diff --git a/pkg/setup/setup.go b/pkg/setup/setup.go index 4b85d65337994044b98d02b9b0840f613d8aa575..96a6cc1086e9fa7b5bb07aee69f6eb2b84325304 100644 --- a/pkg/setup/setup.go +++ b/pkg/setup/setup.go @@ -2,7 +2,6 @@ package setup import ( "context" - "time" "git.perx.ru/perxis/perxis-go/pkg/clients" "git.perx.ru/perxis/perxis-go/pkg/collections" @@ -34,9 +33,9 @@ type Setup struct { force bool remove bool - waitForSpace bool - attempts uint - delay time.Duration + waitForSpaceReady bool + //attempts uint + //delay time.Duration errors []error logger *zap.Logger @@ -77,32 +76,14 @@ func (s *Setup) IsRemove() bool { return s.remove } -func (s *Setup) WithWaitForSpace(wait bool) *Setup { +func (s *Setup) WithWaitForSpaceReady() *Setup { setup := *s - setup.waitForSpace = wait - if setup.attempts == 0 { - setup.attempts = 60000 - } - if setup.delay.Milliseconds() == 0 { - setup.delay = 100 * time.Millisecond - } + setup.waitForSpaceReady = true return &setup } -func (s *Setup) WaitForSpace() bool { - return s.waitForSpace -} - -func (s *Setup) SetAttempts(attempts uint) *Setup { - setup := *s - setup.attempts = attempts - return &setup -} - -func (s *Setup) SetDelay(delay time.Duration) *Setup { - setup := *s - setup.delay = delay - return &setup +func (s *Setup) IsWaitForSpace() bool { + return s.waitForSpaceReady } func (s *Setup) HasErrors() bool { @@ -180,74 +161,67 @@ func (s *Setup) AddItem(item *items.Item, opt ...ItemsOption) *Setup { // Install выполняет установку необходимых требований func (s *Setup) Install(ctx context.Context) error { - var err error - if s.waitForSpace { - err = spaces.CheckIsSpaceAvailableWithRetry(ctx, s.content.Spaces, s.SpaceID, s.delay, s.attempts, s.logger) - } - if err == nil { - if err := s.InstallRoles(ctx); err != nil { - return err - } - if err := s.InstallClients(ctx); err != nil { - return err - } - if err := s.InstallCollections(ctx); err != nil { - return err - } - if err := s.InstallItems(ctx); err != nil { + if s.waitForSpaceReady { + if err := spaces.WaitSpaceAvailable(ctx, s.content.Spaces, s.SpaceID, s.logger); err != nil { return err } } - return err + if err := s.InstallRoles(ctx); err != nil { + return err + } + if err := s.InstallClients(ctx); err != nil { + return err + } + if err := s.InstallCollections(ctx); err != nil { + return err + } + if err := s.InstallItems(ctx); err != nil { + return err + } + return nil } // Check выполняет проверку требований func (s *Setup) Check(ctx context.Context) error { - var err error - if s.waitForSpace { - err = spaces.CheckIsReadAvailableWithRetry(ctx, s.content.Spaces, s.SpaceID, s.delay, s.attempts, s.logger) - } - if err == nil { - if err := s.CheckRoles(ctx); err != nil { + if s.waitForSpaceReady { + if err := spaces.WaitReadAvailable(ctx, s.content.Spaces, s.SpaceID, s.logger); err != nil { return err } - if err := s.CheckClients(ctx); err != nil { - return err - } - if err := s.CheckCollections(ctx); err != nil { - return err - } - if err := s.CheckItems(ctx); err != nil { - return err - } - return nil } - return err - + if err := s.CheckRoles(ctx); err != nil { + return err + } + if err := s.CheckClients(ctx); err != nil { + return err + } + if err := s.CheckCollections(ctx); err != nil { + return err + } + if err := s.CheckItems(ctx); err != nil { + return err + } + return nil } // Uninstall выполняет удаление установленных раннее требований func (s *Setup) Uninstall(ctx context.Context) error { - var err error - if s.waitForSpace { - err = spaces.CheckIsSpaceAvailableWithRetry(ctx, s.content.Spaces, s.SpaceID, s.delay, s.attempts, s.logger) - } - if err == nil { - // В случае если необходимо удалить данные удаляем все что создано при установке расширения - if err := s.UninstallClients(ctx); err != nil { - return err - } - if err := s.UninstallRoles(ctx); err != nil { + if s.waitForSpaceReady { + if err := spaces.WaitSpaceAvailable(ctx, s.content.Spaces, s.SpaceID, s.logger); err != nil { return err } - if err := s.UninstallCollections(ctx); err != nil { - return err - } - if err := s.UninstallItems(ctx); err != nil { - return err - } - s.logger.Info("Uninstall finished", zap.String(s.SpaceID, "spaceID")) - return nil } - return err + // В случае если необходимо удалить данные удаляем все что создано при установке расширения + if err := s.UninstallClients(ctx); err != nil { + return err + } + if err := s.UninstallRoles(ctx); err != nil { + return err + } + if err := s.UninstallCollections(ctx); err != nil { + return err + } + if err := s.UninstallItems(ctx); err != nil { + return err + } + return nil } diff --git a/pkg/setup/setup_test.go b/pkg/setup/setup_test.go index 10313d0bf79f2955b97e2c183501993812d12f4b..7e7483f4f5d88a46ee5bd8676123b5fb9f88d43c 100644 --- a/pkg/setup/setup_test.go +++ b/pkg/setup/setup_test.go @@ -672,7 +672,7 @@ func TestSetupInstall(t *testing.T) { sp.On("Get", mock.Anything, mock.Anything).Return(sps, nil).Once() setup := NewSetup(&content.Content{Spaces: sp}, spaceID, envID, logger) - err := setup.WithWaitForSpace(true).Install(context.Background()) + err := setup.WithWaitForSpaceReady().Install(context.Background()) require.NoError(t, err) @@ -685,7 +685,7 @@ func TestSetupInstall(t *testing.T) { sp.On("Get", mock.Anything, mock.Anything).Return(&spaces.Space{ID: spaceID, OrgID: "org", State: spaces.StateMigration}, nil).Twice() sp.On("Get", mock.Anything, mock.Anything).Return(nil, errors.New("some error")).Once() setup := NewSetup(&content.Content{Spaces: sp}, spaceID, envID, logger) - err := setup.WithWaitForSpace(true).Install(context.Background()) + err := setup.WithWaitForSpaceReady().Install(context.Background()) require.Error(t, err, "в момент выполнения пришла ошибка отличная от 'space not available'") @@ -1056,7 +1056,7 @@ func TestSetupUninstall(t *testing.T) { setup := NewSetup(&content.Content{Spaces: sp}, spaceID, envID, logger) - err := setup.WithWaitForSpace(true).Uninstall(context.Background()) + err := setup.WithWaitForSpaceReady().Uninstall(context.Background()) require.NoError(t, err) @@ -1072,7 +1072,7 @@ func TestSetupUninstall(t *testing.T) { setup := NewSetup(&content.Content{Spaces: sp}, spaceID, envID, logger) - err := setup.WithWaitForSpace(true).Uninstall(context.Background()) + err := setup.WithWaitForSpaceReady().Uninstall(context.Background()) require.Error(t, err, "в момент выполнения пришла ошибка отличная от 'space not available'") }) @@ -1280,7 +1280,7 @@ func TestSetupCheck(t *testing.T) { setup := NewSetup(&content.Content{Spaces: sp}, spaceID, envID, logger) - err := setup.WithWaitForSpace(true).Check(context.Background()) + err := setup.WithWaitForSpaceReady().Check(context.Background()) require.NoError(t, err) @@ -1296,7 +1296,7 @@ func TestSetupCheck(t *testing.T) { setup := NewSetup(&content.Content{Spaces: sp}, spaceID, envID, logger) - err := setup.WithWaitForSpace(true).Check(context.Background()) + err := setup.WithWaitForSpaceReady().Check(context.Background()) require.Error(t, err, "в момент выполнения пришла ошибка отличная от 'Space is migrating'") }) diff --git a/pkg/spaces/service.go b/pkg/spaces/service.go index 2483633ffe4bf87a7cd182e3b4159c1d06c7495b..a4341d2b4313e5f8ebd019f95988b9e47f78c8ee 100644 --- a/pkg/spaces/service.go +++ b/pkg/spaces/service.go @@ -2,11 +2,11 @@ package spaces import ( "context" - "strings" "time" + "git.perx.ru/perxis/perxis-go/pkg/errors" "github.com/avast/retry-go/v4" - "github.com/pkg/errors" + "go.uber.org/zap" ) @@ -54,6 +54,10 @@ type Spaces interface { Move(ctx context.Context, spaceID, orgID string) (err error) } +var ( + ErrSpaceNotAvailable = errors.New("space not available") +) + func IsSpaceAvailable(ctx context.Context, svc Spaces, spaceID string) error { sp, err := svc.Get(ctx, spaceID) if err != nil { @@ -62,7 +66,7 @@ func IsSpaceAvailable(ctx context.Context, svc Spaces, spaceID string) error { if sp.State == StateReady || sp.State == StateNew { return nil } - return errors.New("space not available") + return ErrSpaceNotAvailable } func IsReadAvailable(ctx context.Context, svc Spaces, spaceID string) error { @@ -73,35 +77,35 @@ func IsReadAvailable(ctx context.Context, svc Spaces, spaceID string) error { if sp.State == StateReady || sp.State == StateNew || sp.State == StateMigration { return nil } - return errors.Errorf("space '%s' is migrating, fail to do operation", sp.ID) + return errors.WithContext(ErrSpaceNotAvailable, "state", sp.State) } -func CheckIsSpaceAvailableWithRetry(ctx context.Context, svc Spaces, spaceID string, delay time.Duration, attempts uint, logger *zap.Logger) error { +func WaitSpaceAvailable(ctx context.Context, svc Spaces, spaceID string, logger *zap.Logger) error { return retry.Do( func() error { return IsSpaceAvailable(ctx, svc, spaceID) }, - retry.RetryIf(func(err error) bool { return strings.Contains(err.Error(), "space not available") }), + retry.RetryIf(func(err error) bool { return errors.Is(err, ErrSpaceNotAvailable) }), retry.OnRetry(func(n uint, err error) { logger.Warn("Space not available", zap.String("spaceID", spaceID), zap.Uint("Retry", n), zap.Error(err)) }), - retry.Delay(delay), - retry.Attempts(attempts), + retry.Delay(500*time.Millisecond), + retry.Attempts(1800), // 900s == 900 000 retry.Context(ctx), ) } -func CheckIsReadAvailableWithRetry(ctx context.Context, svc Spaces, spaceID string, delay time.Duration, attempts uint, logger *zap.Logger) error { +func WaitReadAvailable(ctx context.Context, svc Spaces, spaceID string, logger *zap.Logger) error { return retry.Do( func() error { return IsReadAvailable(ctx, svc, spaceID) }, - retry.RetryIf(func(err error) bool { return strings.Contains(err.Error(), "is migrating") }), + retry.RetryIf(func(err error) bool { return errors.Is(err, ErrSpaceNotAvailable) }), retry.OnRetry(func(n uint, err error) { logger.Warn("Space is migrating", zap.String("spaceID", spaceID), zap.Uint("Retry", n), zap.Error(err)) }), - retry.Delay(delay), - retry.Attempts(attempts), + retry.Delay(500*time.Millisecond), + retry.Attempts(1800), retry.Context(ctx), ) }