[client] Fix/stuck connecting when can't access api.netbird.io (#5033)

- Connect on daemon start only if the file existed before
- fixed a bug that happened when the default profile config was removed, which would recreate it and reset the active profile to the default.
This commit is contained in:
Maycon Santos
2026-01-05 15:53:17 +03:00
committed by GitHub
parent 08b782d6ba
commit 07856f516c
4 changed files with 29 additions and 62 deletions

View File

@@ -110,7 +110,6 @@ func wakeUpListen(ctx context.Context) {
} }
if newHash == initialHash { if newHash == initialHash {
log.Tracef("no wakeup detected")
continue continue
} }

View File

@@ -685,7 +685,7 @@ func update(input ConfigInput) (*Config, error) {
return config, nil return config, nil
} }
// GetConfig read config file and return with Config. Errors out if it does not exist // GetConfig read config file and return with Config and if it was created. Errors out if it does not exist
func GetConfig(configPath string) (*Config, error) { func GetConfig(configPath string) (*Config, error) {
return readConfig(configPath, false) return readConfig(configPath, false)
} }

View File

@@ -126,14 +126,6 @@ func (s *ServiceManager) CopyDefaultProfileIfNotExists() (bool, error) {
log.Warnf("failed to set permissions for default profile: %v", err) log.Warnf("failed to set permissions for default profile: %v", err)
} }
if err := s.SetActiveProfileState(&ActiveProfileState{
Name: "default",
Username: "",
}); err != nil {
log.Errorf("failed to set active profile state: %v", err)
return false, fmt.Errorf("failed to set active profile state: %w", err)
}
return true, nil return true, nil
} }

View File

@@ -145,10 +145,10 @@ func (s *Server) Start() error {
ctx, cancel := context.WithCancel(s.rootCtx) ctx, cancel := context.WithCancel(s.rootCtx)
s.actCancel = cancel s.actCancel = cancel
// set the default config if not exists // copy old default config
if err := s.setDefaultConfigIfNotExists(ctx); err != nil { _, err = s.profileManager.CopyDefaultProfileIfNotExists()
log.Errorf("failed to set default config: %v", err) if err != nil && !errors.Is(err, profilemanager.ErrorOldDefaultConfigNotFound) {
return fmt.Errorf("failed to set default config: %w", err) return err
} }
activeProf, err := s.profileManager.GetActiveProfileState() activeProf, err := s.profileManager.GetActiveProfileState()
@@ -156,23 +156,11 @@ func (s *Server) Start() error {
return fmt.Errorf("failed to get active profile state: %w", err) return fmt.Errorf("failed to get active profile state: %w", err)
} }
config, err := s.getConfig(activeProf) config, existingConfig, err := s.getConfig(activeProf)
if err != nil { if err != nil {
log.Errorf("failed to get active profile config: %v", err) log.Errorf("failed to get active profile config: %v", err)
if err := s.profileManager.SetActiveProfileState(&profilemanager.ActiveProfileState{ return err
Name: "default",
Username: "",
}); err != nil {
log.Errorf("failed to set active profile state: %v", err)
return fmt.Errorf("failed to set active profile state: %w", err)
}
config, err = profilemanager.GetConfig(s.profileManager.DefaultProfilePath())
if err != nil {
log.Errorf("failed to get default profile config: %v", err)
return fmt.Errorf("failed to get default profile config: %w", err)
}
} }
s.config = config s.config = config
@@ -186,6 +174,13 @@ func (s *Server) Start() error {
} }
if config.DisableAutoConnect { if config.DisableAutoConnect {
state.Set(internal.StatusIdle)
return nil
}
if !existingConfig {
log.Warnf("not trying to connect when configuration was just created")
state.Set(internal.StatusNeedsLogin)
return nil return nil
} }
@@ -196,30 +191,6 @@ func (s *Server) Start() error {
return nil return nil
} }
func (s *Server) setDefaultConfigIfNotExists(ctx context.Context) error {
ok, err := s.profileManager.CopyDefaultProfileIfNotExists()
if err != nil {
if err := s.profileManager.CreateDefaultProfile(); err != nil {
log.Errorf("failed to create default profile: %v", err)
return fmt.Errorf("failed to create default profile: %w", err)
}
if err := s.profileManager.SetActiveProfileState(&profilemanager.ActiveProfileState{
Name: "default",
Username: "",
}); err != nil {
log.Errorf("failed to set active profile state: %v", err)
return fmt.Errorf("failed to set active profile state: %w", err)
}
}
if ok {
state := internal.CtxGetState(ctx)
state.Set(internal.StatusNeedsLogin)
}
return nil
}
// connectWithRetryRuns runs the client connection with a backoff strategy where we retry the operation as additional // connectWithRetryRuns runs the client connection with a backoff strategy where we retry the operation as additional
// mechanism to keep the client connected even when the connection is lost. // mechanism to keep the client connected even when the connection is lost.
// we cancel retry if the client receive a stop or down command, or if disable auto connect is configured. // we cancel retry if the client receive a stop or down command, or if disable auto connect is configured.
@@ -487,7 +458,7 @@ func (s *Server) Login(callerCtx context.Context, msg *proto.LoginRequest) (*pro
s.mutex.Unlock() s.mutex.Unlock()
config, err := s.getConfig(activeProf) config, _, err := s.getConfig(activeProf)
if err != nil { if err != nil {
log.Errorf("failed to get active profile config: %v", err) log.Errorf("failed to get active profile config: %v", err)
return nil, fmt.Errorf("failed to get active profile config: %w", err) return nil, fmt.Errorf("failed to get active profile config: %w", err)
@@ -716,7 +687,7 @@ func (s *Server) Up(callerCtx context.Context, msg *proto.UpRequest) (*proto.UpR
log.Infof("active profile: %s for %s", activeProf.Name, activeProf.Username) log.Infof("active profile: %s for %s", activeProf.Name, activeProf.Username)
config, err := s.getConfig(activeProf) config, _, err := s.getConfig(activeProf)
if err != nil { if err != nil {
log.Errorf("failed to get active profile config: %v", err) log.Errorf("failed to get active profile config: %v", err)
return nil, fmt.Errorf("failed to get active profile config: %w", err) return nil, fmt.Errorf("failed to get active profile config: %w", err)
@@ -811,7 +782,7 @@ func (s *Server) SwitchProfile(callerCtx context.Context, msg *proto.SwitchProfi
log.Errorf("failed to get active profile state: %v", err) log.Errorf("failed to get active profile state: %v", err)
return nil, fmt.Errorf("failed to get active profile state: %w", err) return nil, fmt.Errorf("failed to get active profile state: %w", err)
} }
config, err := s.getConfig(activeProf) config, _, err := s.getConfig(activeProf)
if err != nil { if err != nil {
log.Errorf("failed to get default profile config: %v", err) log.Errorf("failed to get default profile config: %v", err)
return nil, fmt.Errorf("failed to get default profile config: %w", err) return nil, fmt.Errorf("failed to get default profile config: %w", err)
@@ -908,7 +879,7 @@ func (s *Server) handleActiveProfileLogout(ctx context.Context) (*proto.LogoutRe
return nil, gstatus.Errorf(codes.FailedPrecondition, "failed to get active profile state: %v", err) return nil, gstatus.Errorf(codes.FailedPrecondition, "failed to get active profile state: %v", err)
} }
config, err := s.getConfig(activeProf) config, _, err := s.getConfig(activeProf)
if err != nil { if err != nil {
return nil, gstatus.Errorf(codes.FailedPrecondition, "not logged in") return nil, gstatus.Errorf(codes.FailedPrecondition, "not logged in")
} }
@@ -932,19 +903,24 @@ func (s *Server) handleActiveProfileLogout(ctx context.Context) (*proto.LogoutRe
return &proto.LogoutResponse{}, nil return &proto.LogoutResponse{}, nil
} }
// getConfig loads the config from the active profile // GetConfig reads config file and returns Config and whether the config file already existed. Errors out if it does not exist
func (s *Server) getConfig(activeProf *profilemanager.ActiveProfileState) (*profilemanager.Config, error) { func (s *Server) getConfig(activeProf *profilemanager.ActiveProfileState) (*profilemanager.Config, bool, error) {
cfgPath, err := activeProf.FilePath() cfgPath, err := activeProf.FilePath()
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get active profile file path: %w", err) return nil, false, fmt.Errorf("failed to get active profile file path: %w", err)
} }
config, err := profilemanager.GetConfig(cfgPath) _, err = os.Stat(cfgPath)
configExisted := !os.IsNotExist(err)
log.Infof("active profile config existed: %t, err %v", configExisted, err)
config, err := profilemanager.ReadConfig(cfgPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get config: %w", err) return nil, false, fmt.Errorf("failed to get config: %w", err)
} }
return config, nil return config, configExisted, nil
} }
func (s *Server) canRemoveProfile(profileName string) error { func (s *Server) canRemoveProfile(profileName string) error {