mirror of
https://github.com/kairos-io/kairos-agent.git
synced 2025-04-27 11:21:44 +00:00
Load elemental config/spec from cloud config (#82)
This commit is contained in:
parent
fd22840d14
commit
9bff3742c1
@ -31,7 +31,7 @@ type Config struct {
|
||||
|
||||
func LoadConfig(path ...string) (*Config, error) {
|
||||
if len(path) == 0 {
|
||||
path = append(path, "/etc/kairos/agent.yaml", "/etc/elemental/config.yaml")
|
||||
path = append(path, "/etc/kairos/agent.yaml")
|
||||
}
|
||||
|
||||
cfg := &Config{}
|
||||
|
@ -10,8 +10,8 @@ import (
|
||||
|
||||
type RunStage struct{}
|
||||
|
||||
func (r RunStage) Run(_ config.Config) error {
|
||||
cfg, err := elementalConfig.ReadConfigRun("/etc/elemental")
|
||||
func (r RunStage) Run(c config.Config) error {
|
||||
cfg, err := elementalConfig.ReadConfigRunFromAgentConfig(&c)
|
||||
if err != nil {
|
||||
cfg.Logger.Errorf("Error reading config: %s\n", err)
|
||||
}
|
||||
|
@ -11,10 +11,6 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
events "github.com/kairos-io/kairos-sdk/bus"
|
||||
"github.com/kairos-io/kairos-sdk/collector"
|
||||
"github.com/kairos-io/kairos-sdk/machine"
|
||||
"github.com/kairos-io/kairos-sdk/utils"
|
||||
hook "github.com/kairos-io/kairos-agent/v2/internal/agent/hooks"
|
||||
"github.com/kairos-io/kairos-agent/v2/internal/bus"
|
||||
"github.com/kairos-io/kairos-agent/v2/internal/cmd"
|
||||
@ -23,6 +19,10 @@ import (
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/elementalConfig"
|
||||
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
|
||||
elementalUtils "github.com/kairos-io/kairos-agent/v2/pkg/utils"
|
||||
events "github.com/kairos-io/kairos-sdk/bus"
|
||||
"github.com/kairos-io/kairos-sdk/collector"
|
||||
"github.com/kairos-io/kairos-sdk/machine"
|
||||
"github.com/kairos-io/kairos-sdk/utils"
|
||||
qr "github.com/mudler/go-nodepair/qrcode"
|
||||
"github.com/mudler/go-pluggable"
|
||||
"github.com/pterm/pterm"
|
||||
@ -96,14 +96,7 @@ func ManualInstall(c string, options map[string]string, strictValidations bool)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load the installation Config from the system
|
||||
installConfig, err := elementalConfig.ReadConfigRun("/etc/elemental")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return RunInstall(installConfig, options)
|
||||
return RunInstall(options)
|
||||
}
|
||||
|
||||
func Install(dir ...string) error {
|
||||
@ -130,12 +123,6 @@ func Install(dir ...string) error {
|
||||
|
||||
ensureDataSourceReady()
|
||||
|
||||
// Load the installation Config from the system
|
||||
installConfig, err := elementalConfig.ReadConfigRun("/etc/elemental")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Reads config, and if present and offline is defined,
|
||||
// runs the installation
|
||||
cc, err := config.Scan(collector.Directories(dir...), collector.MergeBootLine, collector.NoLogs)
|
||||
@ -148,7 +135,7 @@ func Install(dir ...string) error {
|
||||
r["device"] = cc.Install.Device
|
||||
mergeOption(configStr, r)
|
||||
|
||||
err = RunInstall(installConfig, r)
|
||||
err = RunInstall(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -242,7 +229,7 @@ func Install(dir ...string) error {
|
||||
|
||||
pterm.Info.Println("Starting installation")
|
||||
|
||||
if err := RunInstall(installConfig, r); err != nil {
|
||||
if err := RunInstall(r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -259,14 +246,7 @@ func Install(dir ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func RunInstall(installConfig *v1.RunConfig, options map[string]string) error {
|
||||
f, err := elementalUtils.TempFile(installConfig.Fs, "", "kairos-install-config-xxx.yaml")
|
||||
if err != nil {
|
||||
installConfig.Logger.Error("Error creating temporal file for install config: %s\n", err.Error())
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(f.Name())
|
||||
|
||||
func RunInstall(options map[string]string) error {
|
||||
cloudInit, ok := options["cc"]
|
||||
if !ok {
|
||||
fmt.Println("cloudInit must be specified among options")
|
||||
@ -286,12 +266,6 @@ func RunInstall(installConfig *v1.RunConfig, options map[string]string) error {
|
||||
env := append(c.Install.Env, c.Env...)
|
||||
utils.SetEnv(env)
|
||||
|
||||
err = os.WriteFile(f.Name(), []byte(cloudInit), os.ModePerm)
|
||||
if err != nil {
|
||||
fmt.Printf("could not write cloud init to %s: %s\n", f.Name(), err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
_, reboot := options["reboot"]
|
||||
_, poweroff := options["poweroff"]
|
||||
if poweroff {
|
||||
@ -301,8 +275,24 @@ func RunInstall(installConfig *v1.RunConfig, options map[string]string) error {
|
||||
c.Install.Reboot = true
|
||||
}
|
||||
|
||||
// Generate the installation spec
|
||||
installSpec, _ := elementalConfig.ReadInstallSpec(installConfig)
|
||||
// Load the installation Config from the system
|
||||
installConfig, installSpec, err := elementalConfig.ReadInstallConfigFromAgentConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := elementalUtils.TempFile(installConfig.Fs, "", "kairos-install-config-xxx.yaml")
|
||||
if err != nil {
|
||||
installConfig.Logger.Error("Error creating temporal file for install config: %s\n", err.Error())
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(f.Name())
|
||||
|
||||
err = os.WriteFile(f.Name(), []byte(cloudInit), os.ModePerm)
|
||||
if err != nil {
|
||||
fmt.Printf("could not write cloud init to %s: %s\n", f.Name(), err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
installSpec.NoFormat = c.Install.NoFormat
|
||||
|
||||
|
@ -1,18 +1,15 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/jaypipes/ghw/pkg/block"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
|
||||
conf "github.com/kairos-io/kairos-agent/v2/pkg/elementalConfig"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/utils"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/config"
|
||||
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
|
||||
v1mock "github.com/kairos-io/kairos-agent/v2/tests/mocks"
|
||||
"github.com/twpayne/go-vfs"
|
||||
"github.com/twpayne/go-vfs/vfst"
|
||||
@ -66,27 +63,17 @@ var _ = Describe("prepareConfiguration", func() {
|
||||
})
|
||||
|
||||
var _ = Describe("RunInstall", func() {
|
||||
var installConfig *v1.RunConfig
|
||||
var options map[string]string
|
||||
var err error
|
||||
var fs vfs.FS
|
||||
var cloudInit *v1mock.FakeCloudInitRunner
|
||||
var cleanup func()
|
||||
var memLog *bytes.Buffer
|
||||
var ghwTest v1mock.GhwMock
|
||||
var cmdline func() ([]byte, error)
|
||||
|
||||
BeforeEach(func() {
|
||||
// Default mock objects
|
||||
runner := v1mock.NewFakeRunner()
|
||||
syscall := &v1mock.FakeSyscall{}
|
||||
mounter := v1mock.NewErrorMounter()
|
||||
memLog = &bytes.Buffer{}
|
||||
logger := v1.NewBufferLogger(memLog)
|
||||
logger = v1.NewLogger()
|
||||
extractor := v1mock.NewFakeImageExtractor(logger)
|
||||
//logger.SetLevel(v1.DebugLevel())
|
||||
cloudInit = &v1mock.FakeCloudInitRunner{}
|
||||
// Set default cmdline function so we dont panic :o
|
||||
cmdline = func() ([]byte, error) {
|
||||
return []byte{}, nil
|
||||
@ -105,17 +92,6 @@ var _ = Describe("RunInstall", func() {
|
||||
_, err = fs.Create(grubCfg)
|
||||
Expect(err).To(BeNil())
|
||||
|
||||
// Create new runconfig with all mocked objects
|
||||
installConfig = conf.NewRunConfig(
|
||||
conf.WithFs(fs),
|
||||
conf.WithRunner(runner),
|
||||
conf.WithLogger(logger),
|
||||
conf.WithMounter(mounter),
|
||||
conf.WithSyscall(syscall),
|
||||
conf.WithCloudInitRunner(cloudInit),
|
||||
conf.WithImageExtractor(extractor),
|
||||
)
|
||||
|
||||
// Side effect of runners, hijack calls to commands and return our stuff
|
||||
partNum := 0
|
||||
partedOut := printOutput
|
||||
@ -225,7 +201,7 @@ install:
|
||||
|
||||
It("runs the install", func() {
|
||||
Skip("Not ready yet")
|
||||
err = RunInstall(installConfig, options)
|
||||
err = RunInstall(options)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
@ -8,8 +8,6 @@ import (
|
||||
"github.com/kairos-io/kairos-agent/v2/internal/bus"
|
||||
"github.com/kairos-io/kairos-agent/v2/internal/cmd"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/config"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/elementalConfig"
|
||||
|
||||
events "github.com/kairos-io/kairos-sdk/bus"
|
||||
"github.com/kairos-io/kairos-sdk/unstructured"
|
||||
|
||||
@ -19,7 +17,6 @@ import (
|
||||
"github.com/mudler/go-pluggable"
|
||||
"github.com/mudler/yip/pkg/schema"
|
||||
"github.com/pterm/pterm"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -277,16 +274,7 @@ func InteractiveInstall(debug, spawnShell bool) error {
|
||||
pterm.Info.Println("Starting installation")
|
||||
pterm.Info.Println(finalCloudConfig)
|
||||
|
||||
// Set debug from here already, so it's loaded by the ReadConfigRun
|
||||
viper.Set("debug", debug)
|
||||
|
||||
// Load the installation Config from the system
|
||||
installConfig, err := elementalConfig.ReadConfigRun("/etc/elemental")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = RunInstall(installConfig, map[string]string{
|
||||
err = RunInstall(map[string]string{
|
||||
"device": device,
|
||||
"cc": finalCloudConfig,
|
||||
})
|
||||
|
@ -3,28 +3,26 @@ package agent
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/sanity-io/litter"
|
||||
"github.com/sirupsen/logrus"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
sdk "github.com/kairos-io/kairos-sdk/bus"
|
||||
"github.com/kairos-io/kairos-sdk/collector"
|
||||
"github.com/kairos-io/kairos-sdk/machine"
|
||||
"github.com/kairos-io/kairos-sdk/utils"
|
||||
hook "github.com/kairos-io/kairos-agent/v2/internal/agent/hooks"
|
||||
"github.com/kairos-io/kairos-agent/v2/internal/bus"
|
||||
"github.com/kairos-io/kairos-agent/v2/internal/cmd"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/action"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/config"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/elementalConfig"
|
||||
sdk "github.com/kairos-io/kairos-sdk/bus"
|
||||
"github.com/kairos-io/kairos-sdk/collector"
|
||||
"github.com/kairos-io/kairos-sdk/machine"
|
||||
"github.com/kairos-io/kairos-sdk/utils"
|
||||
|
||||
"github.com/mudler/go-pluggable"
|
||||
"github.com/pterm/pterm"
|
||||
)
|
||||
|
||||
func Reset(debug bool, dir ...string) error {
|
||||
func Reset(dir ...string) error {
|
||||
// TODO: Enable args? No args for now so no possibility of reset persistent or overriding the source for the reset
|
||||
// Nor the auto-reboot via cmd?
|
||||
// This comment pertains calling reset via cmdline when wanting to override configs
|
||||
@ -43,7 +41,6 @@ func Reset(debug bool, dir ...string) error {
|
||||
|
||||
// This loads yet another config ¬_¬
|
||||
// TODO: merge this somehow with the rest so there is no 5 places to configure stuff?
|
||||
// Also this reads the elemental config.yaml
|
||||
agentConfig, err := LoadConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
@ -83,18 +80,12 @@ func Reset(debug bool, dir ...string) error {
|
||||
|
||||
utils.SetEnv(c.Env)
|
||||
|
||||
resetConfig, err := elementalConfig.ReadConfigRun("/etc/elemental")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if debug {
|
||||
resetConfig.Logger.SetLevel(logrus.DebugLevel)
|
||||
}
|
||||
resetConfig.Logger.Debugf("Full config: %s\n", litter.Sdump(resetConfig))
|
||||
resetSpec, err := elementalConfig.ReadResetSpec(resetConfig)
|
||||
// Load the installation Config from the cloud-config data
|
||||
resetConfig, resetSpec, err := elementalConfig.ReadResetConfigFromAgentConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Not even sure what opts can come from here to be honest. Where is the struct that supports this options?
|
||||
// Where is the docs to support this? This is generic af and not easily identifiable
|
||||
if len(options) == 0 {
|
||||
|
@ -17,8 +17,6 @@ import (
|
||||
"github.com/kairos-io/kairos-sdk/collector"
|
||||
"github.com/kairos-io/kairos-sdk/utils"
|
||||
"github.com/mudler/go-pluggable"
|
||||
"github.com/sanity-io/litter"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func ListReleases(includePrereleases bool) semver.Collection {
|
||||
@ -52,7 +50,7 @@ func ListReleases(includePrereleases bool) semver.Collection {
|
||||
}
|
||||
|
||||
func Upgrade(
|
||||
version, source string, force, debug, strictValidations bool, dirs []string, preReleases bool) error {
|
||||
version, source string, force, strictValidations bool, dirs []string, preReleases bool) error {
|
||||
bus.Manager.Initialize()
|
||||
|
||||
if version == "" && source == "" {
|
||||
@ -93,10 +91,6 @@ func Upgrade(
|
||||
}
|
||||
}
|
||||
|
||||
if debug {
|
||||
fmt.Printf("Upgrading to source: '%s'\n", img)
|
||||
}
|
||||
|
||||
c, err := config.Scan(collector.Directories(dirs...), collector.StrictValidation(strictValidations))
|
||||
if err != nil {
|
||||
return err
|
||||
@ -105,18 +99,11 @@ func Upgrade(
|
||||
utils.SetEnv(c.Env)
|
||||
|
||||
// Load the upgrade Config from the system
|
||||
upgradeConfig, err := elementalConfig.ReadConfigRun("/etc/elemental")
|
||||
upgradeConfig, upgradeSpec, err := elementalConfig.ReadUpgradeConfigFromAgentConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if debug {
|
||||
upgradeConfig.Logger.SetLevel(log.DebugLevel)
|
||||
}
|
||||
|
||||
upgradeConfig.Logger.Debugf("Full config: %s\n", litter.Sdump(upgradeConfig))
|
||||
|
||||
// Generate the upgrade spec
|
||||
upgradeSpec, _ := elementalConfig.ReadUpgradeSpec(upgradeConfig)
|
||||
// Add the image source
|
||||
imgSource, err := v1.NewSrcFromURI(img)
|
||||
if err != nil {
|
||||
@ -124,7 +111,7 @@ func Upgrade(
|
||||
}
|
||||
upgradeSpec.Active.Source = imgSource
|
||||
|
||||
// Sanitize (this is not required but good to do
|
||||
// Sanitize
|
||||
err = upgradeSpec.Sanitize()
|
||||
if err != nil {
|
||||
return err
|
||||
|
19
main.go
19
main.go
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/utils"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
@ -17,7 +18,6 @@ import (
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/config"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/elementalConfig"
|
||||
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/utils"
|
||||
"github.com/kairos-io/kairos-sdk/bundles"
|
||||
"github.com/kairos-io/kairos-sdk/collector"
|
||||
"github.com/kairos-io/kairos-sdk/machine"
|
||||
@ -136,7 +136,7 @@ See https://kairos.io/docs/upgrade/manual/ for documentation.
|
||||
}
|
||||
|
||||
return agent.Upgrade(
|
||||
v, source, c.Bool("force"), c.Bool("debug"),
|
||||
v, source, c.Bool("force"),
|
||||
c.Bool("strict-validation"), configScanDir,
|
||||
c.Bool("pre"),
|
||||
)
|
||||
@ -457,7 +457,8 @@ This command is meant to be used from the boot GRUB menu, but can likely be used
|
||||
{
|
||||
Name: "reset",
|
||||
Action: func(c *cli.Context) error {
|
||||
return agent.Reset(c.Bool("debug"), configScanDir...)
|
||||
|
||||
return agent.Reset(configScanDir...)
|
||||
},
|
||||
Usage: "Starts kairos reset mode",
|
||||
Description: `
|
||||
@ -535,7 +536,11 @@ The validate command expects a configuration file as its only argument. Local fi
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
stage := c.Args().First()
|
||||
cfg, err := elementalConfig.ReadConfigRun("/etc/elemental")
|
||||
config, err := config.Scan(collector.Directories(configScanDir...), collector.NoLogs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg, err := elementalConfig.ReadConfigRunFromAgentConfig(config)
|
||||
cfg.Strict = c.Bool("strict")
|
||||
|
||||
if len(c.StringSlice("cloud-init-paths")) > 0 {
|
||||
@ -582,7 +587,11 @@ The validate command expects a configuration file as its only argument. Local fi
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid path %s", destination)
|
||||
}
|
||||
cfg, err := elementalConfig.ReadConfigRun("/etc/elemental")
|
||||
config, err := config.Scan(collector.Directories(configScanDir...), collector.NoLogs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg, err := elementalConfig.ReadConfigRunFromAgentConfig(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ import (
|
||||
const (
|
||||
GrubConf = "/etc/cos/grub.cfg"
|
||||
GrubOEMEnv = "grub_oem_env"
|
||||
GrubDefEntry = "cOS"
|
||||
GrubDefEntry = "Kairos"
|
||||
DefaultTty = "tty1"
|
||||
BiosPartName = "bios"
|
||||
EfiLabel = "COS_GRUB"
|
||||
|
@ -18,6 +18,7 @@ package elementalConfig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
@ -28,6 +29,7 @@ import (
|
||||
|
||||
"github.com/kairos-io/kairos-agent/v2/internal/common"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/cloudinit"
|
||||
agentConfig "github.com/kairos-io/kairos-agent/v2/pkg/config"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/http"
|
||||
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
|
||||
@ -35,7 +37,6 @@ import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/sanity-io/litter"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/twpayne/go-vfs"
|
||||
"k8s.io/mount-utils"
|
||||
@ -222,11 +223,13 @@ func NewInstallSpec(cfg v1.Config) *v1.InstallSpec {
|
||||
recoveryImg.Source = v1.NewFileSrc(recoveryImgFile)
|
||||
recoveryImg.FS = constants.SquashFs
|
||||
recoveryImg.File = filepath.Join(constants.RecoveryDir, "cOS", constants.RecoverySquashFile)
|
||||
recoveryImg.Size = constants.ImgSize
|
||||
} else {
|
||||
recoveryImg.Source = v1.NewFileSrc(activeImg.File)
|
||||
recoveryImg.FS = constants.LinuxImgFs
|
||||
recoveryImg.Label = constants.SystemLabel
|
||||
recoveryImg.File = filepath.Join(constants.RecoveryDir, "cOS", constants.RecoveryImgFile)
|
||||
recoveryImg.Size = constants.ImgSize
|
||||
}
|
||||
|
||||
passiveImg = v1.Image{
|
||||
@ -234,6 +237,7 @@ func NewInstallSpec(cfg v1.Config) *v1.InstallSpec {
|
||||
Label: constants.PassiveLabel,
|
||||
Source: v1.NewFileSrc(activeImg.File),
|
||||
FS: constants.LinuxImgFs,
|
||||
Size: constants.ImgSize,
|
||||
}
|
||||
|
||||
return &v1.InstallSpec{
|
||||
@ -364,6 +368,7 @@ func NewUpgradeSpec(cfg v1.Config) (*v1.UpgradeSpec, error) {
|
||||
passive = v1.Image{
|
||||
File: filepath.Join(ep.State.MountPoint, "cOS", constants.PassiveImgFile),
|
||||
Label: constants.PassiveLabel,
|
||||
Size: constants.ImgSize,
|
||||
Source: v1.NewFileSrc(active.File),
|
||||
FS: active.FS,
|
||||
}
|
||||
@ -507,6 +512,7 @@ func NewResetSpec(cfg v1.Config) (*v1.ResetSpec, error) {
|
||||
Passive: v1.Image{
|
||||
File: filepath.Join(ep.State.MountPoint, "cOS", constants.PassiveImgFile),
|
||||
Label: constants.PassiveLabel,
|
||||
Size: constants.ImgSize,
|
||||
Source: v1.NewFileSrc(activeFile),
|
||||
FS: constants.LinuxImgFs,
|
||||
},
|
||||
@ -544,112 +550,102 @@ func NewBuildConfig(opts ...GenericOptions) *v1.BuildConfig {
|
||||
return b
|
||||
}
|
||||
|
||||
func ReadConfigRun(configDir string) (*v1.RunConfig, error) {
|
||||
// ReadConfigRunFromAgentConfig reads the configuration directly from a given cloud config string
|
||||
func ReadConfigRunFromAgentConfig(c *agentConfig.Config) (*v1.RunConfig, error) {
|
||||
cfg := NewRunConfig(WithLogger(v1.NewLogger()), WithOCIImageExtractor())
|
||||
var err error
|
||||
|
||||
cc, err := c.String()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
configLogger(cfg.Logger, cfg.Fs)
|
||||
|
||||
// TODO: is this really needed? It feels quite wrong, shouldn't it be loaded
|
||||
// as regular environment variables?
|
||||
// IMHO loading os-release as env variables should be sufficient here
|
||||
cfgDefault := []string{"/etc/os-release"}
|
||||
for _, c := range cfgDefault {
|
||||
if exists, _ := utils.Exists(cfg.Fs, c); exists {
|
||||
viper.SetConfigFile(c)
|
||||
viper.SetConfigType("env")
|
||||
cobra.CheckErr(viper.MergeInConfig())
|
||||
}
|
||||
}
|
||||
|
||||
// merge yaml config files on top of default runconfig
|
||||
if exists, _ := utils.Exists(cfg.Fs, configDir); exists {
|
||||
viper.AddConfigPath(configDir)
|
||||
viper.SetConfigType("yaml")
|
||||
viper.SetConfigName("config")
|
||||
// If a config file is found, read it in.
|
||||
err := viper.MergeInConfig()
|
||||
if err != nil {
|
||||
cfg.Logger.Warnf("error merging config files: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Load extra config files on configdir/config.d/ so we can override config values
|
||||
cfgExtra := fmt.Sprintf("%s/config.d/", strings.TrimSuffix(configDir, "/"))
|
||||
if exists, _ := utils.Exists(cfg.Fs, cfgExtra); exists {
|
||||
viper.AddConfigPath(cfgExtra)
|
||||
_ = filepath.WalkDir(cfgExtra, func(path string, d fs.DirEntry, err error) error {
|
||||
if !d.IsDir() && filepath.Ext(d.Name()) == ".yaml" {
|
||||
viper.SetConfigType("yaml")
|
||||
viper.SetConfigName(strings.TrimSuffix(d.Name(), ".yaml"))
|
||||
cobra.CheckErr(viper.MergeInConfig())
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// unmarshal all the vars into the RunConfig object
|
||||
err := viper.Unmarshal(cfg, setDecoder, decodeHook)
|
||||
err = yaml.Unmarshal([]byte(cc), &cfg)
|
||||
if err != nil {
|
||||
cfg.Logger.Warnf("error unmarshalling RunConfig: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Store the full cloud-config in here so we can reuse it afterwards
|
||||
cfg.FullCloudConfig = cc
|
||||
err = cfg.Sanitize()
|
||||
cfg.Logger.Debugf("Full config loaded: %s", litter.Sdump(cfg))
|
||||
return cfg, err
|
||||
}
|
||||
|
||||
func ReadInstallSpec(r *v1.RunConfig) (*v1.InstallSpec, error) {
|
||||
install := NewInstallSpec(r.Config)
|
||||
vp := viper.Sub("install")
|
||||
if vp == nil {
|
||||
vp = viper.New()
|
||||
}
|
||||
// readSpecFromCloudConfig returns a v1.Spec for the given spec
|
||||
func readSpecFromCloudConfig(r *v1.RunConfig, spec string) (v1.Spec, error) {
|
||||
var sp v1.Spec
|
||||
var err error
|
||||
|
||||
err := vp.Unmarshal(install, setDecoder, decodeHook)
|
||||
if err != nil {
|
||||
r.Logger.Warnf("error unmarshalling InstallSpec: %s", err)
|
||||
switch spec {
|
||||
case "install":
|
||||
sp = NewInstallSpec(r.Config)
|
||||
case "upgrade":
|
||||
sp, err = NewUpgradeSpec(r.Config)
|
||||
case "reset":
|
||||
sp, err = NewResetSpec(r.Config)
|
||||
default:
|
||||
return nil, fmt.Errorf("spec not valid: %s", spec)
|
||||
}
|
||||
err = install.Sanitize()
|
||||
r.Logger.Debugf("Loaded install spec: %s", litter.Sdump(install))
|
||||
return install, err
|
||||
}
|
||||
|
||||
func ReadUpgradeSpec(r *v1.RunConfig) (*v1.UpgradeSpec, error) {
|
||||
upgrade, err := NewUpgradeSpec(r.Config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed initializing upgrade spec: %v", err)
|
||||
}
|
||||
vp := viper.Sub("upgrade")
|
||||
if vp == nil {
|
||||
vp = viper.New()
|
||||
}
|
||||
|
||||
err = vp.Unmarshal(upgrade, setDecoder, decodeHook)
|
||||
if err != nil {
|
||||
r.Logger.Warnf("error unmarshalling UpgradeSpec: %s", err)
|
||||
}
|
||||
err = upgrade.Sanitize()
|
||||
r.Logger.Debugf("Loaded upgrade UpgradeSpec: %s", litter.Sdump(upgrade))
|
||||
return upgrade, err
|
||||
}
|
||||
|
||||
func ReadResetSpec(r *v1.RunConfig) (*v1.ResetSpec, error) {
|
||||
reset, err := NewResetSpec(r.Config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed initializing reset spec: %v", err)
|
||||
}
|
||||
vp := viper.Sub("reset")
|
||||
|
||||
// Load the config into viper from the raw cloud config string
|
||||
viper.SetConfigType("yaml")
|
||||
viper.ReadConfig(strings.NewReader(r.FullCloudConfig))
|
||||
vp := viper.Sub(spec)
|
||||
if vp == nil {
|
||||
vp = viper.New()
|
||||
}
|
||||
|
||||
err = vp.Unmarshal(reset, setDecoder, decodeHook)
|
||||
err = vp.Unmarshal(sp, setDecoder, decodeHook)
|
||||
if err != nil {
|
||||
r.Logger.Warnf("error unmarshalling ResetSpec: %s", err)
|
||||
r.Logger.Warnf("error unmarshalling %s Spec: %s", spec, err)
|
||||
}
|
||||
err = reset.Sanitize()
|
||||
r.Logger.Debugf("Loaded reset spec: %s", litter.Sdump(reset))
|
||||
return reset, err
|
||||
r.Logger.Debugf("Loaded %s spec: %s", litter.Sdump(sp))
|
||||
return sp, err
|
||||
}
|
||||
|
||||
// readConfigAndSpecFromAgentConfig will return the config and spec for the given action based off the agent Config
|
||||
func readConfigAndSpecFromAgentConfig(c *agentConfig.Config, action string) (*v1.RunConfig, v1.Spec, error) {
|
||||
runConfig, err := ReadConfigRunFromAgentConfig(c)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
spec, err := readSpecFromCloudConfig(runConfig, action)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return runConfig, spec, nil
|
||||
}
|
||||
|
||||
// ReadResetConfigFromAgentConfig will return a proper v1.RunConfig and v1.ResetSpec based on an agent Config
|
||||
func ReadResetConfigFromAgentConfig(c *agentConfig.Config) (*v1.RunConfig, *v1.ResetSpec, error) {
|
||||
config, spec, err := readConfigAndSpecFromAgentConfig(c, "reset")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
resetSpec := spec.(*v1.ResetSpec)
|
||||
return config, resetSpec, nil
|
||||
}
|
||||
|
||||
func ReadInstallConfigFromAgentConfig(c *agentConfig.Config) (*v1.RunConfig, *v1.InstallSpec, error) {
|
||||
config, spec, err := readConfigAndSpecFromAgentConfig(c, "install")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
installSpec := spec.(*v1.InstallSpec)
|
||||
return config, installSpec, nil
|
||||
}
|
||||
|
||||
func ReadUpgradeConfigFromAgentConfig(c *agentConfig.Config) (*v1.RunConfig, *v1.UpgradeSpec, error) {
|
||||
config, spec, err := readConfigAndSpecFromAgentConfig(c, "upgrade")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
upgradeSpec := spec.(*v1.UpgradeSpec)
|
||||
return config, upgradeSpec, nil
|
||||
}
|
||||
|
||||
func configLogger(log v1.Logger, vfs v1.FS) {
|
||||
|
@ -122,12 +122,13 @@ func (c *Config) Sanitize() error {
|
||||
}
|
||||
|
||||
type RunConfig struct {
|
||||
Debug bool `yaml:"strict,omitempty" mapstructure:"debug"`
|
||||
Strict bool `yaml:"strict,omitempty" mapstructure:"strict"`
|
||||
Reboot bool `yaml:"reboot,omitempty" mapstructure:"reboot"`
|
||||
PowerOff bool `yaml:"poweroff,omitempty" mapstructure:"poweroff"`
|
||||
CloudInitPaths []string `yaml:"cloud-init-paths,omitempty" mapstructure:"cloud-init-paths"`
|
||||
EjectCD bool `yaml:"eject-cd,omitempty" mapstructure:"eject-cd"`
|
||||
Debug bool `yaml:"debug,omitempty" mapstructure:"debug"`
|
||||
Strict bool `yaml:"strict,omitempty" mapstructure:"strict"`
|
||||
Reboot bool `yaml:"reboot,omitempty" mapstructure:"reboot"`
|
||||
PowerOff bool `yaml:"poweroff,omitempty" mapstructure:"poweroff"`
|
||||
CloudInitPaths []string `yaml:"cloud-init-paths,omitempty" mapstructure:"cloud-init-paths"`
|
||||
EjectCD bool `yaml:"eject-cd,omitempty" mapstructure:"eject-cd"`
|
||||
FullCloudConfig string // Stores the full cloud config used to generate the spec afterwards
|
||||
|
||||
// 'inline' and 'squash' labels ensure config fields
|
||||
// are embedded from a yaml and map PoV
|
||||
@ -197,6 +198,10 @@ func (i *InstallSpec) Sanitize() error {
|
||||
return i.Partitions.SetFirmwarePartitions(i.Firmware, i.PartTable)
|
||||
}
|
||||
|
||||
type Spec interface {
|
||||
Sanitize() error
|
||||
}
|
||||
|
||||
// ResetSpec struct represents all the reset action details
|
||||
type ResetSpec struct {
|
||||
FormatPersistent bool `yaml:"reset-persistent,omitempty" mapstructure:"reset-persistent"`
|
||||
|
Loading…
Reference in New Issue
Block a user