From 68f864299303ac8d510f19d67e8d7e6fe0681138 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 5 Jul 2017 20:19:19 -0400 Subject: DiskImage: Removed grubBooted Properties that used to need it as a parameter now look at Info about the bootloader that is installed in the chroot that the disk image is created from. (API change) This is a simplication, and avoids the user needing to repeat themselves in the propellor config, thus avoiding mistakes. When no boot loader is installed, or multiple different ones are, disk image creation will fail, which seems reasonable. This commit was sponsored by Jake Vosloo on Patreon. --- src/Propellor/Property/Chroot.hs | 1 + src/Propellor/Property/DiskImage.hs | 34 +++++++++++++++--------- src/Propellor/Property/Grub.hs | 12 +++++---- src/Propellor/Property/HostingProvider/Linode.hs | 4 +-- src/Propellor/Types/Bootloader.hs | 12 +++++++++ 5 files changed, 43 insertions(+), 20 deletions(-) create mode 100644 src/Propellor/Types/Bootloader.hs (limited to 'src/Propellor') diff --git a/src/Propellor/Property/Chroot.hs b/src/Propellor/Property/Chroot.hs index 65749e34..d3bd7e5c 100644 --- a/src/Propellor/Property/Chroot.hs +++ b/src/Propellor/Property/Chroot.hs @@ -15,6 +15,7 @@ module Propellor.Property.Chroot ( -- * Internal use provisioned', propagateChrootInfo, + chrootInfo, propellChroot, chain, chrootSystem, diff --git a/src/Propellor/Property/DiskImage.hs b/src/Propellor/Property/DiskImage.hs index 94604a95..10679751 100644 --- a/src/Propellor/Property/DiskImage.hs +++ b/src/Propellor/Property/DiskImage.hs @@ -13,16 +13,12 @@ module Propellor.Property.DiskImage ( imageRebuilt, imageBuiltFrom, imageExists, - -- * Finalization - Finalization, - grubBooted, Grub.BIOS(..), - noFinalization, ) where import Propellor.Base import Propellor.Property.DiskImage.PartSpec -import Propellor.Property.Chroot (Chroot) +import Propellor.Property.Chroot (Chroot, chrootInfo) import Propellor.Property.Chroot.Util (removeChroot) import qualified Propellor.Property.Chroot as Chroot import qualified Propellor.Property.Grub as Grub @@ -33,6 +29,8 @@ import Propellor.Property.Mount import Propellor.Property.Fstab (SwapPartition(..), genFstab) import Propellor.Property.Partition import Propellor.Property.Rsync +import Propellor.Types.Info +import Propellor.Types.Bootloader import Propellor.Container import Utility.Path @@ -71,7 +69,7 @@ type DiskImage = FilePath -- > -- > foo = host "foo.example.com" $ props -- > & imageBuilt "/srv/diskimages/disk.img" mychroot --- > MSDOS grubBooted +-- > MSDOS -- > [ partition EXT2 `mountedAt` "/boot" -- > `setFlag` BootFlag -- > , partition EXT4 `mountedAt` "/" @@ -97,7 +95,7 @@ type DiskImage = FilePath -- > foo = host "foo.example.com" $ props -- > & imageBuilt "/srv/diskimages/bar-disk.img" -- > (hostChroot bar (Debootstrapped mempty)) --- > MSDOS grubBooted +-- > MSDOS -- > [ partition EXT2 `mountedAt` "/boot" -- > `setFlag` BootFlag -- > , partition EXT4 `mountedAt` "/" @@ -111,17 +109,17 @@ type DiskImage = FilePath -- > & Apt.installed ["linux-image-amd64"] -- > & Grub.installed PC -- > & hasPassword (User "root") -imageBuilt :: DiskImage -> (FilePath -> Chroot) -> TableType -> Finalization -> [PartSpec] -> RevertableProperty (HasInfo + DebianLike) Linux +imageBuilt :: DiskImage -> (FilePath -> Chroot) -> TableType -> [PartSpec] -> RevertableProperty (HasInfo + DebianLike) Linux imageBuilt = imageBuilt' False -- | Like 'built', but the chroot is deleted and rebuilt from scratch each -- time. This is more expensive, but useful to ensure reproducible results -- when the properties of the chroot have been changed. -imageRebuilt :: DiskImage -> (FilePath -> Chroot) -> TableType -> Finalization -> [PartSpec] -> RevertableProperty (HasInfo + DebianLike) Linux +imageRebuilt :: DiskImage -> (FilePath -> Chroot) -> TableType -> [PartSpec] -> RevertableProperty (HasInfo + DebianLike) Linux imageRebuilt = imageBuilt' True -imageBuilt' :: Bool -> DiskImage -> (FilePath -> Chroot) -> TableType -> Finalization -> [PartSpec] -> RevertableProperty (HasInfo + DebianLike) Linux -imageBuilt' rebuild img mkchroot tabletype final partspec = +imageBuilt' :: Bool -> DiskImage -> (FilePath -> Chroot) -> TableType -> [PartSpec] -> RevertableProperty (HasInfo + DebianLike) Linux +imageBuilt' rebuild img mkchroot tabletype partspec = imageBuiltFrom img chrootdir tabletype final partspec `requires` Chroot.provisioned chroot `requires` (cleanrebuild (doNothing :: Property UnixLike)) @@ -145,6 +143,12 @@ imageBuilt' rebuild img mkchroot tabletype final partspec = -- Only propagate privdata Info from this chroot, nothing else. propprivdataonly (Chroot.Chroot d b ip h) = Chroot.Chroot d b (\c _ -> ip c onlyPrivData) h + -- Pick boot loader finalization based on which bootloader is + -- installed. + final = case fromInfo (chrootInfo chroot) of + [GrubInstalled] -> grubBooted + [] -> unbootable "no bootloader is installed" + _ -> unbootable "multiple bootloaders are installed; don't know which to use" -- | This property is automatically added to the chroot when building a -- disk image. It cleans any caches of information that can be omitted; @@ -323,8 +327,12 @@ imageFinalized final mnts mntopts devs (PartTable _ parts) = allowservices top = nukeFile (top ++ "/usr/sbin/policy-rc.d") -noFinalization :: Finalization -noFinalization = \_ _ -> doNothing +unbootable :: String -> Finalization +unbootable msg = \_ _ -> property desc $ do + warningMessage (desc ++ ": " ++ msg) + return FailedChange + where + desc = "image is not bootable" -- | Makes grub be the boot loader of the disk image. -- diff --git a/src/Propellor/Property/Grub.hs b/src/Propellor/Property/Grub.hs index 0eaab2bb..4bad7b2b 100644 --- a/src/Propellor/Property/Grub.hs +++ b/src/Propellor/Property/Grub.hs @@ -4,6 +4,8 @@ import Propellor.Base import qualified Propellor.Property.File as File import qualified Propellor.Property.Apt as Apt import Propellor.Property.Chroot (inChroot) +import Propellor.Types.Info +import Propellor.Types.Bootloader -- | Eg, \"hd0,0\" or \"xen/xvda1\" type GrubDevice = String @@ -20,7 +22,7 @@ data BIOS = PC | EFI64 | EFI32 | Coreboot | Xen -- bootloader. -- -- This includes running update-grub, unless it's run in a chroot. -installed :: BIOS -> Property DebianLike +installed :: BIOS -> Property (HasInfo + DebianLike) installed bios = installed' bios `onChange` (check (not <$> inChroot) mkConfig) @@ -31,11 +33,11 @@ mkConfig = tightenTargets $ cmdProperty "update-grub" [] `assume` MadeChange -- | Installs grub; does not run update-grub. -installed' :: BIOS -> Property Linux -installed' bios = (aptinstall `pickOS` unsupportedOS) +installed' :: BIOS -> Property (HasInfo + DebianLike) +installed' bios = setInfoProperty aptinstall + (toInfo [GrubInstalled]) `describe` "grub package installed" where - aptinstall :: Property DebianLike aptinstall = Apt.installed [debpkg] debpkg = case bios of PC -> "grub-pc" @@ -66,7 +68,7 @@ boots dev = tightenTargets $ cmdProperty "grub-install" [dev] -- -- The rootdev should be in the form "hd0", while the bootdev is in the form -- "xen/xvda". -chainPVGrub :: GrubDevice -> GrubDevice -> TimeoutSecs -> Property DebianLike +chainPVGrub :: GrubDevice -> GrubDevice -> TimeoutSecs -> Property (HasInfo + DebianLike) chainPVGrub rootdev bootdev timeout = combineProperties desc $ props & File.dirExists "/boot/grub" & "/boot/grub/menu.lst" `File.hasContent` diff --git a/src/Propellor/Property/HostingProvider/Linode.hs b/src/Propellor/Property/HostingProvider/Linode.hs index b48c1dac..ebe8d261 100644 --- a/src/Propellor/Property/HostingProvider/Linode.hs +++ b/src/Propellor/Property/HostingProvider/Linode.hs @@ -8,7 +8,7 @@ import Utility.FileMode -- | Configures grub to use the serial console as set up by Linode. -- Useful when running a distribution supplied kernel. -- -serialGrub :: Property DebianLike +serialGrub :: Property (HasInfo + DebianLike) serialGrub = "/etc/default/grub" `File.containsLines` [ "GRUB_CMDLINE_LINUX=\"console=ttyS0,19200n8\"" , "GRUB_DISABLE_LINUX_UUID=true" @@ -22,7 +22,7 @@ serialGrub = "/etc/default/grub" `File.containsLines` -- | Linode's pv-grub-x86_64 (only used for its older XEN instances) -- does not support booting recent Debian kernels compressed -- with xz. This sets up pv-grub chaining to enable it. -chainPVGrub :: Grub.TimeoutSecs -> Property DebianLike +chainPVGrub :: Grub.TimeoutSecs -> Property (HasInfo + DebianLike) chainPVGrub = Grub.chainPVGrub "hd0" "xen/xvda" -- | Linode disables mlocate's cron job's execute permissions, diff --git a/src/Propellor/Types/Bootloader.hs b/src/Propellor/Types/Bootloader.hs new file mode 100644 index 00000000..c6953b94 --- /dev/null +++ b/src/Propellor/Types/Bootloader.hs @@ -0,0 +1,12 @@ +{-# LANGUAGE FlexibleInstances #-} + +module Propellor.Types.Bootloader where + +import Propellor.Types.Info + +-- | Boot loader installed on a host. +data BootloaderInstalled = GrubInstalled + deriving (Typeable, Show) + +instance IsInfo [BootloaderInstalled] where + propagateInfo _ = PropagateInfo False -- cgit v1.2.3