Skip to content

Commit

Permalink
Fix bootentry (#277)
Browse files Browse the repository at this point in the history
* Fix bootentry

Signed-off-by: Mauro Morales <[email protected]>

* Use same naming as in GRUB

Signed-off-by: Mauro Morales <[email protected]>

---------

Signed-off-by: Mauro Morales <[email protected]>
  • Loading branch information
mauromorales authored Mar 29, 2024
1 parent cfc5237 commit 69756e3
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 20 deletions.
20 changes: 10 additions & 10 deletions pkg/action/bootentries.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ func selectBootEntrySystemd(cfg *config.Config, entry string) error {

}
originalEntries := entries
// when there are only 3 entries, we can assume they are either cos (which will be replaced eventually), fallback or recovery
if len(entries) == 3 {
entries = []string{"cos", "fallback", "recovery", "autoreset"}
// when there are only 4 entries, we can assume they are either cos (which will be replaced eventually), fallback, recovery or autoreset
if len(entries) == len(cnst.UkiDefaultMenuEntries()) {
entries = cnst.UkiDefaultMenuEntries()
}

// Check that entry exists in the entries list
Expand Down Expand Up @@ -203,9 +203,9 @@ func systemdConfToBootName(conf string) (string, error) {
return bootName, nil
}

if strings.HasPrefix(conf, "autoreset") {
bootName := "auto reset"
confName := strings.TrimPrefix(fileName, "autoreset")
if strings.HasPrefix(conf, "statereset") {
bootName := "statereset"
confName := strings.TrimPrefix(fileName, "statereset")

if confName != "" {
bootName = bootName + " " + strings.Trim(confName, "_")
Expand Down Expand Up @@ -248,11 +248,11 @@ func bootNameToSystemdConf(name string) (string, error) {
return "recovery" + differenciator + ".conf", nil
}

if strings.HasPrefix(name, "autoreset") {
if name != "autoreset" {
differenciator = "_" + strings.TrimPrefix(name, "autoreset ")
if strings.HasPrefix(name, "statereset") {
if name != "statereset" {
differenciator = "_" + strings.TrimPrefix(name, "statereset ")
}
return "autoreset" + differenciator + ".conf", nil
return "statereset" + differenciator + ".conf", nil

}

Expand Down
97 changes: 96 additions & 1 deletion pkg/action/bootentries_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,16 @@ var _ = Describe("Bootentries tests", Label("bootentry"), func() {
Expect(err).ToNot(HaveOccurred())
err = fs.WriteFile("/efi/loader/entries/recovery.conf", []byte("title kairos recovery\nefi /EFI/kairos/recovery.efi\n"), os.ModePerm)
Expect(err).ToNot(HaveOccurred())
err = fs.WriteFile("/efi/loader/entries/statereset.conf", []byte("title kairos state reset (auto)\nefi /EFI/kairos/statereset.efi\n"), os.ModePerm)
Expect(err).ToNot(HaveOccurred())

entries, err := listSystemdEntries(config, &v1.Partition{MountPoint: "/efi"})
Expect(err).ToNot(HaveOccurred())
Expect(entries).To(HaveLen(3))
Expect(entries).To(HaveLen(4))
Expect(entries).To(ContainElement("cos"))
Expect(entries).To(ContainElement("fallback"))
Expect(entries).To(ContainElement("recovery"))
Expect(entries).To(ContainElement("statereset"))

})
It("list empty boot entries if there is none", func() {
Expand All @@ -143,6 +146,8 @@ var _ = Describe("Bootentries tests", Label("bootentry"), func() {
Expect(err).ToNot(HaveOccurred())
err = fs.WriteFile("/efi/loader/entries/recovery.conf", []byte("title kairos recovery\nefi /EFI/kairos/recovery.efi\n"), os.ModePerm)
Expect(err).ToNot(HaveOccurred())
err = fs.WriteFile("/efi/loader/entries/statereset.conf", []byte("title kairos state reset (auto)\nefi /EFI/kairos/statereset.efi\n"), os.ModePerm)
Expect(err).ToNot(HaveOccurred())
err = fs.WriteFile("/efi/loader/loader.conf", []byte(""), os.ModePerm)
Expect(err).ToNot(HaveOccurred())

Expand Down Expand Up @@ -188,6 +193,27 @@ var _ = Describe("Bootentries tests", Label("bootentry"), func() {
syscall.MS_REMOUNT|syscall.MS_RDONLY,
"")).To(BeTrue())

err = SelectBootEntry(config, "statereset")
Expect(err).ToNot(HaveOccurred())
Expect(memLog.String()).To(ContainSubstring("Default boot entry set to statereset"))
reader, err = utils.SystemdBootConfReader(fs, "/efi/loader/loader.conf")
Expect(err).ToNot(HaveOccurred())
Expect(reader["default"]).To(Equal("statereset.conf"))
// Should have called a remount to make it RW
Expect(syscallMock.WasMountCalledWith(
"",
"/efi",
"",
syscall.MS_REMOUNT,
"")).To(BeTrue())
// Should have called a remount to make it RO
Expect(syscallMock.WasMountCalledWith(
"",
"/efi",
"",
syscall.MS_REMOUNT|syscall.MS_RDONLY,
"")).To(BeTrue())

err = SelectBootEntry(config, "cos")
Expect(err).ToNot(HaveOccurred())
Expect(memLog.String()).To(ContainSubstring("Default boot entry set to cos"))
Expand Down Expand Up @@ -239,6 +265,8 @@ var _ = Describe("Bootentries tests", Label("bootentry"), func() {
Expect(err).ToNot(HaveOccurred())
err = fs.WriteFile("/efi/loader/entries/recovery_install-mode_awesomeos.conf", []byte("title awesomeos recovery\nefi /EFI/kairos/recovery_install-mode_awesomeos.efi\n"), os.ModePerm)
Expect(err).ToNot(HaveOccurred())
err = fs.WriteFile("/efi/loader/entries/statereset_install-mode_awesomeos.conf", []byte("title awesomeos state reset (auto)\nefi /EFI/kairos/statereset_install-mode_awesomeos.efi\n"), os.ModePerm)
Expect(err).ToNot(HaveOccurred())
err = fs.WriteFile("/efi/loader/loader.conf", []byte(""), os.ModePerm)
Expect(err).ToNot(HaveOccurred())

Expand Down Expand Up @@ -284,6 +312,27 @@ var _ = Describe("Bootentries tests", Label("bootentry"), func() {
syscall.MS_REMOUNT|syscall.MS_RDONLY,
"")).To(BeTrue())

err = SelectBootEntry(config, "statereset")
Expect(err).ToNot(HaveOccurred())
Expect(memLog.String()).To(ContainSubstring("Default boot entry set to statereset"))
reader, err = utils.SystemdBootConfReader(fs, "/efi/loader/loader.conf")
Expect(err).ToNot(HaveOccurred())
Expect(reader["default"]).To(Equal("statereset_install-mode_awesomeos.conf"))
// Should have called a remount to make it RW
Expect(syscallMock.WasMountCalledWith(
"",
"/efi",
"",
syscall.MS_REMOUNT,
"")).To(BeTrue())
// Should have called a remount to make it RO
Expect(syscallMock.WasMountCalledWith(
"",
"/efi",
"",
syscall.MS_REMOUNT|syscall.MS_RDONLY,
"")).To(BeTrue())

err = SelectBootEntry(config, "cos")
Expect(err).ToNot(HaveOccurred())
Expect(memLog.String()).To(ContainSubstring("Default boot entry set to cos"))
Expand Down Expand Up @@ -341,6 +390,10 @@ var _ = Describe("Bootentries tests", Label("bootentry"), func() {
Expect(err).ToNot(HaveOccurred())
err = fs.WriteFile("/efi/loader/entries/recovery_foobar.conf", []byte("title Kairos recovery\nefi /EFI/kairos/recovery_foobar.efi\n"), os.ModePerm)
Expect(err).ToNot(HaveOccurred())
err = fs.WriteFile("/efi/loader/entries/statereset.conf", []byte("title Kairos state reset (auto)\nefi /EFI/kairos/statereset.efi\n"), os.ModePerm)
Expect(err).ToNot(HaveOccurred())
err = fs.WriteFile("/efi/loader/entries/statereset_foobar.conf", []byte("title Kairos state reset (auto)\nefi /EFI/kairos/state_reset_foobar.efi\n"), os.ModePerm)
Expect(err).ToNot(HaveOccurred())
err = fs.WriteFile("/efi/loader/loader.conf", []byte(""), os.ModePerm)
Expect(err).ToNot(HaveOccurred())

Expand Down Expand Up @@ -428,6 +481,48 @@ var _ = Describe("Bootentries tests", Label("bootentry"), func() {
syscall.MS_REMOUNT|syscall.MS_RDONLY,
"")).To(BeTrue())

err = SelectBootEntry(config, "statereset")
Expect(err).ToNot(HaveOccurred())
Expect(memLog.String()).To(ContainSubstring("Default boot entry set to statereset"))
reader, err = utils.SystemdBootConfReader(fs, "/efi/loader/loader.conf")
Expect(err).ToNot(HaveOccurred())
Expect(reader["default"]).To(Equal("statereset.conf"))
// Should have called a remount to make it RW
Expect(syscallMock.WasMountCalledWith(
"",
"/efi",
"",
syscall.MS_REMOUNT,
"")).To(BeTrue())
// Should have called a remount to make it RO
Expect(syscallMock.WasMountCalledWith(
"",
"/efi",
"",
syscall.MS_REMOUNT|syscall.MS_RDONLY,
"")).To(BeTrue())

err = SelectBootEntry(config, "statereset foobar")
Expect(err).ToNot(HaveOccurred())
Expect(memLog.String()).To(ContainSubstring("Default boot entry set to statereset foobar"))
reader, err = utils.SystemdBootConfReader(fs, "/efi/loader/loader.conf")
Expect(err).ToNot(HaveOccurred())
Expect(reader["default"]).To(Equal("statereset_foobar.conf"))
// Should have called a remount to make it RW
Expect(syscallMock.WasMountCalledWith(
"",
"/efi",
"",
syscall.MS_REMOUNT,
"")).To(BeTrue())
// Should have called a remount to make it RO
Expect(syscallMock.WasMountCalledWith(
"",
"/efi",
"",
syscall.MS_REMOUNT|syscall.MS_RDONLY,
"")).To(BeTrue())

err = SelectBootEntry(config, "cos")
Expect(err).ToNot(HaveOccurred())
Expect(memLog.String()).To(ContainSubstring("Default boot entry set to cos"))
Expand Down
19 changes: 12 additions & 7 deletions pkg/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const (
ActiveImgName = "active"
PassiveImgName = "passive"
RecoveryImgName = "recovery"
AutoResetEntryName = "autoreset"
StateResetImgName = "statereset"
GPT = "gpt"
UsrLocalPath = "/usr/local"
OEMPath = "/oem"
Expand Down Expand Up @@ -117,10 +117,15 @@ const (
UkiMaxEntries = 3

// Boot labeling
PassiveBootSuffix = " (fallback)"
RecoveryBootSuffix = " recovery"
PassiveBootSuffix = " (fallback)"
RecoveryBootSuffix = " recovery"
StateResetBootSuffix = " state reset (auto)"
)

func UkiDefaultMenuEntries() []string {
return []string{"cos", "fallback", "recovery", "statereset"}
}

func UkiDefaultSkipEntries() []string {
return []string{"interactive-install", "install-mode-interactive"}
}
Expand Down Expand Up @@ -173,8 +178,8 @@ func BaseBootTitle(title string) string {
return strings.TrimSuffix(title, RecoveryBootSuffix)
} else if strings.HasSuffix(title, PassiveBootSuffix) {
return strings.TrimSuffix(title, PassiveBootSuffix)
} else if strings.HasSuffix(title, AutoResetEntryName) {
return strings.TrimSuffix(title, AutoResetEntryName)
} else if strings.HasSuffix(title, StateResetBootSuffix) {
return strings.TrimSuffix(title, StateResetBootSuffix)
}
return title
}
Expand All @@ -187,8 +192,8 @@ func BootTitleForRole(role, title string) (string, error) {
return BaseBootTitle(title) + PassiveBootSuffix, nil
case RecoveryImgName:
return BaseBootTitle(title) + RecoveryBootSuffix, nil
case AutoResetEntryName:
return BaseBootTitle(title) + " " + AutoResetEntryName, nil
case StateResetImgName:
return BaseBootTitle(title) + StateResetBootSuffix, nil
default:
return "", errors.New("invalid role")
}
Expand Down
5 changes: 3 additions & 2 deletions pkg/uki/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package uki

import (
"fmt"
"github.com/kairos-io/kairos-agent/v2/pkg/action"
"os"
"path/filepath"
"strings"

"github.com/kairos-io/kairos-agent/v2/pkg/action"

hook "github.com/kairos-io/kairos-agent/v2/internal/agent/hooks"
"github.com/kairos-io/kairos-agent/v2/pkg/config"
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
Expand Down Expand Up @@ -142,7 +143,7 @@ func (i *InstallAction) Run() (err error) {
return err
}

for _, role := range []string{"active", "passive", "recovery", "autoreset"} {
for _, role := range constants.UkiDefaultMenuEntries() {
if err = copyArtifactSetRole(i.cfg.Fs, i.spec.Partitions.EFI.MountPoint, UnassignedArtifactRole, role, i.cfg.Logger); err != nil {
i.cfg.Logger.Errorf("installing the new artifact set as %s: %s", role, err.Error())
return fmt.Errorf("installing the new artifact set as %s: %w", role, err)
Expand Down

0 comments on commit 69756e3

Please sign in to comment.