From 9515db7faf2bbcfdb0456ec69939ee833c51cf18 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Sat, 3 Feb 2024 00:35:57 +0700 Subject: [PATCH] cmd/cli: ensure ctrld was uninstalled before installing In some old Windows systems, s.Uninstall does not remove the service completely at the time s.Install was running, prevent ctrld from being installed again. Workaround this by attempting to uninstall ctrld several times, re-check for service status after each attempt to ensure it was uninstalled. --- cmd/cli/cli.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/cmd/cli/cli.go b/cmd/cli/cli.go index dd1af17..d5ca749 100644 --- a/cmd/cli/cli.go +++ b/cmd/cli/cli.go @@ -266,7 +266,7 @@ func initCLI() { tasks := []task{ {s.Stop, false}, {func() error { return doGenerateNextDNSConfig(nextdns) }, true}, - {s.Uninstall, false}, + {func() error { return ensureUninstall(s) }, false}, {s.Install, false}, {s.Start, true}, // Note that startCmd do not actually write ControlD config, but the config file was @@ -2102,3 +2102,17 @@ func checkDeactivationPin(s service.Service) error { mainLog.Load().Error().Msg("deactivation pin is invalid") return errInvalidDeactivationPin } + +// ensureUninstall ensures that s.Uninstall will remove ctrld service from system completely. +func ensureUninstall(s service.Service) error { + maxAttempts := 10 + var err error + for i := 0; i < maxAttempts; i++ { + err = s.Uninstall() + if _, err := s.Status(); errors.Is(err, service.ErrNotInstalled) { + return nil + } + time.Sleep(time.Second) + } + return errors.Join(err, errors.New("uninstall failed")) +}