diff --git a/phase/validate_facts.go b/phase/validate_facts.go index 885c0fbb..b342b9fb 100644 --- a/phase/validate_facts.go +++ b/phase/validate_facts.go @@ -96,9 +96,17 @@ func (p *ValidateFacts) validateControllerSwap() error { } log.Debugf("%s: host is new, checking if etcd members list %+v already contains %s", h, p.Config.Metadata.EtcdMembers, h.PrivateAddress) if slices.Contains(p.Config.Metadata.EtcdMembers, h.PrivateAddress) { - return fmt.Errorf("controller %s is listed as an existing etcd member but k0s is not found installed on it, host may have been replaced", h) + if Force { + leader := p.Config.Spec.K0sLeader() + if err := leader.Exec(leader.Configurer.K0sCmdf("etcd leave --peer-address %s", h.PrivateAddress)); err != nil { + return fmt.Errorf("controller %s is listed as an existing etcd member but k0s is not found installed on it, the host may have been replaced. attempted etcd leave for the address %s but it failed: %w", h, h.PrivateAddress, err) + } + } else { + return fmt.Errorf("controller %s is listed as an existing etcd member but k0s is not found installed on it, the host may have been replaced. check the host and use `k0s etcd leave --peer-address %s on a controller or re-run apply with --force", h, h.PrivateAddress) + } + } else { + log.Debugf("%s: no match, assuming its safe to install", h) } - log.Debugf("%s: no match, assuming its safe to install", h) } return nil