Add UKI functionlity to replace titles (#246)

* Add UKI functionlity to replace titles

Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>

* Move common logic to constants

Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>

---------

Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>
This commit is contained in:
Mauro Morales 2024-03-13 09:54:12 +01:00 committed by GitHub
parent 0ae9c04eb4
commit 590e39e97e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 110 additions and 2 deletions

1
go.mod
View File

@ -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

2
go.sum
View File

@ -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=

View File

@ -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")
}
}

View File

@ -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")
}

View File

@ -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"),
)
})

View File

@ -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 {

View File

@ -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
}