Can now reconcile

This commit is contained in:
2026-03-30 18:41:18 +08:00
parent 0aa4065c26
commit 68e7dcd001
7 changed files with 245 additions and 141 deletions

View File

@@ -114,89 +114,6 @@ func WaitForExistingClusterIfNeeded(ctx context.Context, nctx *NodeContext) erro
}
}
func CheckForVersionSkew(ctx context.Context, nctx *NodeContext) error {
if nctx.BootstrapState == nil {
return errors.New("BootstrapState is nil, call ClassifyBootstrapAction() first")
}
role := strings.TrimSpace(nctx.Config.Spec.ClusterRole)
wantVersion := normalizeKubeVersion(strings.TrimSpace(nctx.Config.Spec.KubernetesVersion))
if wantVersion == "" {
return errors.New("spec.kubernetesVersion is required")
}
switch nctx.LocalClusterState.MembershipKind {
case LocalMembershipFresh:
// Nothing to compare for fresh nodes.
return nil
case LocalMembershipPartial:
return fmt.Errorf("cannot check version skew with partial local cluster state")
}
versionKubeconfig := chooseVersionKubeconfig(nctx.LocalClusterState)
if versionKubeconfig == "" {
return fmt.Errorf("no kubeconfig available for version detection")
}
currentVersion, err := getServerVersion(ctx, versionKubeconfig)
if err != nil {
if role == "control-plane" {
return fmt.Errorf("existing control-plane state found, but cluster version could not be determined: %w", err)
}
// Worker path stays permissive.
nctx.BootstrapState.UnsupportedWorkerVersionSkew = true
nctx.BootstrapState.VersionSkewReason = "cluster version could not be determined"
if nctx.BootstrapState.Action == BootstrapActionManageWorker {
nctx.BootstrapState.Action = BootstrapActionReconcileWorker
}
return nil
}
nctx.BootstrapState.DetectedClusterVersion = currentVersion
switch role {
case "control-plane":
if !isSupportedControlPlaneSkew(currentVersion, wantVersion) {
return fmt.Errorf(
"unsupported control-plane version skew: cluster=%s node=%s",
currentVersion, wantVersion,
)
}
if nctx.BootstrapState.Action == BootstrapActionManageControlPlane {
if versionEq(currentVersion, wantVersion) {
nctx.BootstrapState.Action = BootstrapActionReconcileControlPlane
} else {
nctx.BootstrapState.Action = BootstrapActionUpgradeControlPlane
}
}
case "worker":
if !isSupportedWorkerSkew(currentVersion, wantVersion) {
nctx.BootstrapState.UnsupportedWorkerVersionSkew = true
nctx.BootstrapState.VersionSkewReason = fmt.Sprintf(
"unsupported worker version skew: cluster=%s node=%s",
currentVersion, wantVersion,
)
}
if nctx.BootstrapState.Action == BootstrapActionManageWorker {
if versionEq(currentVersion, wantVersion) {
nctx.BootstrapState.Action = BootstrapActionReconcileWorker
} else {
nctx.BootstrapState.Action = BootstrapActionUpgradeWorker
}
}
default:
return fmt.Errorf("unsupported cluster role %q", role)
}
return nil
}
func ClassifyBootstrapAction(ctx context.Context, nctx *NodeContext) error {
_ = ctx
@@ -863,3 +780,41 @@ func RunKubeadmUpgradeNode(context.Context, *NodeContext) error {
klog.Info("run_kubeadm_upgrade_node: TODO implement kubeadm upgrade node")
return nil
}
func ReconcileControlPlane(ctx context.Context, nctx *NodeContext) error {
if nctx.BootstrapState == nil {
return errors.New("BootstrapState is nil, call ClassifyBootstrapAction() first")
}
if nctx.BootstrapState.Action != BootstrapActionReconcileControlPlane {
klog.V(4).Infof("ReconcileControlPlane skipped for action %q", nctx.BootstrapState.Action)
return nil
}
if err := StartKubelet(ctx, nctx); err != nil {
return fmt.Errorf("start kubelet: %w", err)
}
if err := waitForLocalAPIServer(ctx, nctx, 2*time.Minute); err != nil {
return fmt.Errorf("wait for local apiserver: %w", err)
}
if err := waitForAPIViaKubeconfig(ctx, adminKubeconfigPath, 2*time.Minute); err != nil {
return fmt.Errorf("wait for admin api: %w", err)
}
return nil
}
func ReconcileWorker(ctx context.Context, nctx *NodeContext) error {
if nctx.BootstrapState == nil {
return errors.New("BootstrapState is nil, call ClassifyBootstrapAction() first")
}
if nctx.BootstrapState.Action != BootstrapActionReconcileWorker {
klog.V(4).Infof("ReconcileWorker skipped for action %q", nctx.BootstrapState.Action)
return nil
}
if err := StartKubelet(ctx, nctx); err != nil {
return fmt.Errorf("start kubelet: %w", err)
}
if err := waitForKubeletHealthy(ctx, 2*time.Minute); err != nil {
return fmt.Errorf("wait for kubelet healthy: %w", err)
}
return nil
}