From bdb073ad10e6f20b5141806dae8a02c51e61b45c Mon Sep 17 00:00:00 2001 From: David Cassany Date: Tue, 27 Feb 2024 07:24:33 +0100 Subject: [PATCH] Adding snapshotter.type flag install command Signed-off-by: David Cassany --- cmd/config/config_test.go | 20 ++++++++++++++++---- cmd/config/fixtures/config/config.yaml | 1 - cmd/install.go | 5 +++++ pkg/config/config.go | 16 ++++------------ pkg/config/config_test.go | 2 +- pkg/constants/constants.go | 12 +++++++----- pkg/snapshotter/loopdevice_test.go | 6 +----- pkg/types/v1/config.go | 6 +----- pkg/types/v1/snapshotter.go | 20 ++++++++++++++++++++ 9 files changed, 55 insertions(+), 33 deletions(-) diff --git a/cmd/config/config_test.go b/cmd/config/config_test.go index 36a49a85455..1f74622e5a2 100644 --- a/cmd/config/config_test.go +++ b/cmd/config/config_test.go @@ -247,18 +247,30 @@ var _ = Describe("Config", Label("config"), func() { Expect(debug).To(BeTrue()) Expect(cfg.Logger.GetLevel()).To(Equal(logrus.DebugLevel)) }) - It("reads the snaphotter configuration", func() { - // Default value + It("reads the snaphotter configuration and environment variables", func() { + err := os.Setenv("ELEMENTAL_REBOOT", "true") + Expect(err).ShouldNot(HaveOccurred()) + cfg, err := ReadConfigRun("fixtures/config/", nil, mounter) Expect(err).ShouldNot(HaveOccurred()) - Expect(err).To(BeNil()) + Expect(cfg.Reboot).To(BeTrue()) Expect(cfg.Snapshotter.Type).To(Equal(constants.LoopDeviceSnapshotterType)) - Expect(cfg.Snapshotter.MaxSnaps).To(Equal(7)) + Expect(cfg.Snapshotter.MaxSnaps).To(Equal(constants.LoopDeviceMaxSnaps)) snapshooterCfg, ok := cfg.Snapshotter.Config.(*v1.LoopDeviceConfig) Expect(ok).To(BeTrue()) Expect(snapshooterCfg.FS).To(Equal("xfs")) Expect(snapshooterCfg.Size).To(Equal(uint(1024))) + + // Reads snapshotter type from env vars + err = os.Setenv("ELEMENTAL_SNAPSHOTTER_TYPE", "btrfs") + Expect(err).ShouldNot(HaveOccurred()) + + cfg, err = ReadConfigRun("fixtures/config/", nil, mounter) + Expect(err).ShouldNot(HaveOccurred()) + + Expect(cfg.Snapshotter.Type).To(Equal(constants.BtrfsSnapshotterType)) + Expect(cfg.Snapshotter.MaxSnaps).To(Equal(constants.BtrfsMaxSnaps)) }) }) Describe("Read runtime specs", Label("spec"), func() { diff --git a/cmd/config/fixtures/config/config.yaml b/cmd/config/fixtures/config/config.yaml index 46b89982af0..87186ca5894 100644 --- a/cmd/config/fixtures/config/config.yaml +++ b/cmd/config/fixtures/config/config.yaml @@ -21,7 +21,6 @@ upgrade: snapshotter: type: loopdevice - max-snaps: 7 config: fs: xfs size: 1024 diff --git a/cmd/install.go b/cmd/install.go index acdf140bde0..fe934963ea5 100644 --- a/cmd/install.go +++ b/cmd/install.go @@ -95,6 +95,10 @@ func NewInstallCmd(root *cobra.Command, addCheckRoot bool) *cobra.Command { } firmType := newEnumFlag([]string{v1.EFI}, v1.EFI) pTableType := newEnumFlag([]string{v1.GPT}, v1.GPT) + snapshotterType := newEnumFlag( + []string{constants.LoopDeviceSnapshotterType, constants.BtrfsSnapshotterType}, + constants.LoopDeviceSnapshotterType, + ) root.AddCommand(c) c.Flags().StringSliceP("cloud-init", "c", []string{}, "Cloud-init config files") @@ -110,6 +114,7 @@ func NewInstallCmd(root *cobra.Command, addCheckRoot bool) *cobra.Command { c.Flags().Bool("force", false, "Force install") c.Flags().Bool("eject-cd", false, "Try to eject the cd on reboot, only valid if booting from iso") c.Flags().Bool("disable-boot-entry", false, "Dont create an EFI entry for the system install.") + c.Flags().Var(snapshotterType, "snapshotter.type", "Sets the snapshotter type to install") addSharedInstallUpgradeFlags(c) addLocalImageFlag(c) addPlatformFlags(c) diff --git a/pkg/config/config.go b/pkg/config/config.go index ff56f891509..c0a4f86d747 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -163,11 +163,7 @@ func NewConfig(opts ...GenericOptions) *v1.Config { func NewRunConfig(opts ...GenericOptions) *v1.RunConfig { config := NewConfig(opts...) - snapshotter := v1.SnapshotterConfig{ - Type: constants.LoopDeviceSnapshotterType, - MaxSnaps: constants.MaxSnaps, - Config: v1.NewLoopDeviceConfig(), - } + snapshotter := v1.NewLoopDevice() // Load snapshotter setup from state.yaml for reset and upgrade installState, _ := config.LoadInstallState() @@ -550,13 +546,9 @@ func NewISO() *v1.LiveISO { func NewBuildConfig(opts ...GenericOptions) *v1.BuildConfig { b := &v1.BuildConfig{ - Config: *NewConfig(opts...), - Name: constants.BuildImgName, - Snapshotter: v1.SnapshotterConfig{ - Type: constants.LoopDeviceSnapshotterType, - MaxSnaps: constants.MaxSnaps, - Config: v1.NewLoopDeviceConfig(), - }, + Config: *NewConfig(opts...), + Name: constants.BuildImgName, + Snapshotter: v1.NewLoopDevice(), } return b } diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 4e18769eeaa..80c0887598c 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -106,7 +106,7 @@ var _ = Describe("Types", Label("types", "config"), func() { Expect(cfg.Mounter).To(Equal(mounter)) Expect(cfg.Runner).NotTo(BeNil()) It("sets the default snapshot", func() { - Expect(cfg.Snapshotter.MaxSnaps).To(Equal(constants.MaxSnaps)) + Expect(cfg.Snapshotter.MaxSnaps).To(Equal(constants.LoopDeviceMaxSnaps)) Expect(cfg.Snapshotter.Type).To(Equal(constants.LoopDeviceSnapshotterType)) snapshotterCfg, ok := cfg.Snapshotter.Config.(*v1.LoopDeviceConfig) Expect(ok).To(BeTrue()) diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 1198909e947..085b1c40bbc 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -172,7 +172,8 @@ const ( Rsync = "rsync" // Snapshotters - MaxSnaps = 2 + LoopDeviceMaxSnaps = 2 + BtrfsMaxSnaps = 4 LoopDeviceSnapshotterType = "loopdevice" BtrfsSnapshotterType = "btrfs" ActiveSnapshot = "active" @@ -279,10 +280,11 @@ func GetDefaultSquashfsCompressionOptions() []string { // GetRunKeyEnvMap returns environment variable bindings to RunConfig data func GetRunKeyEnvMap() map[string]string { return map[string]string{ - "poweroff": "POWEROFF", - "reboot": "REBOOT", - "strict": "STRICT", - "eject-cd": "EJECT_CD", + "poweroff": "POWEROFF", + "reboot": "REBOOT", + "strict": "STRICT", + "eject-cd": "EJECT_CD", + "snapshotter.type": "SNAPSHOTTER_TYPE", } } diff --git a/pkg/snapshotter/loopdevice_test.go b/pkg/snapshotter/loopdevice_test.go index 95741fb104a..11d1816929f 100644 --- a/pkg/snapshotter/loopdevice_test.go +++ b/pkg/snapshotter/loopdevice_test.go @@ -71,11 +71,7 @@ var _ = Describe("LoopDevice", Label("snapshotter", "loopdevice"), func() { conf.WithMounter(mounter), conf.WithPlatform("linux/amd64"), ) - snapCfg = v1.SnapshotterConfig{ - Type: constants.LoopDeviceSnapshotterType, - MaxSnaps: constants.MaxSnaps, - Config: v1.NewLoopDeviceConfig(), - } + snapCfg = v1.NewLoopDevice() Expect(utils.MkdirAll(fs, rootDir, constants.DirPerm)).To(Succeed()) }) diff --git a/pkg/types/v1/config.go b/pkg/types/v1/config.go index 89fded5b8f0..4720aa4f887 100644 --- a/pkg/types/v1/config.go +++ b/pkg/types/v1/config.go @@ -94,11 +94,7 @@ func (c Config) WriteInstallState(i *InstallState, statePath, recoveryPath strin // LoadInstallState loads the state.yaml file and unmarshals it to an InstallState object func (c Config) LoadInstallState() (*InstallState, error) { installState := &InstallState{ - Snapshotter: SnapshotterConfig{ - Type: constants.LoopDeviceSnapshotterType, - MaxSnaps: constants.MaxSnaps, - Config: NewLoopDeviceConfig(), - }, + Snapshotter: NewLoopDevice(), } stateFile := filepath.Join(constants.RunningStateDir, constants.InstallStateFile) data, err := c.Fs.ReadFile(stateFile) diff --git a/pkg/types/v1/snapshotter.go b/pkg/types/v1/snapshotter.go index cdb1991a1c0..972827723d2 100644 --- a/pkg/types/v1/snapshotter.go +++ b/pkg/types/v1/snapshotter.go @@ -67,6 +67,22 @@ func NewBtrfsConfig() *BtrfsConfig { return &BtrfsConfig{} } +func NewLoopDevice() SnapshotterConfig { + return SnapshotterConfig{ + Type: constants.LoopDeviceSnapshotterType, + MaxSnaps: constants.LoopDeviceMaxSnaps, + Config: NewLoopDeviceConfig(), + } +} + +func NewBtrfs() SnapshotterConfig { + return SnapshotterConfig{ + Type: constants.BtrfsSnapshotterType, + MaxSnaps: constants.BtrfsMaxSnaps, + Config: NewBtrfsConfig(), + } +} + type snapshotterConfFactory func(defConfig interface{}, data interface{}) (interface{}, error) var snapshotterConfFactories = map[string]snapshotterConfFactory{} @@ -129,6 +145,10 @@ func (c *SnapshotterConfig) CustomUnmarshal(data interface{}) (bool, error) { return false, fmt.Errorf("'max-snap' must be of integer type") } c.MaxSnaps = maxSnaps + } else if c.Type == constants.BtrfsSnapshotterType { + // constants.LoopDeviceMaxSnaps is already the default if nothing is provided + // switch to btrfs default in case btrfs is requested and no max-snaps is provided + c.MaxSnaps = constants.BtrfsMaxSnaps } factory := snapshotterConfFactories[c.Type]