package node import ( "context" "fmt" "io" "net/http" "strings" "time" "k8s.io/klog/v2" system "example.com/monok8s/pkg/system" ) const ( crdsPath = "/usr/lib/monok8s/crds/" ) func StartKubelet(ctx context.Context, n *NodeContext) error { return system.EnsureServiceRunning(ctx, n.SystemRunner, "kubelet") } func waitForKubeletHealthy(ctx context.Context, timeout time.Duration) error { ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() url := "http://127.0.0.1:10248/healthz" client := &http.Client{ Timeout: 2 * time.Second, } ticker := time.NewTicker(2 * time.Second) defer ticker.Stop() for { req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err == nil { resp, err := client.Do(req) if err == nil { body, _ := io.ReadAll(resp.Body) resp.Body.Close() if resp.StatusCode == http.StatusOK && strings.TrimSpace(string(body)) == "ok" { return nil } } } select { case <-ctx.Done(): return fmt.Errorf("kubelet health endpoint did not become ready: %w", ctx.Err()) case <-ticker.C: } } } func ApplyCRDs(ctx context.Context, nctx *NodeContext) error { if nctx.Config.Spec.ClusterRole != "control-plane" { return nil } _, err := nctx.SystemRunner.RunWithOptions( ctx, "kubectl", []string{"apply", "-f", crdsPath}, system.RunOptions{ Timeout: 10 * time.Minute, OnStdoutLine: func(line string) { klog.Infof("[kubectl] %s", line) }, OnStderrLine: func(line string) { klog.Infof("[kubectl] %s", line) }, }, ) return err }