-- | Maintainer: Sean Whitton <spwhitton@spwhitton.name>
--
-- Properties for use on <https://www.exoscale.ch/>

module Propellor.Property.HostingProvider.Exoscale (
	distroKernel,
) where

import Propellor.Base
import qualified Propellor.Property.File as File
import qualified Propellor.Property.Grub as Grub
import qualified Propellor.Property.Apt as Apt
import qualified Propellor.Property.Reboot as Reboot

-- | Flavor of kernel, eg "amd64" or "686"
type KernelFlavor = String

-- | The current Exoshare Debian image doesn't install GRUB, so this property
-- makes sure GRUB is installed and correctly configured
--
-- In case an old, insecure kernel is running, we check for an old kernel
-- version and reboot immediately if one is found.
--
-- Note that we ignore anything after the first hyphen when considering
-- whether the running kernel's version is older than the Debian-supplied
-- kernel's version.
distroKernel :: KernelFlavor -> Property DebianLike
distroKernel :: KernelFlavor -> Property DebianLike
distroKernel KernelFlavor
kernelflavor = Property DebianLike
go forall i. Property i -> KernelFlavor -> Property i
`flagFile` KernelFlavor
theFlagFile
  where
	go :: Property
  (MetaTypes
     (Combine
        (Combine
           (Combine
              (Combine
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                    'Targeting 'OSArchLinux])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
              'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD])
        '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]))
go = forall {k} (metatypes :: k).
SingI metatypes =>
KernelFlavor
-> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)
combineProperties KernelFlavor
"boots distro kernel" forall a b. (a -> b) -> a -> b
$ Props UnixLike
props
		forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& [KernelFlavor] -> Property DebianLike
Apt.installed [KernelFlavor
"grub2", KernelFlavor
"linux-image-" forall a. [a] -> [a] -> [a]
++ KernelFlavor
kernelflavor]
		forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& KernelFlavor -> Property Linux
Grub.boots KernelFlavor
"/dev/vda"
		forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Property DebianLike
Grub.mkConfig
		-- Since we're rebooting we have to manually create the flagfile
		forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& KernelFlavor -> [KernelFlavor] -> Property UnixLike
File.hasContent KernelFlavor
theFlagFile [KernelFlavor
""]
		forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Property DebianLike
Reboot.toDistroKernel
	theFlagFile :: KernelFlavor
theFlagFile = KernelFlavor
"/etc/propellor-distro-kernel"