penguin/monok8s

k8s image for Mono Gateway Dev Kit

clitools/pkg/bootstrap/runner.go

raw ยท 5859 bytes

package bootstrap

import (
	"context"
	"fmt"

	monov1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1"
	"example.com/monok8s/pkg/node"
	"example.com/monok8s/pkg/system"
	"k8s.io/klog/v2"
)

type Runner struct {
	NodeCtx  *node.NodeContext
	Registry *Registry

	initSteps []StepInfo
}

type StepInfo struct {
	RegKey string
	Name   string
	Desc   string
}

type StepSelection struct {
	Indices []int // 1-based
}

func NewRunner(cfg *monov1alpha1.MonoKSConfig) *Runner {
	runnerCfg := system.RunnerConfig{}
	nctx := &node.NodeContext{
		Config:       cfg,
		SystemRunner: system.NewRunner(runnerCfg),
	}
	return &Runner{
		NodeCtx:  nctx,
		Registry: NewRegistry(nctx),
		initSteps: []StepInfo{
			{
				RegKey: "ConfigureHostname",
				Name:   "Configure hostname",
				Desc:   "Set system hostname according to cluster configuration",
			},
			{
				RegKey: "ConfigureMgmtInterface",
				Name:   "Configure management interface",
				Desc:   "Configure management network interface, IP address, and gateway",
			},
			{
				RegKey: "ConfigureDNS",
				Name:   "Configure DNS",
				Desc:   "Set system DNS resolver configuration for cluster and external access",
			},
			{
				RegKey: "EnsureIPForward",
				Name:   "Ensure IP forwarding",
				Desc:   "Enable kernel IP forwarding required for pod networking",
			},
			{
				RegKey: "ConfigureDefaultCNI",
				Name:   "Configure default CNI",
				Desc:   "Install or configure default container networking (CNI bridge, IPAM, etc.)",
			},
			{
				RegKey: "MountAltImageStore",
				Name:   "Mount alt image store for CRI-O. Needed for upgrade.",
				Desc:   "Will be unmount after kubeadm upgrade apply",
			},
			{
				RegKey: "EngageControlGate",
				Name:   "Engage the control gate",
				Desc:   "Prevents agent watching resources prematurely",
			},
			{
				RegKey: "StartCRIO",
				Name:   "Start CRI-O runtime",
				Desc:   "Start container runtime and verify it is ready for Kubernetes workloads",
			},
			{
				RegKey: "ValidateRequiredImagesPresent",
				Name:   "Validate required images",
				Desc:   "Ensure all required Kubernetes images are present or available locally",
			},
			{
				RegKey: "ValidateNodeIPAndAPIServerReachability",
				Name:   "Validate Node IP and wether API Server is available",
				Desc:   "Verify the local ip address with the api server advertise address. Contact remote api server",
			},
			{
				RegKey: "DetectLocalClusterState",
				Name:   "Detect local cluster state",
				Desc:   "Inspect local node to determine existing Kubernetes membership and configuration",
			},
			{
				RegKey: "ClassifyBootstrapAction",
				Name:   "Classify bootstrap action",
				Desc:   "Decide whether to init, join, upgrade, or reconcile based on local state and desired version",
			},
			{
				RegKey: "RunKubeadmInit",
				Name:   "Run kubeadm init",
				Desc:   "Initialize a new Kubernetes control plane using kubeadm",
			},
			{
				RegKey: "RunKubeadmJoin",
				Name:   "Run kubeadm join",
				Desc:   "Join node to existing cluster as worker or control-plane",
			},
			{
				RegKey: "WaitForExistingClusterIfNeeded",
				Name:   "Wait for existing cluster",
				Desc:   "Block until control plane is reachable when joining or reconciling an existing cluster",
			},
			{
				RegKey: "CheckForVersionSkew",
				Name:   "Check for version skew",
				Desc:   "Validate wether version satisfy the requirements againts current cluster if any",
			},
			{
				RegKey: "ReconcileControlPlane",
				Name:   "Reconcile control plane",
				Desc:   "Ensure control plane components match desired state without full reinitialization",
			},
			{
				RegKey: "ReconcileWorker",
				Name:   "Reconcile worker node",
				Desc:   "Reconcile the worker node",
			},
			{
				RegKey: "RunKubeadmUpgradeApply",
				Name:   "Run kubeadm upgrade apply",
				Desc:   "Upgrade control plane components using kubeadm",
			},
			{
				RegKey: "RunKubeadmUpgradeNode",
				Name:   "Run kubeadm upgrade node",
				Desc:   "Upgrade node components (kubelet, config) to match control plane",
			},
			{
				RegKey: "UnmountAltImageStore",
				Name:   "Unmount alt image store",
				Desc:   "Rewrite CRIO storage.conf. Then restart CRIO. Then unmount.",
			},
			{
				RegKey: "ApplyLocalNodeMetadataIfPossible",
				Name:   "Apply node metadata",
				Desc:   "Apply labels/annotations to the local node if API server is reachable",
			},
			{
				RegKey: "ConfigureUBootCommands",
				Name:   "Ensure fw_env config and u-boot-tools availablilty",
				Desc:   "Install or generate /etc/fw_env.config for U-Boot environment access",
			},
			{
				RegKey: "ConfigureABBoot",
				Name:   "Configure A/B booting environment",
				Desc:   "Make A/B booting possible",
			},
			{
				RegKey: "ApplyNodeControlDaemonSetResources",
				Name:   "Apply daemonset for control agent",
				Desc:   "Control agent handles OSUpgrade resources",
			},
			{
				RegKey: "ReleaseControlGate",
				Name:   "Release the control gate",
				Desc:   "Allow agent to start watching resources",
			},
		},
	}
}

func (r *Runner) RunNamedStep(ctx context.Context, name string) error {
	step, err := r.Registry.Get(name)
	if err != nil {
		return err
	}
	return step(ctx, r.NodeCtx)
}

func (r *Runner) InitSteps() []StepInfo {
	return r.initSteps
}

func (r *Runner) Init(ctx context.Context) error {
	for i, step := range r.initSteps {
		if err := r.RunNamedStep(ctx, step.RegKey); err != nil {
			return fmt.Errorf("step %d (%s): %w", i+1, step.Name, err)
		}
	}
	klog.Info("All steps completed successfully")
	return nil
}

func (r *Runner) InitSelected(ctx context.Context, sel StepSelection) error {
	for _, idx := range sel.Indices {
		step := r.initSteps[idx-1]
		if err := r.RunNamedStep(ctx, step.RegKey); err != nil {
			return fmt.Errorf("step %d (%s): %w", idx, step.Name, err)
		}
	}
	return nil
}