package installer import ( "context" "fmt" "os" "path/filepath" "github.com/samber/lo" "yizhisec.com/hsv2/forge/pkg/logger" ) type K0sOpt func(*k0sOpt) type k0sOpt struct { Type string // controller, worker controllerAsWorker bool WorkerTokenFile string } func WithK0sType(t string) K0sOpt { types := []string{"controller", "worker"} return func(o *k0sOpt) { if lo.Contains(types, t) { o.Type = t } } } func WithK0sControllerAsWorker() K0sOpt { return func(o *k0sOpt) { o.controllerAsWorker = true } } func WithK0sWorkerTokenFile(filename string) K0sOpt { return func(o *k0sOpt) { if filename != "" { o.WorkerTokenFile = filename } } } func (i *installer) K0s(ctx context.Context, opts ...K0sOpt) error { var ( err error o = &k0sOpt{ Type: "controller", controllerAsWorker: false, WorkerTokenFile: "/etc/k0s/worker.token", } ) if err = i.targetOK(ctx); err != nil { return err } for _, fn := range opts { fn(o) } binaries := []string{ "dependency/bin/k0s", "dependency/bin/k9s", "dependency/bin/kubectl", "dependency/bin/helm"} if err = i.checkFiles(binaries...); err != nil { return err } // check image tar files: images := []string{ "dependency/image/k0s.apiserver-network-proxy-agent.tar", "dependency/image/k0s.cni-node.tar", "dependency/image/k0s.coredns.tar", "dependency/image/k0s.kube-proxy.tar", "dependency/image/k0s.kube-router.tar", "dependency/image/k0s.metrics-server.tar", "dependency/image/k0s.pause.tar", } if err = i.checkFiles(images...); err != nil { return err } // copy binaries to /usr/local/bin and add executable permissions if err = i.copyFile(ctx, "dependency/bin/k0s", "/usr/local/bin/k0s", withCopyFileExecutable()); err != nil { return err } if err = i.copyFile(ctx, "dependency/bin/k9s", "/usr/local/bin/k9s", withCopyFileExecutable()); err != nil { return err } if err = i.copyFile(ctx, "dependency/bin/kubectl", "/usr/local/bin/kubectl", withCopyFileExecutable()); err != nil { return err } if err = i.copyFile(ctx, "dependency/bin/helm", "/usr/local/bin/helm", withCopyFileExecutable()); err != nil { return err } i.ExecuteCommand(ctx, "k0s", "") return nil } // checkBinaryFiles checks if the required binary files exist in the dependency/bin directory func (i *installer) checkFiles(fileBaseName ...string) error { logger.Info("☑️ installer.checkFiles: Checking files in %s...", i.workdir) for _, file := range fileBaseName { filename := filepath.Join(i.workdir, file) logger.Debug("Checking file: %s", filename) if _, err := os.Stat(filename); os.IsNotExist(err) { logger.Error("❌ File not found: %s", filename) return fmt.Errorf("file not found: %s", filename) } else if err != nil { logger.Error("❌ Failed to check file %s: %v", filename, err) return fmt.Errorf("failed to check file %s: %w", filename, err) } logger.Info("✅ File found: %s", file) } logger.Info("✅ installer.checkBinaryFiles: All binary files verified successfully!") return nil }