mirror of
https://github.com/kairos-io/kairos-agent.git
synced 2025-08-10 12:41:56 +00:00
152 lines
3.6 KiB
Go
152 lines
3.6 KiB
Go
package agent
|
|
|
|
import (
|
|
"github.com/kairos-io/kairos-agent/v2/pkg/config"
|
|
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
|
|
"github.com/kairos-io/kairos-sdk/collector"
|
|
"github.com/mudler/yip/pkg/schema"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/kairos-io/kairos-agent/v2/internal/kairos"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
type BrandingText struct {
|
|
InteractiveInstall string `yaml:"interactive-install"`
|
|
Install string `yaml:"install"`
|
|
Reset string `yaml:"reset"`
|
|
Recovery string `yaml:"recovery"`
|
|
}
|
|
type WebUI struct {
|
|
Disable bool `yaml:"disable"`
|
|
ListenAddress string `yaml:"listen_address"`
|
|
}
|
|
|
|
func (w WebUI) HasAddress() bool {
|
|
return w.ListenAddress != ""
|
|
}
|
|
|
|
type Config struct {
|
|
Fast bool `yaml:"fast,omitempty"`
|
|
WebUI WebUI `yaml:"webui"`
|
|
Branding BrandingText `yaml:"branding"`
|
|
}
|
|
|
|
func LoadConfig(path ...string) (*Config, error) {
|
|
if len(path) == 0 {
|
|
path = append(path, "/etc/kairos/agent.yaml")
|
|
}
|
|
|
|
cfg := &Config{}
|
|
|
|
for _, p := range path {
|
|
f, err := os.ReadFile(p)
|
|
if err == nil {
|
|
yaml.Unmarshal(f, cfg) //nolint:errcheck
|
|
}
|
|
}
|
|
|
|
if cfg.Branding.InteractiveInstall == "" {
|
|
f, err := os.ReadFile(kairos.BrandingFile("interactive_install_text"))
|
|
if err == nil {
|
|
cfg.Branding.InteractiveInstall = string(f)
|
|
}
|
|
}
|
|
|
|
if cfg.Branding.Install == "" {
|
|
f, err := os.ReadFile(kairos.BrandingFile("install_text"))
|
|
if err == nil {
|
|
cfg.Branding.Install = string(f)
|
|
}
|
|
}
|
|
|
|
if cfg.Branding.Recovery == "" {
|
|
f, err := os.ReadFile(kairos.BrandingFile("recovery_text"))
|
|
if err == nil {
|
|
cfg.Branding.Recovery = string(f)
|
|
}
|
|
}
|
|
|
|
if cfg.Branding.Reset == "" {
|
|
f, err := os.ReadFile(kairos.BrandingFile("reset_text"))
|
|
if err == nil {
|
|
cfg.Branding.Reset = string(f)
|
|
}
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
type ExtraFields struct {
|
|
Extrafields map[string]any `yaml:",inline,omitempty"`
|
|
}
|
|
|
|
// NewInteractiveInstallConfig creates a new config from model values
|
|
func NewInteractiveInstallConfig(m *Model) *config.Config {
|
|
// Always set the extra fields
|
|
extras := ExtraFields{m.extraFields}
|
|
|
|
// This is temporal to generate a valid cc file, no need to properly initialize everything
|
|
cc := &config.Config{
|
|
Install: &config.Install{
|
|
Device: m.disk,
|
|
},
|
|
}
|
|
|
|
if m.source != "" {
|
|
cc.Install.Source = m.source
|
|
}
|
|
|
|
var cloudConfig schema.YipConfig
|
|
|
|
// Only add the user stage if we have any users
|
|
if m.username != "" {
|
|
user := schema.User{
|
|
Name: m.username,
|
|
PasswordHash: m.password,
|
|
Groups: []string{"admin"},
|
|
SSHAuthorizedKeys: m.sshKeys,
|
|
}
|
|
|
|
stage := config.NetworkStage.String()
|
|
// If we got no ssh keys, we don't need network, do the user as soon as possible
|
|
if len(m.sshKeys) == 0 {
|
|
stage = config.InitramfsStage.String()
|
|
}
|
|
|
|
cloudConfig = schema.YipConfig{Name: "Config generated by the installer",
|
|
Stages: map[string][]schema.Stage{stage: {
|
|
{
|
|
Users: map[string]schema.User{
|
|
m.username: user,
|
|
},
|
|
},
|
|
}}}
|
|
} else {
|
|
// If no users, we need to set this option to skip the user validation and confirm that we want a system with no users.
|
|
cc.Install.NoUsers = true
|
|
}
|
|
|
|
// Merge all yamls into one
|
|
dat, err := config.MergeYAML(cloudConfig, cc, extras)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
finalCloudConfig := config.AddHeader("#cloud-config", string(dat))
|
|
|
|
// Read also any userdata in the system
|
|
cc, _ = config.ScanNoLogs(
|
|
collector.Readers(strings.NewReader(finalCloudConfig)),
|
|
collector.Directories(constants.GetUserConfigDirs()...),
|
|
collector.MergeBootLine,
|
|
)
|
|
|
|
// Generate final config
|
|
ccString, _ := cc.String()
|
|
m.log.Logger.Debug().Msgf("Generated cloud config: %s", ccString)
|
|
|
|
return cc
|
|
}
|