func kernelOrOsRebootRequired(s *SnapPart) bool { if s.m.Type != pkg.TypeKernel && s.m.Type != pkg.TypeOS { return false } var nextBoot, goodBoot string switch s.m.Type { case pkg.TypeKernel: nextBoot = "snappy_kernel" goodBoot = "snappy_good_kernel" case pkg.TypeOS: nextBoot = "snappy_os" goodBoot = "snappy_good_os" } nextBootVer, err := getBootVar(nextBoot) if err != nil { return false } goodBootVer, err := getBootVar(goodBoot) if err != nil { return false } squashfsName := filepath.Base(stripGlobalRootDir(squashfs.BlobPath(s.basedir))) if nextBootVer == squashfsName && goodBootVer != nextBootVer { return true } return false }
// removeKernelAssets removes the unpacked kernel/initrd for the given // kernel snap func removeKernelAssets(s *SnapPart, inter interacter) error { if s.m.Type != pkg.TypeKernel { return fmt.Errorf("can not remove kernel assets from snap type %q", s.Type()) } // remove the kernel blob blobName := filepath.Base(squashfs.BlobPath(s.basedir)) dstDir := filepath.Join(partition.BootloaderDir(), blobName) if err := os.RemoveAll(dstDir); err != nil { return err } return nil }
// extractKernelAssets extracts kernel/initrd/dtb data from the given // SnapPart to a versionized bootloader directory so that the bootloader // can use it. func extractKernelAssets(s *SnapPart, inter progress.Meter, flags InstallFlags) error { if s.m.Type != pkg.TypeKernel { return fmt.Errorf("can not extract kernel assets from snap type %q", s.Type()) } // FIXME: feels wrong to use the basedir here, need something better // // now do the kernel specific bits blobName := filepath.Base(squashfs.BlobPath(s.basedir)) dstDir := filepath.Join(partition.BootloaderDir(), blobName) if err := os.MkdirAll(dstDir, 0755); err != nil { return err } dir, err := os.Open(dstDir) if err != nil { return err } defer dir.Close() for _, src := range []string{s.m.Kernel, s.m.Initrd} { if src == "" { continue } if err := s.deb.Unpack(src, dstDir); err != nil { return err } src = filepath.Join(dstDir, src) dst := filepath.Join(dstDir, dropVersionSuffix(src)) if err := os.Rename(src, dst); err != nil { return err } if err := dir.Sync(); err != nil { return err } } if s.m.Dtbs != "" { src := filepath.Join(s.m.Dtbs, "*") dst := dstDir if err := s.deb.Unpack(src, dst); err != nil { return err } } return dir.Sync() }
func (m *packageYaml) addSquashfsMount(baseDir string, inhibitHooks bool, inter interacter) error { squashfsPath := stripGlobalRootDir(squashfs.BlobPath(baseDir)) whereDir := stripGlobalRootDir(baseDir) sysd := systemd.New(dirs.GlobalRootDir, inter) mountUnitName, err := sysd.WriteMountUnitFile(m.Name, squashfsPath, whereDir) if err != nil { return err } // we always enable the mount unit even in inhibit hooks if err := sysd.Enable(mountUnitName); err != nil { return err } if !inhibitHooks { return sysd.Start(mountUnitName) } return nil }
func (s *SnapPart) remove(inter interacter) (err error) { if err := s.deactivate(false, inter); err != nil && err != ErrSnapNotActive { return err } // ensure mount unit stops if err := s.m.removeSquashfsMount(s.basedir, inter); err != nil { return err } err = os.RemoveAll(s.basedir) if err != nil { return err } // best effort(?) os.Remove(filepath.Dir(s.basedir)) // remove the snap if err := os.RemoveAll(squashfs.BlobPath(s.basedir)); err != nil { return err } // remove the kernel assets (if any) if s.m.Type == pkg.TypeKernel { if err := removeKernelAssets(s, inter); err != nil { logger.Noticef("removing kernel assets failed with %s", err) } } // don't fail if icon can't be removed if helpers.FileExists(iconPath(s)) { if err := os.Remove(iconPath(s)); err != nil { logger.Noticef("Failed to remove store icon %s: %s", iconPath(s), err) } } return nil }
// setNextBoot will schedule the given os or kernel snap to be used in // the next boot func setNextBoot(s *SnapPart) error { if s.m.Type != pkg.TypeOS && s.m.Type != pkg.TypeKernel { return nil } var bootvar string switch s.m.Type { case pkg.TypeOS: bootvar = "snappy_os" case pkg.TypeKernel: bootvar = "snappy_kernel" } blobName := filepath.Base(squashfs.BlobPath(s.basedir)) if err := setBootVar(bootvar, blobName); err != nil { return err } if err := setBootVar("snappy_mode", "try"); err != nil { return err } return nil }