Repository: k3s-io/k3s
File: pkg/agent/run.go (Go)

Code before:
		return agent.Agent(ctx, nodeConfig, proxy)
	}
	return nil
}

func waitForAPIServerAddresses(ctx context.Context, nodeConfig *daemonconfig.Node, cfg cmds.Agent, proxy proxy.Proxy) error {
	var localSupervisorDefault bool
	if addresses := proxy.SupervisorAddresses(); len(addresses) > 0 {
		host, _, _ := net.SplitHostPort(addresses[0])
		if host == "127.0.0.1" || host == "::1" {
			localSupervisorDefault = true
		}
	}

	for {
		select {
		case <-time.After(5 * time.Second):
			logrus.Info("Waiting for apiserver addresses")
		case addresses := <-cfg.APIAddressCh:
			for i, a := range addresses {
				host, _, err := net.SplitHostPort(a)
				if err == nil {
					addresses[i] = net.JoinHostPort(host, strconv.Itoa(nodeConfig.ServerHTTPSPort))
				}
			}
			// If this is an etcd-only node that started up using its local supervisor,
			// switch to using a control-plane node as the supervisor. Otherwise, leave the
			// configured server address as the default.
			if localSupervisorDefault && len(addresses) > 0 {
				proxy.SetSupervisorDefault(addresses[0])
			}
			proxy.Update(addresses)
			return nil
		case <-ctx.Done():
			return ctx.Err()
		}
	}
}

// tunnelSetup calls tunnel setup, unless the embedded etc cluster is being reset/restored, in which case
// this is unnecessary as the kubelet is only needed to manage static pods and does not need to establish
// tunneled connections to other cluster members.
func tunnelSetup(ctx context.Context, nodeConfig *daemonconfig.Node, cfg cmds.Agent, proxy proxy.Proxy) error {
	if cfg.ClusterReset {
		return nil
	}
	return tunnel.Setup(ctx, nodeConfig, proxy)
}

func certMonitorSetup(ctx context.Context, nodeConfig *daemonconfig.Node, cfg cmds.Agent) error {
	if cfg.ClusterReset {

Review comment (suggestion):
ugh, this breaks agents that join against an etcd-only node. They need to switch over to a control-plane node instead, and we were relying on removal of the etcd-only node as default triggering its removal from the loadbalancer server list to make the agent switch over to the apiserver node. I will have to think about this more.

Code after:
		return agent.Agent(ctx, nodeConfig, proxy)
	}
	return nil
}

func waitForAPIServerAddresses(ctx context.Context, nodeConfig *daemonconfig.Node, cfg cmds.Agent, proxy proxy.Proxy) error {
	var localSupervisorDefault bool
	if addresses := proxy.SupervisorAddresses(); len(addresses) > 0 {
		host, _, _ := net.SplitHostPort(addresses[0])
		if host == "127.0.0.1" || host == "::1" {
			localSupervisorDefault = true
		}
	}

	for {
		select {
		case <-time.After(5 * time.Second):
			logrus.Info("Waiting for control-plane node to register apiserver addresses in etcd")
		case addresses := <-cfg.APIAddressCh:
			for i, a := range addresses {
				host, _, err := net.SplitHostPort(a)
				if err == nil {
					addresses[i] = net.JoinHostPort(host, strconv.Itoa(nodeConfig.ServerHTTPSPort))
				}
			}
			// If this is an etcd-only node that started up using its local supervisor,
			// switch to using a control-plane node as the supervisor. Otherwise, leave the
			// configured server address as the default.
			if localSupervisorDefault && len(addresses) > 0 {
				proxy.SetSupervisorDefault(addresses[0])
			}
			proxy.Update(addresses)
			return nil
		case <-ctx.Done():
			return ctx.Err()
		}
	}
}

// tunnelSetup calls tunnel setup, unless the embedded etc cluster is being reset/restored, in which case
// this is unnecessary as the kubelet is only needed to manage static pods and does not need to establish
// tunneled connections to other cluster members.
func tunnelSetup(ctx context.Context, nodeConfig *daemonconfig.Node, cfg cmds.Agent, proxy proxy.Proxy) error {
	if cfg.ClusterReset {
		return nil
	}
	return tunnel.Setup(ctx, nodeConfig, proxy)
}

func certMonitorSetup(ctx context.Context, nodeConfig *daemonconfig.Node, cfg cmds.Agent) error {
	if cfg.ClusterReset {