From 590e39e97ed6ec2eead72bf4b6e96adcbe4d76bb Mon Sep 17 00:00:00 2001 From: Mauro Morales Date: Wed, 13 Mar 2024 09:54:12 +0100 Subject: [PATCH] Add UKI functionlity to replace titles (#246) * Add UKI functionlity to replace titles Signed-off-by: Mauro Morales * Move common logic to constants Signed-off-by: Mauro Morales --------- Signed-off-by: Mauro Morales --- go.mod | 1 + go.sum | 2 ++ pkg/constants/constants.go | 28 +++++++++++++++++++++++ pkg/constants/constants_suite_test.go | 13 +++++++++++ pkg/constants/constants_test.go | 25 +++++++++++++++++++++ pkg/uki/common.go | 32 ++++++++++++++++++++++++++- pkg/uki/upgrade.go | 11 ++++++++- 7 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 pkg/constants/constants_suite_test.go create mode 100644 pkg/constants/constants_test.go diff --git a/go.mod b/go.mod index 9e31271..bafe81a 100644 --- a/go.mod +++ b/go.mod @@ -140,6 +140,7 @@ require ( github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.2 // indirect github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect + github.com/onsi/ginkgo v1.16.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc3 // indirect github.com/otiai10/copy v1.9.0 // indirect diff --git a/go.sum b/go.sum index 99fdbe2..50e0eaa 100644 --- a/go.sum +++ b/go.sum @@ -488,6 +488,8 @@ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index ad5b5e7..e71f7ce 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -17,7 +17,9 @@ limitations under the License. package constants import ( + "errors" "os" + "strings" ) const ( @@ -112,6 +114,10 @@ const ( UkiEfiDir = "/efi" UkiEfiDiskByLabel = `/dev/disk/by-label/` + EfiLabel UkiMaxEntries = 3 + + // Boot labeling + PassiveBootSuffix = " (fallback)" + RecoveryBootSuffix = " recovery" ) func UkiDefaultSkipEntries() []string { @@ -160,3 +166,25 @@ func GetConfigScanDirs() []string { "/etc/elemental", // for backwards compatibility } } + +func BaseBootTitle(title string) string { + if strings.HasSuffix(title, RecoveryBootSuffix) { + return strings.TrimSuffix(title, RecoveryBootSuffix) + } else if strings.HasSuffix(title, PassiveBootSuffix) { + return strings.TrimSuffix(title, PassiveBootSuffix) + } + return title +} + +func BootTitleForRole(role, title string) (string, error) { + switch role { + case ActiveImgName: + return BaseBootTitle(title), nil + case PassiveImgName: + return BaseBootTitle(title) + PassiveBootSuffix, nil + case RecoveryImgName: + return BaseBootTitle(title) + RecoveryBootSuffix, nil + default: + return "", errors.New("invalid role") + } +} diff --git a/pkg/constants/constants_suite_test.go b/pkg/constants/constants_suite_test.go new file mode 100644 index 0000000..e89adb5 --- /dev/null +++ b/pkg/constants/constants_suite_test.go @@ -0,0 +1,13 @@ +package constants_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestConstants(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Constants Suite") +} diff --git a/pkg/constants/constants_test.go b/pkg/constants/constants_test.go new file mode 100644 index 0000000..6213b92 --- /dev/null +++ b/pkg/constants/constants_test.go @@ -0,0 +1,25 @@ +package constants_test + +import ( + "github.com/kairos-io/kairos-agent/v2/pkg/constants" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("Replace title", func() { + DescribeTable("Replacing the tile", + func(role, oldTitle, newTitle string) { + Expect(constants.BootTitleForRole(role, oldTitle)).To(Equal(newTitle)) + }, + Entry("When seeting to active with a default title", "active", "My awesome OS", "My awesome OS"), + Entry("When setting to active with a fallback title", "active", "My awesome OS (fallback)", "My awesome OS"), + Entry("When setting to active with a recovery title", "active", "My awesome OS recovery", "My awesome OS"), + Entry("When setting to passive with a default title", "passive", "My awesome OS", "My awesome OS (fallback)"), + Entry("When setting to passive with a fallback title", "passive", "My awesome OS (fallback)", "My awesome OS (fallback)"), + Entry("When setting to passive with a recovery title", "passive", "My awesome OS recovery", "My awesome OS (fallback)"), + Entry("When setting to recovery with a default title", "recovery", "My awesome OS", "My awesome OS recovery"), + Entry("When setting to recovery with a fallback title", "recovery", "My awesome OS (fallback)", "My awesome OS recovery"), + Entry("When setting to recovery with a recovery title", "recovery", "My awesome OS recovery", "My awesome OS recovery"), + ) +}) diff --git a/pkg/uki/common.go b/pkg/uki/common.go index 6bcefe2..ed49c84 100644 --- a/pkg/uki/common.go +++ b/pkg/uki/common.go @@ -1,12 +1,15 @@ package uki import ( + "errors" "fmt" - sdkTypes "github.com/kairos-io/kairos-sdk/types" "io" "os" "strings" + sdkTypes "github.com/kairos-io/kairos-sdk/types" + + "github.com/kairos-io/kairos-agent/v2/pkg/constants" v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1" fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs" sdkutils "github.com/kairos-io/kairos-sdk/utils" @@ -65,6 +68,9 @@ func copyArtifactSetRole(fs v1.FS, artifactDir, oldRole, newRole string, logger if err := replaceRoleInKey(newPath, "efi", oldRole, newRole, logger); err != nil { return err } + if err := replaceConfTitle(newPath, newRole); err != nil { + return err + } } return nil @@ -95,6 +101,30 @@ func replaceRoleInKey(path, key, oldRole, newRole string, logger sdkTypes.Kairos return os.WriteFile(path, []byte(newContents), os.ModePerm) } +func replaceConfTitle(path, role string) error { + conf, err := sdkutils.SystemdBootConfReader(path) + if err != nil { + return err + } + + if len(conf["title"]) == 0 { + return errors.New("no title in .conf file") + } + + newTitle, err := constants.BootTitleForRole(role, conf["title"]) + if err != nil { + return err + } + + conf["title"] = newTitle + newContents := "" + for k, v := range conf { + newContents = fmt.Sprintf("%s%s %s\n", newContents, k, v) + } + + return os.WriteFile(path, []byte(newContents), os.ModePerm) +} + func copyFile(src, dst string) error { sourceFile, err := os.Open(src) if err != nil { diff --git a/pkg/uki/upgrade.go b/pkg/uki/upgrade.go index ccd13ce..4dbc9c3 100644 --- a/pkg/uki/upgrade.go +++ b/pkg/uki/upgrade.go @@ -121,6 +121,15 @@ func (i *UpgradeAction) installRecovery() error { if err != nil { return err } + err = replaceRoleInKey(targetConfPath, "efi", UnassignedArtifactRole, "recovery", i.cfg.Logger) + if err != nil { + return err + } - return replaceRoleInKey(targetConfPath, "efi", UnassignedArtifactRole, "recovery", i.cfg.Logger) + err = replaceConfTitle(targetConfPath, "recovery") + if err != nil { + return err + } + + return nil }