183 lines
5.1 KiB
Go
183 lines
5.1 KiB
Go
package bootstrap
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
monov1alpha1 "undecided.project/monok8s/pkg/apis/monok8s/v1alpha1"
|
|
"undecided.project/monok8s/pkg/node"
|
|
"undecided.project/monok8s/pkg/system"
|
|
)
|
|
|
|
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: "configure_hostname",
|
|
Name: "Configure hostname",
|
|
Desc: "Set system hostname according to cluster configuration",
|
|
},
|
|
{
|
|
RegKey: "configure_mgmt_interface",
|
|
Name: "Configure management interface",
|
|
Desc: "Configure management network interface, IP address, and gateway",
|
|
},
|
|
{
|
|
RegKey: "configure_dns",
|
|
Name: "Configure DNS",
|
|
Desc: "Set system DNS resolver configuration for cluster and external access",
|
|
},
|
|
{
|
|
RegKey: "ensure_ip_forward",
|
|
Name: "Ensure IP forwarding",
|
|
Desc: "Enable kernel IP forwarding required for pod networking",
|
|
},
|
|
{
|
|
RegKey: "configure_default_cni",
|
|
Name: "Configure default CNI",
|
|
Desc: "Install or configure default container networking (CNI bridge, IPAM, etc.)",
|
|
},
|
|
{
|
|
RegKey: "start_crio",
|
|
Name: "Start CRI-O runtime",
|
|
Desc: "Start container runtime and verify it is ready for Kubernetes workloads",
|
|
},
|
|
{
|
|
RegKey: "validate_required_images",
|
|
Name: "Validate required images",
|
|
Desc: "Ensure all required Kubernetes images are present or available locally",
|
|
},
|
|
{
|
|
RegKey: "validate_network_requirements",
|
|
Name: "Validate network requirements",
|
|
Desc: "Ensure required kernel networking features (iptables/nftables, bridge, forwarding) are available",
|
|
},
|
|
{
|
|
RegKey: "detect_local_cluster_state",
|
|
Name: "Detect local cluster state",
|
|
Desc: "Inspect local node to determine existing Kubernetes membership and configuration",
|
|
},
|
|
{
|
|
RegKey: "classify_bootstrap_action",
|
|
Name: "Classify bootstrap action",
|
|
Desc: "Decide whether to init, join, upgrade, or reconcile based on local state and desired version",
|
|
},
|
|
{
|
|
RegKey: "wait_for_existing_cluster_if_needed",
|
|
Name: "Wait for existing cluster",
|
|
Desc: "Block until control plane is reachable when joining or reconciling an existing cluster",
|
|
},
|
|
{
|
|
RegKey: "generate_kubeadm_config",
|
|
Name: "Generate kubeadm config",
|
|
Desc: "Render kubeadm configuration for init, join, or upgrade operations",
|
|
},
|
|
{
|
|
RegKey: "apply_local_node_metadata_if_possible",
|
|
Name: "Apply node metadata",
|
|
Desc: "Apply labels/annotations to the local node if API server is reachable",
|
|
},
|
|
{
|
|
RegKey: "allow_single_node_scheduling",
|
|
Name: "Allow single-node scheduling",
|
|
Desc: "Remove control-plane taints to allow workloads on single-node clusters",
|
|
},
|
|
{
|
|
RegKey: "reconcile_control_plane",
|
|
Name: "Reconcile control plane",
|
|
Desc: "Ensure control plane components match desired state without full reinitialization",
|
|
},
|
|
{
|
|
RegKey: "check_upgrade_prereqs",
|
|
Name: "Check upgrade prerequisites",
|
|
Desc: "Validate cluster state and version compatibility before upgrade",
|
|
},
|
|
{
|
|
RegKey: "run_kubeadm_upgrade_apply",
|
|
Name: "Run kubeadm upgrade apply",
|
|
Desc: "Upgrade control plane components using kubeadm",
|
|
},
|
|
{
|
|
RegKey: "run_kubeadm_init",
|
|
Name: "Run kubeadm init",
|
|
Desc: "Initialize a new Kubernetes control plane using kubeadm",
|
|
},
|
|
{
|
|
RegKey: "run_kubeadm_join",
|
|
Name: "Run kubeadm join",
|
|
Desc: "Join node to existing cluster as worker or control-plane",
|
|
},
|
|
{
|
|
RegKey: "reconcile_node",
|
|
Name: "Reconcile node state",
|
|
Desc: "Ensure node configuration matches desired state after join or upgrade",
|
|
},
|
|
{
|
|
RegKey: "run_kubeadm_upgrade_node",
|
|
Name: "Run kubeadm upgrade node",
|
|
Desc: "Upgrade node components (kubelet, config) to match control plane",
|
|
},
|
|
{
|
|
RegKey: "print_summary",
|
|
Name: "Print summary",
|
|
Desc: "Output final bootstrap summary and detected state",
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
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
|
|
}
|