package cloudinit import ( "fmt" "log/slog" "os" "path/filepath" "strings" ) // ApplyKubeSolo writes KubeSolo configuration files based on cloud-init config. // These files are read by init stage 90-kubesolo.sh when building the // KubeSolo command line. func ApplyKubeSolo(cfg *Config, configDir string) error { if err := os.MkdirAll(configDir, 0o755); err != nil { return fmt.Errorf("creating config dir %s: %w", configDir, err) } // Write extra flags file (consumed by 90-kubesolo.sh) flags := buildExtraFlags(cfg) if flags != "" { flagsPath := filepath.Join(configDir, "extra-flags") if err := os.WriteFile(flagsPath, []byte(flags+"\n"), 0o644); err != nil { return fmt.Errorf("writing extra-flags: %w", err) } slog.Info("wrote KubeSolo extra flags", "path", flagsPath, "flags", flags) } // Write config.yaml for KubeSolo if we have settings beyond defaults if err := writeKubeSoloConfig(cfg, configDir); err != nil { return err } return nil } func buildExtraFlags(cfg *Config) string { var parts []string if cfg.KubeSolo.ExtraFlags != "" { parts = append(parts, cfg.KubeSolo.ExtraFlags) } // Add extra SANs from cloud-init for _, san := range cfg.KubeSolo.ExtraSANs { parts = append(parts, "--apiserver-extra-sans", san) } if cfg.KubeSolo.LocalStorageSharedPath != "" { parts = append(parts, "--local-storage-shared-path", cfg.KubeSolo.LocalStorageSharedPath) } if cfg.KubeSolo.Debug { parts = append(parts, "--debug") } if cfg.KubeSolo.PprofServer { parts = append(parts, "--pprof-server") } if cfg.KubeSolo.PortainerEdgeID != "" { parts = append(parts, "--portainer-edge-id", cfg.KubeSolo.PortainerEdgeID) } if cfg.KubeSolo.PortainerEdgeKey != "" { parts = append(parts, "--portainer-edge-key", cfg.KubeSolo.PortainerEdgeKey) } if cfg.KubeSolo.PortainerEdgeAsync { parts = append(parts, "--portainer-edge-async") } return strings.Join(parts, " ") } func writeKubeSoloConfig(cfg *Config, configDir string) error { var lines []string lines = append(lines, "# Generated by KubeSolo OS cloud-init") lines = append(lines, "data-dir: /var/lib/kubesolo") if cfg.KubeSolo.LocalStorage != nil { if *cfg.KubeSolo.LocalStorage { lines = append(lines, "local-storage: true") } else { lines = append(lines, "local-storage: false") } } else { lines = append(lines, "local-storage: true") } lines = append(lines, "bind-address: 0.0.0.0") lines = append(lines, "cluster-cidr: 10.42.0.0/16") lines = append(lines, "service-cidr: 10.43.0.0/16") dest := filepath.Join(configDir, "config.yaml") content := strings.Join(lines, "\n") + "\n" if err := os.WriteFile(dest, []byte(content), 0o644); err != nil { return fmt.Errorf("writing config.yaml: %w", err) } slog.Info("wrote KubeSolo config", "path", dest) return nil }