Drop runconfig in favour of config (#101)

This commit is contained in:
Itxaka 2023-07-25 11:08:27 +02:00 committed by GitHub
parent bca3277b7d
commit 5b945303c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 127 additions and 148 deletions

View File

@ -16,7 +16,7 @@ func (r RunStage) Run(c config.Config, _ v1.Spec) error {
if err != nil {
cfg.Logger.Errorf("Error reading config: %s\n", err)
}
_ = utils.RunStage(&cfg.Config, "kairos-install.after", cfg.Strict, cfg.CloudInitPaths...)
_ = utils.RunStage(cfg, "kairos-install.after")
events.RunHookScript("/usr/bin/kairos-agent.install.after.hook") //nolint:errcheck
return nil
}

View File

@ -270,7 +270,7 @@ func RunInstall(c *config.Config) error {
installConfig.CloudInitPaths = append(installConfig.CloudInitPaths, installSpec.CloudInit...)
// Run pre-install stage
_ = elementalUtils.RunStage(&installConfig.Config, "kairos-install.pre", installConfig.Strict, installConfig.CloudInitPaths...)
_ = elementalUtils.RunStage(installConfig, "kairos-install.pre")
events.RunHookScript("/usr/bin/kairos-agent.install.pre.hook") //nolint:errcheck
// Create the action
installAction := action.NewInstallAction(installConfig, installSpec)

View File

@ -544,7 +544,7 @@ The validate command expects a configuration file as its only argument. Local fi
if err != nil {
cfg.Logger.Errorf("Error reading config: %s\n", err)
}
return utils.RunStage(&cfg.Config, stage, cfg.Strict, cfg.CloudInitPaths...)
return utils.RunStage(cfg, stage)
},
},
{

View File

@ -22,20 +22,20 @@ import (
)
// Hook is RunStage wrapper that only adds logic to ignore errors
// in case v1.RunConfig.Strict is set to false
func Hook(config *v1.Config, hook string, strict bool, cloudInitPaths ...string) error {
// in case v1.Config.Strict is set to false
func Hook(config *v1.Config, hook string) error {
config.Logger.Infof("Running %s hook", hook)
err := utils.RunStage(config, hook, strict, cloudInitPaths...)
if !strict {
err := utils.RunStage(config, hook)
if !config.Strict {
err = nil
}
return err
}
// ChrootHook executes Hook inside a chroot environment
func ChrootHook(config *v1.Config, hook string, strict bool, chrootDir string, bindMounts map[string]string, cloudInitPaths ...string) (err error) {
func ChrootHook(config *v1.Config, hook string, chrootDir string, bindMounts map[string]string) (err error) {
callback := func() error {
return Hook(config, hook, strict, cloudInitPaths...)
return Hook(config, hook)
}
return utils.ChrootedCallback(config, chrootDir, bindMounts, callback)
}

View File

@ -38,9 +38,9 @@ func (i *InstallAction) installHook(hook string, chroot bool) error {
if oem != nil && oem.MountPoint != "" {
extraMounts[oem.MountPoint] = cnst.OEMPath
}
return ChrootHook(&i.cfg.Config, hook, i.cfg.Strict, i.spec.Active.MountPoint, extraMounts, i.cfg.CloudInitPaths...)
return ChrootHook(i.cfg, hook, i.spec.Active.MountPoint, extraMounts)
}
return Hook(&i.cfg.Config, hook, i.cfg.Strict, i.cfg.CloudInitPaths...)
return Hook(i.cfg, hook)
}
func (i *InstallAction) createInstallStateYaml(sysMeta, recMeta interface{}) error {
@ -107,17 +107,17 @@ func (i *InstallAction) createInstallStateYaml(sysMeta, recMeta interface{}) err
}
type InstallAction struct {
cfg *v1.RunConfig
cfg *v1.Config
spec *v1.InstallSpec
}
func NewInstallAction(cfg *v1.RunConfig, spec *v1.InstallSpec) *InstallAction {
func NewInstallAction(cfg *v1.Config, spec *v1.InstallSpec) *InstallAction {
return &InstallAction{cfg: cfg, spec: spec}
}
// InstallRun will install the system from a given configuration
func (i InstallAction) Run() (err error) {
e := elemental.NewElemental(&i.cfg.Config)
e := elemental.NewElemental(i.cfg)
cleanup := utils.NewCleanStack()
defer func() { err = cleanup.Cleanup(err) }()
@ -181,7 +181,7 @@ func (i InstallAction) Run() (err error) {
return err
}
// Install grub
grub := utils.NewGrub(&i.cfg.Config)
grub := utils.NewGrub(i.cfg)
err = grub.Install(
i.spec.Target,
i.spec.Active.MountPoint,
@ -197,14 +197,14 @@ func (i InstallAction) Run() (err error) {
// Relabel SELinux
binds := map[string]string{}
if mnt, _ := utils.IsMounted(&i.cfg.Config, i.spec.Partitions.Persistent); mnt {
if mnt, _ := utils.IsMounted(i.cfg, i.spec.Partitions.Persistent); mnt {
binds[i.spec.Partitions.Persistent.MountPoint] = cnst.UsrLocalPath
}
if mnt, _ := utils.IsMounted(&i.cfg.Config, i.spec.Partitions.OEM); mnt {
if mnt, _ := utils.IsMounted(i.cfg, i.spec.Partitions.OEM); mnt {
binds[i.spec.Partitions.OEM.MountPoint] = cnst.OEMPath
}
err = utils.ChrootedCallback(
&i.cfg.Config, i.spec.Active.MountPoint, binds, func() error { return e.SelinuxRelabel("/", true) },
i.cfg, i.spec.Active.MountPoint, binds, func() error { return e.SelinuxRelabel("/", true) },
)
if err != nil {
return err

View File

@ -42,7 +42,7 @@ const partTmpl = `
%d:%ss:%ss:2048s:ext4::type=83;`
var _ = Describe("Install action tests", func() {
var config *v1.RunConfig
var config *v1.Config
var runner *v1mock.FakeRunner
var fs vfs.FS
var logger v1.Logger
@ -69,7 +69,7 @@ var _ = Describe("Install action tests", func() {
Expect(err).Should(BeNil())
cloudInit = &v1mock.FakeCloudInitRunner{}
config = conf.NewRunConfig(
config = conf.NewConfig(
conf.WithFs(fs),
conf.WithRunner(runner),
conf.WithLogger(logger),
@ -146,7 +146,7 @@ var _ = Describe("Install action tests", func() {
err = utils.MkdirAll(fs, constants.IsoBaseTree, constants.DirPerm)
Expect(err).To(BeNil())
spec = conf.NewInstallSpec(config.Config)
spec = conf.NewInstallSpec(config)
spec.Active.Size = 16
grubCfg := filepath.Join(spec.Active.MountPoint, constants.GrubConf)

View File

@ -38,17 +38,17 @@ func (r *ResetAction) resetHook(hook string, chroot bool) error {
if oem != nil && oem.MountPoint != "" {
extraMounts[oem.MountPoint] = cnst.OEMPath
}
return ChrootHook(&r.cfg.Config, hook, r.cfg.Strict, r.spec.Active.MountPoint, extraMounts, r.cfg.CloudInitPaths...)
return ChrootHook(r.cfg, hook, r.spec.Active.MountPoint, extraMounts)
}
return Hook(&r.cfg.Config, hook, r.cfg.Strict, r.cfg.CloudInitPaths...)
return Hook(r.cfg, hook)
}
type ResetAction struct {
cfg *v1.RunConfig
cfg *v1.Config
spec *v1.ResetSpec
}
func NewResetAction(cfg *v1.RunConfig, spec *v1.ResetSpec) *ResetAction {
func NewResetAction(cfg *v1.Config, spec *v1.ResetSpec) *ResetAction {
return &ResetAction{cfg: cfg, spec: spec}
}
@ -108,7 +108,7 @@ func (r *ResetAction) updateInstallState(e *elemental.Elemental, cleanup *utils.
// ResetRun will reset the cos system to by following several steps
func (r ResetAction) Run() (err error) {
e := elemental.NewElemental(&r.cfg.Config)
e := elemental.NewElemental(r.cfg)
cleanup := utils.NewCleanStack()
defer func() { err = cleanup.Cleanup(err) }()
@ -168,7 +168,7 @@ func (r ResetAction) Run() (err error) {
cleanup.Push(func() error { return e.UnmountImage(&r.spec.Active) })
// install grub
grub := utils.NewGrub(&r.cfg.Config)
grub := utils.NewGrub(r.cfg)
err = grub.Install(
r.spec.Target,
r.spec.Active.MountPoint,
@ -186,14 +186,14 @@ func (r ResetAction) Run() (err error) {
// TODO probably relabelling persistent volumes should be an opt in feature, it could
// have undesired effects in case of failures
binds := map[string]string{}
if mnt, _ := utils.IsMounted(&r.cfg.Config, r.spec.Partitions.Persistent); mnt {
if mnt, _ := utils.IsMounted(r.cfg, r.spec.Partitions.Persistent); mnt {
binds[r.spec.Partitions.Persistent.MountPoint] = cnst.UsrLocalPath
}
if mnt, _ := utils.IsMounted(&r.cfg.Config, r.spec.Partitions.OEM); mnt {
if mnt, _ := utils.IsMounted(r.cfg, r.spec.Partitions.OEM); mnt {
binds[r.spec.Partitions.OEM.MountPoint] = cnst.OEMPath
}
err = utils.ChrootedCallback(
&r.cfg.Config, r.spec.Active.MountPoint, binds,
r.cfg, r.spec.Active.MountPoint, binds,
func() error { return e.SelinuxRelabel("/", true) },
)
if err != nil {

View File

@ -37,7 +37,7 @@ import (
)
var _ = Describe("Reset action tests", func() {
var config *v1.RunConfig
var config *v1.Config
var runner *v1mock.FakeRunner
var fs vfs.FS
var logger v1.Logger
@ -63,7 +63,7 @@ var _ = Describe("Reset action tests", func() {
Expect(err).Should(BeNil())
cloudInit = &v1mock.FakeCloudInitRunner{}
config = conf.NewRunConfig(
config = conf.NewConfig(
conf.WithFs(fs),
conf.WithRunner(runner),
conf.WithLogger(logger),
@ -140,7 +140,7 @@ var _ = Describe("Reset action tests", func() {
}
}
spec, err = conf.NewResetSpec(config.Config)
spec, err = conf.NewResetSpec(config)
Expect(err).ShouldNot(HaveOccurred())
Expect(spec.Active.Source.IsEmpty()).To(BeFalse())

View File

@ -29,11 +29,11 @@ import (
// UpgradeAction represents the struct that will run the upgrade from start to finish
type UpgradeAction struct {
config *v1.RunConfig
config *v1.Config
spec *v1.UpgradeSpec
}
func NewUpgradeAction(config *v1.RunConfig, spec *v1.UpgradeSpec) *UpgradeAction {
func NewUpgradeAction(config *v1.Config, spec *v1.UpgradeSpec) *UpgradeAction {
return &UpgradeAction{config: config, spec: spec}
}
@ -52,21 +52,21 @@ func (u UpgradeAction) Error(s string, args ...interface{}) {
func (u UpgradeAction) upgradeHook(hook string, chroot bool) error {
u.Info("Applying '%s' hook", hook)
if chroot {
mountPoints := map[string]string{}
extraMounts := map[string]string{}
oemDevice := u.spec.Partitions.OEM
if oemDevice != nil && oemDevice.MountPoint != "" {
mountPoints[oemDevice.MountPoint] = constants.OEMPath
extraMounts[oemDevice.MountPoint] = constants.OEMPath
}
persistentDevice := u.spec.Partitions.Persistent
if persistentDevice != nil && persistentDevice.MountPoint != "" {
mountPoints[persistentDevice.MountPoint] = constants.UsrLocalPath
extraMounts[persistentDevice.MountPoint] = constants.UsrLocalPath
}
return ChrootHook(&u.config.Config, hook, u.config.Strict, u.spec.Active.MountPoint, mountPoints, u.config.CloudInitPaths...)
return ChrootHook(u.config, hook, u.spec.Active.MountPoint, extraMounts)
}
return Hook(&u.config.Config, hook, u.config.Strict, u.config.CloudInitPaths...)
return Hook(u.config, hook)
}
func (u *UpgradeAction) upgradeInstallStateYaml(meta interface{}, img v1.Image) error {
@ -122,7 +122,7 @@ func (u *UpgradeAction) Run() (err error) {
cleanup := utils.NewCleanStack()
defer func() { err = cleanup.Cleanup(err) }()
e := elemental.NewElemental(&u.config.Config)
e := elemental.NewElemental(u.config)
if u.spec.RecoveryUpgrade {
upgradeImg = u.spec.Recovery
@ -155,7 +155,7 @@ func (u *UpgradeAction) Run() (err error) {
if persistentPart != nil {
// Create the dir otherwise the check for mounted dir fails
_ = utils.MkdirAll(u.config.Fs, persistentPart.MountPoint, constants.DirPerm)
if mnt, err := utils.IsMounted(&u.config.Config, persistentPart); !mnt && err == nil {
if mnt, err := utils.IsMounted(u.config, persistentPart); !mnt && err == nil {
u.Debug("mounting persistent partition")
umount, err = e.MountRWPartition(persistentPart)
if err != nil {
@ -186,14 +186,14 @@ func (u *UpgradeAction) Run() (err error) {
// TODO probably relabelling persistent volumes should be an opt in feature, it could
// have undesired effects in case of failures
binds := map[string]string{}
if mnt, _ := utils.IsMounted(&u.config.Config, u.spec.Partitions.Persistent); mnt {
if mnt, _ := utils.IsMounted(u.config, u.spec.Partitions.Persistent); mnt {
binds[u.spec.Partitions.Persistent.MountPoint] = constants.UsrLocalPath
}
if mnt, _ := utils.IsMounted(&u.config.Config, u.spec.Partitions.OEM); mnt {
if mnt, _ := utils.IsMounted(u.config, u.spec.Partitions.OEM); mnt {
binds[u.spec.Partitions.OEM.MountPoint] = constants.OEMPath
}
err = utils.ChrootedCallback(
&u.config.Config, upgradeImg.MountPoint, binds,
u.config, upgradeImg.MountPoint, binds,
func() error { return e.SelinuxRelabel("/", true) },
)
if err != nil {

View File

@ -36,7 +36,7 @@ import (
)
var _ = Describe("Runtime Actions", func() {
var config *v1.RunConfig
var config *v1.Config
var runner *v1mock.FakeRunner
var fs vfs.FS
var logger v1.Logger
@ -63,7 +63,7 @@ var _ = Describe("Runtime Actions", func() {
Expect(err).Should(BeNil())
cloudInit = &v1mock.FakeCloudInitRunner{}
config = conf.NewRunConfig(
config = conf.NewConfig(
conf.WithFs(fs),
conf.WithRunner(runner),
conf.WithLogger(logger),
@ -143,7 +143,7 @@ var _ = Describe("Runtime Actions", func() {
Describe(fmt.Sprintf("Booting from %s", constants.ActiveLabel), Label("active_label"), func() {
var err error
BeforeEach(func() {
spec, err = conf.NewUpgradeSpec(config.Config)
spec, err = conf.NewUpgradeSpec(config)
Expect(err).ShouldNot(HaveOccurred())
err = utils.MkdirAll(config.Fs, filepath.Join(spec.Active.MountPoint, "etc"), constants.DirPerm)
@ -346,7 +346,7 @@ var _ = Describe("Runtime Actions", func() {
Describe(fmt.Sprintf("Booting from %s", constants.PassiveLabel), Label("passive_label"), func() {
var err error
BeforeEach(func() {
spec, err = conf.NewUpgradeSpec(config.Config)
spec, err = conf.NewUpgradeSpec(config)
Expect(err).ShouldNot(HaveOccurred())
err = utils.MkdirAll(config.Fs, filepath.Join(spec.Active.MountPoint, "etc"), constants.DirPerm)
@ -428,7 +428,7 @@ var _ = Describe("Runtime Actions", func() {
err = fs.WriteFile(recoveryImgSquash, []byte("recovery"), constants.FilePerm)
Expect(err).ShouldNot(HaveOccurred())
spec, err = conf.NewUpgradeSpec(config.Config)
spec, err = conf.NewUpgradeSpec(config)
Expect(err).ShouldNot(HaveOccurred())
spec.Active.Size = 10
spec.Passive.Size = 10
@ -513,7 +513,7 @@ var _ = Describe("Runtime Actions", func() {
err = fs.WriteFile(recoveryImg, []byte("recovery"), constants.FilePerm)
Expect(err).ShouldNot(HaveOccurred())
spec, err = conf.NewUpgradeSpec(config.Config)
spec, err = conf.NewUpgradeSpec(config)
Expect(err).ShouldNot(HaveOccurred())
spec.Active.Size = 10

View File

@ -522,7 +522,7 @@ func (e Elemental) UpdateSourcesFormDownloadedISO(workDir string, activeImg *v1.
return nil
}
// SetDefaultGrubEntry Sets the default_meny_entry value in RunConfig.GrubOEMEnv file at in
// SetDefaultGrubEntry Sets the default_meny_entry value in Config.GrubOEMEnv file at in
// State partition mountpoint. If there is not a custom value in the os-release file, we do nothing
// As the grub config already has a sane default
func (e Elemental) SetDefaultGrubEntry(partMountPoint string, imgMountPoint string, defaultEntry string) error {

View File

@ -341,7 +341,7 @@ var _ = Describe("Elemental", Label("elemental"), func() {
cInit = &v1mock.FakeCloudInitRunner{ExecStages: []string{}, Error: false}
config.CloudInitRunner = cInit
el = elemental.NewElemental(config)
install = conf.NewInstallSpec(*config)
install = conf.NewInstallSpec(config)
install.Target = "/some/device"
err := utils.MkdirAll(fs, "/some", cnst.DirPerm)

View File

@ -138,7 +138,7 @@ func NewConfig(opts ...GenericOptions) *v1.Config {
}
// Delay the yip runner creation, so we set the proper logger instead of blindly setting it to the logger we create
// at the start of NewRunConfig, as WithLogger can be passed on init, and that would result in 2 different logger
// at the start of NewConfig, as WithLogger can be passed on init, and that would result in 2 different logger
// instances, on the config.Logger and the other on config.CloudInitRunner
if c.CloudInitRunner == nil {
c.CloudInitRunner = cloudinit.NewYipCloudInitRunner(c.Logger, c.Runner, vfs.OSFS)
@ -151,16 +151,8 @@ func NewConfig(opts ...GenericOptions) *v1.Config {
return c
}
func NewRunConfig(opts ...GenericOptions) *v1.RunConfig {
config := NewConfig(opts...)
r := &v1.RunConfig{
Config: *config,
}
return r
}
// NewInstallSpec returns an InstallSpec struct all based on defaults and basic host checks (e.g. EFI vs BIOS)
func NewInstallSpec(cfg v1.Config) *v1.InstallSpec {
func NewInstallSpec(cfg *v1.Config) *v1.InstallSpec {
var firmware string
var recoveryImg, activeImg, passiveImg v1.Image
@ -264,7 +256,7 @@ func NewInstallElementalParitions() v1.ElementalPartitions {
}
// NewUpgradeSpec returns an UpgradeSpec struct all based on defaults and current host state
func NewUpgradeSpec(cfg v1.Config) (*v1.UpgradeSpec, error) {
func NewUpgradeSpec(cfg *v1.Config) (*v1.UpgradeSpec, error) {
var recLabel, recFs, recMnt string
var active, passive, recovery v1.Image
@ -299,7 +291,7 @@ func NewUpgradeSpec(cfg v1.Config) (*v1.UpgradeSpec, error) {
ep.Recovery.MountPoint = constants.RecoveryDir
}
squashedRec, err := utils.HasSquashedRecovery(&cfg, ep.Recovery)
squashedRec, err := utils.HasSquashedRecovery(cfg, ep.Recovery)
if err != nil {
return nil, fmt.Errorf("failed checking for squashed recovery")
}
@ -369,7 +361,7 @@ func NewUpgradeSpec(cfg v1.Config) (*v1.UpgradeSpec, error) {
}
// NewResetSpec returns a ResetSpec struct all based on defaults and current host state
func NewResetSpec(cfg v1.Config) (*v1.ResetSpec, error) {
func NewResetSpec(cfg *v1.Config) (*v1.ResetSpec, error) {
var imgSource *v1.ImageSource
//TODO find a way to pre-load current state values such as labels
@ -493,8 +485,8 @@ func NewResetSpec(cfg v1.Config) (*v1.ResetSpec, 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()), WithImageExtractor(v1.OCIImageExtractor{}))
func ReadConfigRunFromAgentConfig(c *agentConfig.Config) (*v1.Config, error) {
cfg := NewConfig(WithLogger(v1.NewLogger()), WithImageExtractor(v1.OCIImageExtractor{}))
var err error
ccString, err := c.Config.String()
@ -520,17 +512,17 @@ func ReadConfigRunFromAgentConfig(c *agentConfig.Config) (*v1.RunConfig, error)
}
// ReadSpecFromCloudConfig returns a v1.Spec for the given spec
func ReadSpecFromCloudConfig(r *v1.RunConfig, spec string) (v1.Spec, error) {
func ReadSpecFromCloudConfig(r *v1.Config, spec string) (v1.Spec, error) {
var sp v1.Spec
var err error
switch spec {
case "install":
sp = NewInstallSpec(r.Config)
sp = NewInstallSpec(r)
case "upgrade":
sp, err = NewUpgradeSpec(r.Config)
sp, err = NewUpgradeSpec(r)
case "reset":
sp, err = NewResetSpec(r.Config)
sp, err = NewResetSpec(r)
default:
return nil, fmt.Errorf("spec not valid: %s", spec)
}
@ -555,20 +547,20 @@ func ReadSpecFromCloudConfig(r *v1.RunConfig, spec string) (v1.Spec, error) {
}
// 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)
func readConfigAndSpecFromAgentConfig(c *agentConfig.Config, action string) (*v1.Config, v1.Spec, error) {
config, err := ReadConfigRunFromAgentConfig(c)
if err != nil {
return nil, nil, err
}
spec, err := ReadSpecFromCloudConfig(runConfig, action)
spec, err := ReadSpecFromCloudConfig(config, action)
if err != nil {
return nil, nil, err
}
return runConfig, spec, nil
return config, 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) {
// ReadResetConfigFromAgentConfig will return a proper v1.Config and v1.ResetSpec based on an agent Config
func ReadResetConfigFromAgentConfig(c *agentConfig.Config) (*v1.Config, *v1.ResetSpec, error) {
config, spec, err := readConfigAndSpecFromAgentConfig(c, "reset")
if err != nil {
return nil, nil, err
@ -577,7 +569,7 @@ func ReadResetConfigFromAgentConfig(c *agentConfig.Config) (*v1.RunConfig, *v1.R
return config, resetSpec, nil
}
func ReadInstallConfigFromAgentConfig(c *agentConfig.Config) (*v1.RunConfig, *v1.InstallSpec, error) {
func ReadInstallConfigFromAgentConfig(c *agentConfig.Config) (*v1.Config, *v1.InstallSpec, error) {
config, spec, err := readConfigAndSpecFromAgentConfig(c, "install")
if err != nil {
return nil, nil, err
@ -586,7 +578,7 @@ func ReadInstallConfigFromAgentConfig(c *agentConfig.Config) (*v1.RunConfig, *v1
return config, installSpec, nil
}
func ReadUpgradeConfigFromAgentConfig(c *agentConfig.Config) (*v1.RunConfig, *v1.UpgradeSpec, error) {
func ReadUpgradeConfigFromAgentConfig(c *agentConfig.Config) (*v1.Config, *v1.UpgradeSpec, error) {
config, spec, err := readConfigAndSpecFromAgentConfig(c, "upgrade")
if err != nil {
return nil, nil, err

View File

@ -124,8 +124,8 @@ var _ = Describe("Types", Label("types", "config"), func() {
Expect(c.Mounter).To(Equal(mount.New(constants.MountBinary)))
})
})
Describe("RunConfig", func() {
cfg := elementalConfig.NewRunConfig(elementalConfig.WithMounter(mounter))
Describe("Config", func() {
cfg := elementalConfig.NewConfig(elementalConfig.WithMounter(mounter))
Expect(cfg.Mounter).To(Equal(mounter))
Expect(cfg.Runner).NotTo(BeNil())
})
@ -150,7 +150,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
_, err = fs.Create(recoveryImgFile)
Expect(err).ShouldNot(HaveOccurred())
spec := elementalConfig.NewInstallSpec(*c)
spec := elementalConfig.NewInstallSpec(c)
Expect(spec.Firmware).To(Equal(v1.EFI))
Expect(spec.Active.Source.Value()).To(Equal(constants.IsoBaseTree))
Expect(spec.Recovery.Source.Value()).To(Equal(recoveryImgFile))
@ -171,7 +171,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
_, err = fs.Create(constants.IsoBaseTree)
Expect(err).ShouldNot(HaveOccurred())
spec := elementalConfig.NewInstallSpec(*c)
spec := elementalConfig.NewInstallSpec(c)
Expect(spec.Firmware).To(Equal(v1.BIOS))
Expect(spec.Active.Source.Value()).To(Equal(constants.IsoBaseTree))
Expect(spec.Recovery.Source.Value()).To(Equal(spec.Active.File))
@ -186,7 +186,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
Expect(spec.Partitions.BIOS).NotTo(BeNil())
})
It("sets installation defaults without being on installation media", Label("install"), func() {
spec := elementalConfig.NewInstallSpec(*c)
spec := elementalConfig.NewInstallSpec(c)
Expect(spec.Firmware).To(Equal(v1.BIOS))
Expect(spec.Active.Source.IsEmpty()).To(BeTrue())
Expect(spec.Recovery.Source.Value()).To(Equal(spec.Active.File))
@ -256,7 +256,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
_, err = fs.Create(constants.IsoBaseTree)
Expect(err).ShouldNot(HaveOccurred())
spec, err := elementalConfig.NewResetSpec(*c)
spec, err := elementalConfig.NewResetSpec(c)
Expect(err).ShouldNot(HaveOccurred())
Expect(spec.Active.Source.Value()).To(Equal(constants.IsoBaseTree))
Expect(spec.Partitions.EFI.MountPoint).To(Equal(constants.EfiDir))
@ -269,12 +269,12 @@ var _ = Describe("Types", Label("types", "config"), func() {
_, err = fs.Create(recoveryImg)
Expect(err).ShouldNot(HaveOccurred())
spec, err := elementalConfig.NewResetSpec(*c)
spec, err := elementalConfig.NewResetSpec(c)
Expect(err).ShouldNot(HaveOccurred())
Expect(spec.Active.Source.Value()).To(Equal(recoveryImg))
})
It("sets reset defaults on bios from unknown recovery", func() {
spec, err := elementalConfig.NewResetSpec(*c)
spec, err := elementalConfig.NewResetSpec(c)
Expect(err).ShouldNot(HaveOccurred())
Expect(spec.Active.Source.IsEmpty()).To(BeTrue())
})
@ -312,13 +312,13 @@ var _ = Describe("Types", Label("types", "config"), func() {
ghwTest.Clean()
})
It("fails to set defaults if not booted from recovery", func() {
_, err := elementalConfig.NewResetSpec(*c)
_, err := elementalConfig.NewResetSpec(c)
Expect(err).Should(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("reset can only be called from the recovery system"))
})
It("fails to set defaults if no recovery partition detected", func() {
bootedFrom = constants.SystemLabel
_, err := elementalConfig.NewResetSpec(*c)
_, err := elementalConfig.NewResetSpec(c)
Expect(err).Should(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("recovery partition not found"))
})
@ -333,7 +333,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
defer ghwTest.Clean()
bootedFrom = constants.SystemLabel
_, err := elementalConfig.NewResetSpec(*c)
_, err := elementalConfig.NewResetSpec(c)
Expect(err).Should(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("state partition not found"))
})
@ -345,7 +345,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
Expect(err).ShouldNot(HaveOccurred())
bootedFrom = constants.SystemLabel
_, err := elementalConfig.NewResetSpec(*c)
_, err := elementalConfig.NewResetSpec(c)
Expect(err).Should(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("EFI partition not found"))
})
@ -394,12 +394,12 @@ var _ = Describe("Types", Label("types", "config"), func() {
ghwTest.Clean()
})
It("sets upgrade defaults for active upgrade", func() {
spec, err := elementalConfig.NewUpgradeSpec(*c)
spec, err := elementalConfig.NewUpgradeSpec(c)
Expect(err).ShouldNot(HaveOccurred())
Expect(spec.Active.Source.IsEmpty()).To(BeTrue())
})
It("sets upgrade defaults for non-squashed recovery upgrade", func() {
spec, err := elementalConfig.NewUpgradeSpec(*c)
spec, err := elementalConfig.NewUpgradeSpec(c)
Expect(err).ShouldNot(HaveOccurred())
Expect(spec.Recovery.Source.IsEmpty()).To(BeTrue())
Expect(spec.Recovery.FS).To(Equal(constants.LinuxImgFs))
@ -413,7 +413,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
_, err = fs.Create(img)
Expect(err).ShouldNot(HaveOccurred())
spec, err := elementalConfig.NewUpgradeSpec(*c)
spec, err := elementalConfig.NewUpgradeSpec(c)
Expect(err).ShouldNot(HaveOccurred())
Expect(spec.Recovery.Source.IsEmpty()).To(BeTrue())
Expect(spec.Recovery.FS).To(Equal(constants.SquashFs))
@ -512,14 +512,14 @@ cloud-init-paths:
It("Reads properly the cloud config for reset", func() {
bootedFrom = constants.SystemLabel
cfg, err := config.Scan(collector.Directories([]string{dir}...), collector.NoLogs)
runconfig, err := elementalConfig.ReadConfigRunFromAgentConfig(cfg)
config, err := elementalConfig.ReadConfigRunFromAgentConfig(cfg)
Expect(err).ToNot(HaveOccurred())
// Override the runconfig with our test params
runconfig.Runner = runner
runconfig.Fs = fs
runconfig.Mounter = mounter
runconfig.CloudInitRunner = ci
spec, err := elementalConfig.ReadSpecFromCloudConfig(runconfig, "reset")
// Override the config with our test params
config.Runner = runner
config.Fs = fs
config.Mounter = mounter
config.CloudInitRunner = ci
spec, err := elementalConfig.ReadSpecFromCloudConfig(config, "reset")
Expect(err).ToNot(HaveOccurred())
resetSpec := spec.(*v1.ResetSpec)
Expect(resetSpec.FormatPersistent).To(BeTrue())
@ -528,23 +528,23 @@ cloud-init-paths:
})
It("Reads properly the cloud config for upgrade", func() {
cfg, err := config.Scan(collector.Directories([]string{dir}...), collector.NoLogs)
runconfig, err := elementalConfig.ReadConfigRunFromAgentConfig(cfg)
config, err := elementalConfig.ReadConfigRunFromAgentConfig(cfg)
Expect(err).ToNot(HaveOccurred())
// Override the runconfig with our test params
runconfig.Runner = runner
runconfig.Fs = fs
runconfig.Mounter = mounter
runconfig.CloudInitRunner = ci
spec, err := elementalConfig.ReadSpecFromCloudConfig(runconfig, "upgrade")
// Override the config with our test params
config.Runner = runner
config.Fs = fs
config.Mounter = mounter
config.CloudInitRunner = ci
spec, err := elementalConfig.ReadSpecFromCloudConfig(config, "upgrade")
Expect(err).ToNot(HaveOccurred())
upgradeSpec := spec.(*v1.UpgradeSpec)
Expect(upgradeSpec.RecoveryUpgrade).To(BeTrue())
})
It("Fails when a wrong action is read", func() {
cfg, err := config.Scan(collector.Directories([]string{dir}...), collector.NoLogs)
runconfig, err := elementalConfig.ReadConfigRunFromAgentConfig(cfg)
config, err := elementalConfig.ReadConfigRunFromAgentConfig(cfg)
Expect(err).ToNot(HaveOccurred())
_, err = elementalConfig.ReadSpecFromCloudConfig(runconfig, "nope")
_, err = elementalConfig.ReadSpecFromCloudConfig(config, "nope")
Expect(err).To(HaveOccurred())
})
It("Sets info level if its not on the cloud-config", func() {

View File

@ -46,6 +46,11 @@ type Spec interface {
// Config is the struct that includes basic and generic configuration of elemental binary runtime.
// It mostly includes the interfaces used around many methods in elemental code
type Config struct {
Debug bool `yaml:"debug,omitempty" mapstructure:"debug"`
Strict bool `yaml:"strict,omitempty" mapstructure:"strict"`
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
Logger Logger
Fs FS
Mounter mount.Interface
@ -126,24 +131,6 @@ func (c *Config) Sanitize() error {
return nil
}
type RunConfig struct {
Debug bool `yaml:"debug,omitempty" mapstructure:"debug"`
Strict bool `yaml:"strict,omitempty" mapstructure:"strict"`
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
Config `yaml:",inline" mapstructure:",squash"`
}
// Sanitize checks the consistency of the struct, returns error
// if unsolvable inconsistencies are found
func (r *RunConfig) Sanitize() error {
return r.Config.Sanitize()
}
// InstallSpec struct represents all the installation action details
type InstallSpec struct {
Target string `yaml:"device,omitempty" mapstructure:"device"`

View File

@ -33,7 +33,7 @@ import (
var _ = Describe("Types", Label("types", "config"), func() {
Describe("Write and load installation state", func() {
var config *v1.RunConfig
var config *v1.Config
var runner *v1mocks.FakeRunner
var fs vfs.FS
var mounter *v1mocks.ErrorMounter
@ -49,7 +49,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
fs, cleanup, err = vfst.NewTestFS(map[string]interface{}{})
Expect(err).Should(BeNil())
config = conf.NewRunConfig(
config = conf.NewConfig(
conf.WithFs(fs),
conf.WithRunner(runner),
conf.WithMounter(mounter),
@ -319,10 +319,10 @@ var _ = Describe("Types", Label("types", "config"), func() {
Expect(p.GetByName("nonexistent")).To(BeNil())
})
})
Describe("RunConfig", func() {
Describe("Config", func() {
It("runs sanitize method", func() {
cfg := elementalConfig.NewRunConfig(elementalConfig.WithMounter(v1mocks.NewErrorMounter()))
cfg.Config.Verify = true
cfg := elementalConfig.NewConfig(elementalConfig.WithMounter(v1mocks.NewErrorMounter()))
cfg.Verify = true
err := cfg.Sanitize()
Expect(err).ShouldNot(HaveOccurred())
@ -333,7 +333,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
BeforeEach(func() {
cfg := elementalConfig.NewConfig(elementalConfig.WithMounter(v1mocks.NewErrorMounter()))
spec = elementalConfig.NewInstallSpec(*cfg)
spec = elementalConfig.NewInstallSpec(cfg)
})
Describe("sanitize", func() {
It("runs method", func() {

View File

@ -57,11 +57,12 @@ func checkYAMLError(cfg *v1.Config, allErrors, err error) error {
}
// RunStage will run yip
func RunStage(cfg *v1.Config, stage string, strict bool, cloudInitPaths ...string) error {
func RunStage(cfg *v1.Config, stage string) error {
var cmdLineYipURI string
var allErrors error
var cloudInitPaths []string
cloudInitPaths = append(constants.GetCloudInitPaths(), cloudInitPaths...)
cloudInitPaths = append(constants.GetCloudInitPaths(), cfg.CloudInitPaths...)
cfg.Logger.Debugf("Cloud-init paths set to %v", cloudInitPaths)
// Make sure cloud init path specified are existing in the system
@ -126,7 +127,7 @@ func RunStage(cfg *v1.Config, stage string, strict bool, cloudInitPaths ...strin
// We return error here only if we have been running in strict mode.
// Cloud configs are being loaded and executed on a best-effort, so every step/config
// gets a chance to be executed and error is being appended and reported.
if allErrors != nil && !strict {
if allErrors != nil && !cfg.Strict {
cfg.Logger.Info("Some errors found but were ignored. Enable --strict mode to fail on those or --debug to see them in the log")
cfg.Logger.Warn(allErrors)
return nil

View File

@ -51,10 +51,8 @@ var _ = Describe("run stage", Label("RunStage"), func() {
var memLog *bytes.Buffer
var cleanup func()
var strict bool
BeforeEach(func() {
strict = false
runner = v1mock.NewFakeRunner()
// Use a different config with a buffer for logger, so we can check the output
// We also use the real fs
@ -80,15 +78,15 @@ var _ = Describe("run stage", Label("RunStage"), func() {
d, err := utils.TempDir(fs, "", "elemental")
Expect(err).ToNot(HaveOccurred())
_ = fs.WriteFile(fmt.Sprintf("%s/test.yaml", d), []byte("stages: [foo,bar]"), os.ModePerm)
strict = true
Expect(utils.RunStage(config, "c3po", strict, d)).ToNot(BeNil())
config.Strict = true
Expect(utils.RunStage(config, "c3po")).ToNot(BeNil())
})
It("does not fail but prints errors by default", Label("strict"), func() {
writeCmdline("stages.c3po[0].datasource", fs)
config.Logger.SetLevel(log.DebugLevel)
out := utils.RunStage(config, "c3po", strict)
out := utils.RunStage(config, "c3po")
Expect(out).To(BeNil())
Expect(memLog.String()).To(ContainSubstring("parsing returned errors"))
})
@ -97,8 +95,9 @@ var _ = Describe("run stage", Label("RunStage"), func() {
d, err := utils.TempDir(fs, "", "elemental")
Expect(err).ToNot(HaveOccurred())
config.Logger.SetLevel(log.DebugLevel)
config.CloudInitPaths = []string{d}
Expect(utils.RunStage(config, "luke", strict, d)).To(BeNil())
Expect(utils.RunStage(config, "luke")).To(BeNil())
Expect(memLog.String()).To(ContainSubstring(d))
Expect(memLog).To(ContainSubstring("luke"))
Expect(memLog).To(ContainSubstring("luke.before"))
@ -111,7 +110,7 @@ var _ = Describe("run stage", Label("RunStage"), func() {
writeCmdline(fmt.Sprintf("cos.setup=%s/test.yaml", d), fs)
Expect(utils.RunStage(config, "padme", strict)).To(BeNil())
Expect(utils.RunStage(config, "padme")).To(BeNil())
Expect(memLog).To(ContainSubstring("padme"))
Expect(memLog).To(ContainSubstring(fmt.Sprintf("%s/test.yaml", d)))
})
@ -119,13 +118,13 @@ var _ = Describe("run stage", Label("RunStage"), func() {
It("parses cmdline uri with dotnotation", func() {
writeCmdline("stages.leia[0].commands[0]='echo beepboop'", fs)
config.Logger.SetLevel(log.DebugLevel)
Expect(utils.RunStage(config, "leia", strict)).To(BeNil())
Expect(utils.RunStage(config, "leia")).To(BeNil())
Expect(memLog).To(ContainSubstring("leia"))
Expect(memLog).To(ContainSubstring("running command `echo beepboop`"))
// try with a non-clean cmdline
writeCmdline("BOOT=death-star single stages.leia[0].commands[0]='echo beepboop'", fs)
Expect(utils.RunStage(config, "leia", strict)).To(BeNil())
Expect(utils.RunStage(config, "leia")).To(BeNil())
Expect(memLog).To(ContainSubstring("leia"))
Expect(memLog).To(ContainSubstring("running command `echo beepboop`"))
Expect(memLog.String()).ToNot(ContainSubstring("/proc/cmdline parsing returned errors while unmarshalling"))
@ -135,7 +134,7 @@ var _ = Describe("run stage", Label("RunStage"), func() {
It("ignores YAML errors", func() {
config.Logger.SetLevel(log.DebugLevel)
writeCmdline("BOOT=death-star sing1!~@$%6^&**le /varlib stag_#var<Lib stages[0]='utterly broken by breaking schema'", fs)
Expect(utils.RunStage(config, "leia", strict)).To(BeNil())
Expect(utils.RunStage(config, "leia")).To(BeNil())
Expect(memLog.String()).To(ContainSubstring("/proc/cmdline parsing returned errors while unmarshalling"))
Expect(memLog.String()).ToNot(ContainSubstring("Some errors found but were ignored. Enable --strict mode to fail on those or --debug to see them in the log"))
})