mirror of
https://github.com/kairos-io/kairos-agent.git
synced 2025-07-13 07:54:06 +00:00
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:
parent
0ae9c04eb4
commit
590e39e97e
1
go.mod
1
go.mod
@ -140,6 +140,7 @@ require (
|
|||||||
github.com/muesli/reflow v0.3.0 // indirect
|
github.com/muesli/reflow v0.3.0 // indirect
|
||||||
github.com/muesli/termenv v0.15.2 // indirect
|
github.com/muesli/termenv v0.15.2 // indirect
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // 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/go-digest v1.0.0 // indirect
|
||||||
github.com/opencontainers/image-spec v1.1.0-rc3 // indirect
|
github.com/opencontainers/image-spec v1.1.0-rc3 // indirect
|
||||||
github.com/otiai10/copy v1.9.0 // indirect
|
github.com/otiai10/copy v1.9.0 // indirect
|
||||||
|
2
go.sum
2
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.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.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.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 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA=
|
||||||
github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
|
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=
|
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||||
|
@ -17,7 +17,9 @@ limitations under the License.
|
|||||||
package constants
|
package constants
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -112,6 +114,10 @@ const (
|
|||||||
UkiEfiDir = "/efi"
|
UkiEfiDir = "/efi"
|
||||||
UkiEfiDiskByLabel = `/dev/disk/by-label/` + EfiLabel
|
UkiEfiDiskByLabel = `/dev/disk/by-label/` + EfiLabel
|
||||||
UkiMaxEntries = 3
|
UkiMaxEntries = 3
|
||||||
|
|
||||||
|
// Boot labeling
|
||||||
|
PassiveBootSuffix = " (fallback)"
|
||||||
|
RecoveryBootSuffix = " recovery"
|
||||||
)
|
)
|
||||||
|
|
||||||
func UkiDefaultSkipEntries() []string {
|
func UkiDefaultSkipEntries() []string {
|
||||||
@ -160,3 +166,25 @@ func GetConfigScanDirs() []string {
|
|||||||
"/etc/elemental", // for backwards compatibility
|
"/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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
13
pkg/constants/constants_suite_test.go
Normal file
13
pkg/constants/constants_suite_test.go
Normal 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")
|
||||||
|
}
|
25
pkg/constants/constants_test.go
Normal file
25
pkg/constants/constants_test.go
Normal 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"),
|
||||||
|
)
|
||||||
|
})
|
@ -1,12 +1,15 @@
|
|||||||
package uki
|
package uki
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
sdkTypes "github.com/kairos-io/kairos-sdk/types"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"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"
|
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
|
||||||
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
|
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
|
||||||
sdkutils "github.com/kairos-io/kairos-sdk/utils"
|
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 {
|
if err := replaceRoleInKey(newPath, "efi", oldRole, newRole, logger); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := replaceConfTitle(newPath, newRole); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -95,6 +101,30 @@ func replaceRoleInKey(path, key, oldRole, newRole string, logger sdkTypes.Kairos
|
|||||||
return os.WriteFile(path, []byte(newContents), os.ModePerm)
|
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 {
|
func copyFile(src, dst string) error {
|
||||||
sourceFile, err := os.Open(src)
|
sourceFile, err := os.Open(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -121,6 +121,15 @@ func (i *UpgradeAction) installRecovery() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user