diff --git a/boot/boot.go b/boot/boot.go index b580dcd1cd..19b1b23a5f 100644 --- a/boot/boot.go +++ b/boot/boot.go @@ -135,7 +135,7 @@ func applicable(s snap.PlaceInfo, t snap.Type, model Model, onClassic bool) bool // InUse checks if the given name/revision is used in the // boot environment func InUse(name string, rev snap.Revision) bool { - bootloader, err := bootloader.Find() + bootloader, err := bootloader.Find("", nil) if err != nil { logger.Noticef("cannot get boot settings: %s", err) return false @@ -182,7 +182,7 @@ func GetCurrentBoot(t snap.Type) (*NameAndRevision, error) { return nil, fmt.Errorf("internal error: cannot find boot revision for snap type %q", t) } - bloader, err := bootloader.Find() + bloader, err := bootloader.Find("", nil) if err != nil { return nil, fmt.Errorf("cannot get boot settings: %s", err) } @@ -244,7 +244,7 @@ func nameAndRevnoFromSnap(sn string) (*NameAndRevision, error) { // will set snap_mode="" and the system will boot with the known good // values from snap_{core,kernel} func MarkBootSuccessful() error { - bl, err := bootloader.Find() + bl, err := bootloader.Find("", nil) if err != nil { return fmt.Errorf("cannot mark boot successful: %s", err) } diff --git a/boot/kernel_os.go b/boot/kernel_os.go index 324cf052d0..41d552e80a 100644 --- a/boot/kernel_os.go +++ b/boot/kernel_os.go @@ -39,7 +39,7 @@ var _ BootParticipant = (*coreBootParticipant)(nil) func (*coreBootParticipant) IsTrivial() bool { return false } func (bs *coreBootParticipant) SetNextBoot() error { - bootloader, err := bootloader.Find() + bootloader, err := bootloader.Find("", nil) if err != nil { return fmt.Errorf("cannot set next boot: %s", err) } @@ -83,7 +83,7 @@ func (bs *coreBootParticipant) SetNextBoot() error { } func (bs *coreBootParticipant) ChangeRequiresReboot() bool { - bootloader, err := bootloader.Find() + bootloader, err := bootloader.Find("", nil) if err != nil { logger.Noticef("cannot get boot settings: %s", err) return false @@ -124,7 +124,7 @@ func (*coreKernel) IsTrivial() bool { return false } func (k *coreKernel) RemoveKernelAssets() error { // XXX: shouldn't we check the snap type? - bootloader, err := bootloader.Find() + bootloader, err := bootloader.Find("", nil) if err != nil { return fmt.Errorf("cannot remove kernel assets: %s", err) } @@ -134,7 +134,7 @@ func (k *coreKernel) RemoveKernelAssets() error { } func (k *coreKernel) ExtractKernelAssets(snapf snap.Container) error { - bootloader, err := bootloader.Find() + bootloader, err := bootloader.Find("", nil) if err != nil { return fmt.Errorf("cannot extract kernel assets: %s", err) } diff --git a/boot/kernel_os_test.go b/boot/kernel_os_test.go index 25d15196f2..05160a405c 100644 --- a/boot/kernel_os_test.go +++ b/boot/kernel_os_test.go @@ -29,6 +29,7 @@ import ( "github.com/snapcore/snapd/boot" "github.com/snapcore/snapd/bootloader" "github.com/snapcore/snapd/bootloader/bootloadertest" + "github.com/snapcore/snapd/dirs" "github.com/snapcore/snapd/logger" "github.com/snapcore/snapd/osutil" "github.com/snapcore/snapd/snap" @@ -223,10 +224,10 @@ func (s *ubootBootSetSuite) forceUbootBootloader(c *C) bootloader.Bootloader { mockGadgetDir := c.MkDir() err := ioutil.WriteFile(filepath.Join(mockGadgetDir, "uboot.conf"), nil, 0644) c.Assert(err, IsNil) - err = bootloader.InstallBootConfig(mockGadgetDir) + err = bootloader.InstallBootConfig(mockGadgetDir, dirs.GlobalRootDir) c.Assert(err, IsNil) - bloader, err := bootloader.Find() + bloader, err := bootloader.Find("", nil) c.Assert(err, IsNil) c.Check(bloader, NotNil) bootloader.Force(bloader) @@ -302,10 +303,10 @@ func (s *grubBootSetSuite) forceGrubBootloader(c *C) bootloader.Bootloader { mockGadgetDir := c.MkDir() err := ioutil.WriteFile(filepath.Join(mockGadgetDir, "grub.conf"), nil, 0644) c.Assert(err, IsNil) - err = bootloader.InstallBootConfig(mockGadgetDir) + err = bootloader.InstallBootConfig(mockGadgetDir, dirs.GlobalRootDir) c.Assert(err, IsNil) - bloader, err := bootloader.Find() + bloader, err := bootloader.Find("", nil) c.Assert(err, IsNil) c.Check(bloader, NotNil) bloader.SetBootVars(map[string]string{ diff --git a/bootloader/androidboot.go b/bootloader/androidboot.go index 952644618a..9ab8ddd91a 100644 --- a/bootloader/androidboot.go +++ b/bootloader/androidboot.go @@ -24,16 +24,17 @@ import ( "path/filepath" "github.com/snapcore/snapd/bootloader/androidbootenv" - "github.com/snapcore/snapd/dirs" "github.com/snapcore/snapd/osutil" "github.com/snapcore/snapd/snap" ) -type androidboot struct{} +type androidboot struct { + rootdir string +} // newAndroidboot creates a new Androidboot bootloader object -func newAndroidBoot() Bootloader { - a := &androidboot{} +func newAndroidBoot(rootdir string) Bootloader { + a := &androidboot{rootdir: rootdir} if !osutil.FileExists(a.ConfigFile()) { return nil } @@ -44,8 +45,15 @@ func (a *androidboot) Name() string { return "androidboot" } +func (a *androidboot) setRootDir(rootdir string) { + a.rootdir = rootdir +} + func (a *androidboot) dir() string { - return filepath.Join(dirs.GlobalRootDir, "/boot/androidboot") + if a.rootdir == "" { + panic("internal error: unset rootdir") + } + return filepath.Join(a.rootdir, "/boot/androidboot") } func (a *androidboot) ConfigFile() string { diff --git a/bootloader/androidboot_test.go b/bootloader/androidboot_test.go index f983d541bb..8ebfb959c3 100644 --- a/bootloader/androidboot_test.go +++ b/bootloader/androidboot_test.go @@ -25,7 +25,6 @@ import ( . "gopkg.in/check.v1" "github.com/snapcore/snapd/bootloader" - "github.com/snapcore/snapd/dirs" "github.com/snapcore/snapd/osutil" "github.com/snapcore/snapd/snap" "github.com/snapcore/snapd/snap/snaptest" @@ -41,22 +40,21 @@ func (s *androidBootTestSuite) SetUpTest(c *C) { s.baseBootenvTestSuite.SetUpTest(c) // the file needs to exist for androidboot object to be created - bootloader.MockAndroidBootFile(c, 0644) + bootloader.MockAndroidBootFile(c, s.rootdir, 0644) } func (s *androidBootTestSuite) TestNewAndroidbootNoAndroidbootReturnsNil(c *C) { - dirs.GlobalRootDir = "/something/not/there" - a := bootloader.NewAndroidBoot() + a := bootloader.NewAndroidBoot("/something/not/there") c.Assert(a, IsNil) } func (s *androidBootTestSuite) TestNewAndroidboot(c *C) { - a := bootloader.NewAndroidBoot() + a := bootloader.NewAndroidBoot(s.rootdir) c.Assert(a, NotNil) } func (s *androidBootTestSuite) TestSetGetBootVar(c *C) { - a := bootloader.NewAndroidBoot() + a := bootloader.NewAndroidBoot(s.rootdir) bootVars := map[string]string{"snap_mode": "try"} a.SetBootVars(bootVars) @@ -67,7 +65,7 @@ func (s *androidBootTestSuite) TestSetGetBootVar(c *C) { } func (s *androidBootTestSuite) TestExtractKernelAssetsNoUnpacksKernel(c *C) { - a := bootloader.NewAndroidBoot() + a := bootloader.NewAndroidBoot(s.rootdir) c.Assert(a, NotNil) @@ -91,6 +89,6 @@ func (s *androidBootTestSuite) TestExtractKernelAssetsNoUnpacksKernel(c *C) { c.Assert(err, IsNil) // kernel is *not* here - kernimg := filepath.Join(dirs.GlobalRootDir, "boot", "androidboot", "ubuntu-kernel_42.snap", "kernel.img") + kernimg := filepath.Join(s.rootdir, "boot", "androidboot", "ubuntu-kernel_42.snap", "kernel.img") c.Assert(osutil.FileExists(kernimg), Equals, false) } diff --git a/bootloader/bootloader.go b/bootloader/bootloader.go index 197db10105..c44f9a39ff 100644 --- a/bootloader/bootloader.go +++ b/bootloader/bootloader.go @@ -25,6 +25,7 @@ import ( "os" "path/filepath" + "github.com/snapcore/snapd/dirs" "github.com/snapcore/snapd/osutil" "github.com/snapcore/snapd/snap" ) @@ -56,16 +57,23 @@ type Bootloader interface { RemoveKernelAssets(s snap.PlaceInfo) error } +type installableBootloader interface { + Bootloader + setRootDir(string) +} + // InstallBootConfig installs the bootloader config from the gadget // snap dir into the right place. -func InstallBootConfig(gadgetDir string) error { - for _, bl := range []Bootloader{&grub{}, &uboot{}, &androidboot{}} { +func InstallBootConfig(gadgetDir, rootDir string) error { + for _, bl := range []installableBootloader{&grub{}, &uboot{}, &androidboot{}} { // the bootloader config file has to be root of the gadget snap gadgetFile := filepath.Join(gadgetDir, bl.Name()+".conf") if !osutil.FileExists(gadgetFile) { continue } + bl.setRootDir(rootDir) + systemFile := bl.ConfigFile() if err := os.MkdirAll(filepath.Dir(systemFile), 0755); err != nil { return err @@ -81,25 +89,37 @@ var ( forcedError error ) -// Find returns the bootloader for the given system -// or an error if no bootloader is found -func Find() (Bootloader, error) { +// Options carries bootloader options. +type Options struct { + // PrepareImageTime indicates whether the booloader is being + // used at prepare-image time, that means not on a runtime + // system. + PrepareImageTime bool +} + +// Find returns the bootloader for the system +// or an error if no bootloader is found. +func Find(rootdir string, _ *Options) (Bootloader, error) { if forcedBootloader != nil || forcedError != nil { return forcedBootloader, forcedError } + if rootdir == "" { + rootdir = dirs.GlobalRootDir + } + // try uboot - if uboot := newUboot(); uboot != nil { + if uboot := newUboot(rootdir); uboot != nil { return uboot, nil } // no, try grub - if grub := newGrub(); grub != nil { + if grub := newGrub(rootdir); grub != nil { return grub, nil } // no, try androidboot - if androidboot := newAndroidBoot(); androidboot != nil { + if androidboot := newAndroidBoot(rootdir); androidboot != nil { return androidboot, nil } diff --git a/bootloader/bootloader_test.go b/bootloader/bootloader_test.go index bc603465da..65bd7900bd 100644 --- a/bootloader/bootloader_test.go +++ b/bootloader/bootloader_test.go @@ -29,7 +29,7 @@ import ( "github.com/snapcore/snapd/bootloader" "github.com/snapcore/snapd/bootloader/bootloadertest" - "github.com/snapcore/snapd/dirs" + //"github.com/snapcore/snapd/dirs" "github.com/snapcore/snapd/osutil" "github.com/snapcore/snapd/snap" "github.com/snapcore/snapd/testutil" @@ -47,13 +47,14 @@ vendor: Someone type baseBootenvTestSuite struct { testutil.BaseTest + + rootdir string } func (s *baseBootenvTestSuite) SetUpTest(c *C) { s.BaseTest.SetUpTest(c) s.AddCleanup(snap.MockSanitizePlugsSlots(func(snapInfo *snap.Info) {})) - dirs.SetRootDir(c.MkDir()) - s.AddCleanup(func() { dirs.SetRootDir("") }) + s.rootdir = c.MkDir() } type bootenvTestSuite struct { @@ -74,7 +75,7 @@ func (s *bootenvTestSuite) TestForceBootloader(c *C) { bootloader.Force(s.b) defer bootloader.Force(nil) - got, err := bootloader.Find() + got, err := bootloader.Find("", nil) c.Assert(err, IsNil) c.Check(got, Equals, s.b) } @@ -84,13 +85,13 @@ func (s *bootenvTestSuite) TestForceBootloaderError(c *C) { bootloader.ForceError(myErr) defer bootloader.ForceError(nil) - got, err := bootloader.Find() + got, err := bootloader.Find("", nil) c.Assert(err, Equals, myErr) c.Check(got, IsNil) } func (s *bootenvTestSuite) TestInstallBootloaderConfigNoConfig(c *C) { - err := bootloader.InstallBootConfig(c.MkDir()) + err := bootloader.InstallBootConfig(c.MkDir(), s.rootdir) c.Assert(err, ErrorMatches, `cannot find boot config in.*`) } @@ -103,9 +104,9 @@ func (s *bootenvTestSuite) TestInstallBootloaderConfig(c *C) { mockGadgetDir := c.MkDir() err := ioutil.WriteFile(filepath.Join(mockGadgetDir, t.gadgetFile), nil, 0644) c.Assert(err, IsNil) - err = bootloader.InstallBootConfig(mockGadgetDir) + err = bootloader.InstallBootConfig(mockGadgetDir, s.rootdir) c.Assert(err, IsNil) - fn := filepath.Join(dirs.GlobalRootDir, t.systemFile) + fn := filepath.Join(s.rootdir, t.systemFile) c.Assert(osutil.FileExists(fn), Equals, true) } } diff --git a/bootloader/export_test.go b/bootloader/export_test.go index 67dbd2ef53..2433a359b9 100644 --- a/bootloader/export_test.go +++ b/bootloader/export_test.go @@ -29,24 +29,24 @@ import ( ) // creates a new Androidboot bootloader object -func NewAndroidBoot() Bootloader { - return newAndroidBoot() +func NewAndroidBoot(rootdir string) Bootloader { + return newAndroidBoot(rootdir) } -func MockAndroidBootFile(c *C, mode os.FileMode) { - f := &androidboot{} +func MockAndroidBootFile(c *C, rootdir string, mode os.FileMode) { + f := &androidboot{rootdir: rootdir} err := os.MkdirAll(f.dir(), 0755) c.Assert(err, IsNil) err = ioutil.WriteFile(f.ConfigFile(), nil, mode) c.Assert(err, IsNil) } -func NewUboot() Bootloader { - return newUboot() +func NewUboot(rootdir string) Bootloader { + return newUboot(rootdir) } -func MockUbootFiles(c *C) { - u := &uboot{} +func MockUbootFiles(c *C, rootdir string) { + u := &uboot{rootdir: rootdir} err := os.MkdirAll(u.dir(), 0755) c.Assert(err, IsNil) @@ -57,12 +57,12 @@ func MockUbootFiles(c *C) { c.Assert(err, IsNil) } -func NewGrub() Bootloader { - return newGrub() +func NewGrub(rootdir string) Bootloader { + return newGrub(rootdir) } -func MockGrubFiles(c *C) { - g := &grub{} +func MockGrubFiles(c *C, rootdir string) { + g := &grub{rootdir: rootdir} err := os.MkdirAll(g.dir(), 0755) c.Assert(err, IsNil) err = ioutil.WriteFile(g.ConfigFile(), nil, 0644) diff --git a/bootloader/grub.go b/bootloader/grub.go index 2364b61ae4..fe7999b152 100644 --- a/bootloader/grub.go +++ b/bootloader/grub.go @@ -24,16 +24,17 @@ import ( "path/filepath" "github.com/snapcore/snapd/bootloader/grubenv" - "github.com/snapcore/snapd/dirs" "github.com/snapcore/snapd/osutil" "github.com/snapcore/snapd/snap" ) -type grub struct{} +type grub struct { + rootdir string +} // newGrub create a new Grub bootloader object -func newGrub() Bootloader { - g := &grub{} +func newGrub(rootdir string) Bootloader { + g := &grub{rootdir: rootdir} if !osutil.FileExists(g.ConfigFile()) { return nil } @@ -45,8 +46,15 @@ func (g *grub) Name() string { return "grub" } +func (g *grub) setRootDir(rootdir string) { + g.rootdir = rootdir +} + func (g *grub) dir() string { - return filepath.Join(dirs.GlobalRootDir, "/boot/grub") + if g.rootdir == "" { + panic("internal error: unset rootdir") + } + return filepath.Join(g.rootdir, "/boot/grub") } func (g *grub) ConfigFile() string { diff --git a/bootloader/grub_test.go b/bootloader/grub_test.go index 96a207f2a1..562affdd02 100644 --- a/bootloader/grub_test.go +++ b/bootloader/grub_test.go @@ -44,9 +44,9 @@ var _ = Suite(&grubTestSuite{}) func (s *grubTestSuite) SetUpTest(c *C) { s.baseBootenvTestSuite.SetUpTest(c) - bootloader.MockGrubFiles(c) + bootloader.MockGrubFiles(c, s.rootdir) - s.bootdir = filepath.Join(dirs.GlobalRootDir, "boot") + s.bootdir = filepath.Join(s.rootdir, "boot") } // grubEditenvCmd finds the right grub{,2}-editenv command @@ -59,25 +59,25 @@ func grubEditenvCmd() string { return "" } -func grubEnvPath() string { - return filepath.Join(dirs.GlobalRootDir, "boot/grub/grubenv") +func grubEnvPath(rootdir string) string { + return filepath.Join(rootdir, "boot/grub/grubenv") } -func grubEditenvSet(c *C, key, value string) { +func (s *grubTestSuite) grubEditenvSet(c *C, key, value string) { if grubEditenvCmd() == "" { c.Skip("grub{,2}-editenv is not available") } - err := exec.Command(grubEditenvCmd(), grubEnvPath(), "set", fmt.Sprintf("%s=%s", key, value)).Run() + err := exec.Command(grubEditenvCmd(), grubEnvPath(s.rootdir), "set", fmt.Sprintf("%s=%s", key, value)).Run() c.Assert(err, IsNil) } -func grubEditenvGet(c *C, key string) string { +func (s *grubTestSuite) grubEditenvGet(c *C, key string) string { if grubEditenvCmd() == "" { c.Skip("grub{,2}-editenv is not available") } - output, err := exec.Command(grubEditenvCmd(), grubEnvPath(), "list").CombinedOutput() + output, err := exec.Command(grubEditenvCmd(), grubEnvPath(s.rootdir), "list").CombinedOutput() c.Assert(err, IsNil) cfg := goconfigparser.New() cfg.AllowNoSectionHeader = true @@ -89,20 +89,18 @@ func grubEditenvGet(c *C, key string) string { } func (s *grubTestSuite) makeFakeGrubEnv(c *C) { - grubEditenvSet(c, "k", "v") + s.grubEditenvSet(c, "k", "v") } func (s *grubTestSuite) TestNewGrubNoGrubReturnsNil(c *C) { - dirs.GlobalRootDir = "/something/not/there" - - g := bootloader.NewGrub() + g := bootloader.NewGrub("/something/not/there") c.Assert(g, IsNil) } func (s *grubTestSuite) TestNewGrub(c *C) { s.makeFakeGrubEnv(c) - g := bootloader.NewGrub() + g := bootloader.NewGrub(s.rootdir) c.Assert(g, NotNil) c.Assert(g.Name(), Equals, "grub") } @@ -110,16 +108,27 @@ func (s *grubTestSuite) TestNewGrub(c *C) { func (s *grubTestSuite) TestGetBootloaderWithGrub(c *C) { s.makeFakeGrubEnv(c) - bootloader, err := bootloader.Find() + bootloader, err := bootloader.Find(s.rootdir, nil) + c.Assert(err, IsNil) + c.Assert(bootloader.Name(), Equals, "grub") +} + +func (s *grubTestSuite) TestGetBootloaderWithGrubWithDefaultRoot(c *C) { + s.makeFakeGrubEnv(c) + + dirs.SetRootDir(s.rootdir) + defer func() { dirs.SetRootDir("") }() + + bootloader, err := bootloader.Find("", nil) c.Assert(err, IsNil) c.Assert(bootloader.Name(), Equals, "grub") } func (s *grubTestSuite) TestGetBootVer(c *C) { s.makeFakeGrubEnv(c) - grubEditenvSet(c, "snap_mode", "regular") + s.grubEditenvSet(c, "snap_mode", "regular") - g := bootloader.NewGrub() + g := bootloader.NewGrub(s.rootdir) v, err := g.GetBootVars("snap_mode") c.Assert(err, IsNil) c.Check(v, HasLen, 1) @@ -129,21 +138,21 @@ func (s *grubTestSuite) TestGetBootVer(c *C) { func (s *grubTestSuite) TestSetBootVer(c *C) { s.makeFakeGrubEnv(c) - g := bootloader.NewGrub() + g := bootloader.NewGrub(s.rootdir) err := g.SetBootVars(map[string]string{ "k1": "v1", "k2": "v2", }) c.Assert(err, IsNil) - c.Check(grubEditenvGet(c, "k1"), Equals, "v1") - c.Check(grubEditenvGet(c, "k2"), Equals, "v2") + c.Check(s.grubEditenvGet(c, "k1"), Equals, "v1") + c.Check(s.grubEditenvGet(c, "k2"), Equals, "v2") } func (s *grubTestSuite) TestExtractKernelAssetsNoUnpacksKernelForGrub(c *C) { s.makeFakeGrubEnv(c) - g := bootloader.NewGrub() + g := bootloader.NewGrub(s.rootdir) files := [][]string{ {"kernel.img", "I'm a kernel"}, @@ -172,7 +181,7 @@ func (s *grubTestSuite) TestExtractKernelAssetsNoUnpacksKernelForGrub(c *C) { func (s *grubTestSuite) TestExtractKernelForceWorks(c *C) { s.makeFakeGrubEnv(c) - g := bootloader.NewGrub() + g := bootloader.NewGrub(s.rootdir) c.Assert(g, NotNil) files := [][]string{ diff --git a/bootloader/uboot.go b/bootloader/uboot.go index f460b47395..0a475fcfdb 100644 --- a/bootloader/uboot.go +++ b/bootloader/uboot.go @@ -23,16 +23,17 @@ import ( "path/filepath" "github.com/snapcore/snapd/bootloader/ubootenv" - "github.com/snapcore/snapd/dirs" "github.com/snapcore/snapd/osutil" "github.com/snapcore/snapd/snap" ) -type uboot struct{} +type uboot struct { + rootdir string +} // newUboot create a new Uboot bootloader object -func newUboot() Bootloader { - u := &uboot{} +func newUboot(rootdir string) Bootloader { + u := &uboot{rootdir: rootdir} if !osutil.FileExists(u.envFile()) { return nil } @@ -44,8 +45,15 @@ func (u *uboot) Name() string { return "uboot" } +func (u *uboot) setRootDir(rootdir string) { + u.rootdir = rootdir +} + func (u *uboot) dir() string { - return filepath.Join(dirs.GlobalRootDir, "/boot/uboot") + if u.rootdir == "" { + panic("internal error: unset rootdir") + } + return filepath.Join(u.rootdir, "/boot/uboot") } func (u *uboot) ConfigFile() string { diff --git a/bootloader/uboot_test.go b/bootloader/uboot_test.go index a85f487cb6..8276a231ae 100644 --- a/bootloader/uboot_test.go +++ b/bootloader/uboot_test.go @@ -28,7 +28,6 @@ import ( "github.com/snapcore/snapd/bootloader" "github.com/snapcore/snapd/bootloader/ubootenv" - "github.com/snapcore/snapd/dirs" "github.com/snapcore/snapd/osutil" "github.com/snapcore/snapd/snap" "github.com/snapcore/snapd/snap/snaptest" @@ -42,20 +41,20 @@ type ubootTestSuite struct { var _ = Suite(&ubootTestSuite{}) func (s *ubootTestSuite) TestNewUbootNoUbootReturnsNil(c *C) { - u := bootloader.NewUboot() + u := bootloader.NewUboot(s.rootdir) c.Assert(u, IsNil) } func (s *ubootTestSuite) TestNewUboot(c *C) { - bootloader.MockUbootFiles(c) - u := bootloader.NewUboot() + bootloader.MockUbootFiles(c, s.rootdir) + u := bootloader.NewUboot(s.rootdir) c.Assert(u, NotNil) c.Assert(u.Name(), Equals, "uboot") } func (s *ubootTestSuite) TestUbootGetEnvVar(c *C) { - bootloader.MockUbootFiles(c) - u := bootloader.NewUboot() + bootloader.MockUbootFiles(c, s.rootdir) + u := bootloader.NewUboot(s.rootdir) c.Assert(u, NotNil) err := u.SetBootVars(map[string]string{ "snap_mode": "", @@ -72,16 +71,16 @@ func (s *ubootTestSuite) TestUbootGetEnvVar(c *C) { } func (s *ubootTestSuite) TestGetBootloaderWithUboot(c *C) { - bootloader.MockUbootFiles(c) + bootloader.MockUbootFiles(c, s.rootdir) - bootloader, err := bootloader.Find() + bootloader, err := bootloader.Find(s.rootdir, nil) c.Assert(err, IsNil) c.Assert(bootloader.Name(), Equals, "uboot") } func (s *ubootTestSuite) TestUbootSetEnvNoUselessWrites(c *C) { - bootloader.MockUbootFiles(c) - u := bootloader.NewUboot() + bootloader.MockUbootFiles(c, s.rootdir) + u := bootloader.NewUboot(s.rootdir) c.Assert(u, NotNil) envFile := u.ConfigFile() @@ -110,8 +109,8 @@ func (s *ubootTestSuite) TestUbootSetEnvNoUselessWrites(c *C) { } func (s *ubootTestSuite) TestUbootSetBootVarFwEnv(c *C) { - bootloader.MockUbootFiles(c) - u := bootloader.NewUboot() + bootloader.MockUbootFiles(c, s.rootdir) + u := bootloader.NewUboot(s.rootdir) err := u.SetBootVars(map[string]string{"key": "value"}) c.Assert(err, IsNil) @@ -122,8 +121,8 @@ func (s *ubootTestSuite) TestUbootSetBootVarFwEnv(c *C) { } func (s *ubootTestSuite) TestUbootGetBootVarFwEnv(c *C) { - bootloader.MockUbootFiles(c) - u := bootloader.NewUboot() + bootloader.MockUbootFiles(c, s.rootdir) + u := bootloader.NewUboot(s.rootdir) err := u.SetBootVars(map[string]string{"key2": "value2"}) c.Assert(err, IsNil) @@ -134,8 +133,8 @@ func (s *ubootTestSuite) TestUbootGetBootVarFwEnv(c *C) { } func (s *ubootTestSuite) TestExtractKernelAssetsAndRemove(c *C) { - bootloader.MockUbootFiles(c) - u := bootloader.NewUboot() + bootloader.MockUbootFiles(c, s.rootdir) + u := bootloader.NewUboot(s.rootdir) files := [][]string{ {"kernel.img", "I'm a kernel"}, @@ -160,7 +159,7 @@ func (s *ubootTestSuite) TestExtractKernelAssetsAndRemove(c *C) { c.Assert(err, IsNil) // this is where the kernel/initrd is unpacked - kernelAssetsDir := filepath.Join(dirs.GlobalRootDir, "boot", "uboot", "ubuntu-kernel_42.snap") + kernelAssetsDir := filepath.Join(s.rootdir, "boot", "uboot", "ubuntu-kernel_42.snap") for _, def := range files { if def[0] == "meta/kernel.yaml" { diff --git a/image/image.go b/image/image.go index 2a4e4ccadd..dd0ebeb603 100644 --- a/image/image.go +++ b/image/image.go @@ -32,7 +32,6 @@ import ( "github.com/snapcore/snapd/asserts" "github.com/snapcore/snapd/asserts/snapasserts" "github.com/snapcore/snapd/asserts/sysdb" - "github.com/snapcore/snapd/boot" "github.com/snapcore/snapd/bootloader" "github.com/snapcore/snapd/dirs" "github.com/snapcore/snapd/osutil" @@ -587,8 +586,10 @@ func setupSeed(tsto *ToolingStore, model *asserts.Model, opts *Options, local *l } if !opts.Classic { + // TODO: make this functionality part of the boot package? + // now do the bootloader stuff - if err := bootloader.InstallBootConfig(opts.GadgetUnpackDir); err != nil { + if err := bootloader.InstallBootConfig(opts.GadgetUnpackDir, dirs.GlobalRootDir); err != nil { return err } @@ -812,7 +813,9 @@ func setBootvars(downloadedSnapsInfoForBootConfig map[string]*snap.Info, model * // Set bootvars for kernel/core snaps so the system boots and // does the first-time initialization. There is also no // mounted kernel/core/base snap, but just the blobs. - bloader, err := bootloader.Find() + bloader, err := bootloader.Find("", &bootloader.Options{ + PrepareImageTime: true, + }) if err != nil { return fmt.Errorf("cannot set kernel/core boot variables: %s", err) } @@ -849,7 +852,7 @@ func setBootvars(downloadedSnapsInfoForBootConfig map[string]*snap.Info, model * bootvar = "snap_core" case snap.TypeKernel: bootvar = "snap_kernel" - if err := extractKernelAssets(fn, info, model); err != nil { + if err := extractKernelAssets(bloader, fn, info, model); err != nil { return err } } @@ -866,15 +869,13 @@ func setBootvars(downloadedSnapsInfoForBootConfig map[string]*snap.Info, model * return nil } -func extractKernelAssets(snapPath string, info *snap.Info, model *asserts.Model) error { +func extractKernelAssets(bootloader bootloader.Bootloader, snapPath string, info *snap.Info, model *asserts.Model) error { snapf, err := snap.Open(snapPath) if err != nil { return err } - // image always runs in not-on-classic mode - kernel := boot.Kernel(info, info.GetType(), model, false) - return kernel.ExtractKernelAssets(snapf) + return bootloader.ExtractKernelAssets(info, snapf) } func copyLocalSnapFile(snapPath, targetDir string, info *snap.Info) (dstPath string, err error) {