    module Propellor.Property.HostingProvider.DigitalOcean (
    	distroKernel
    ) where

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

    -- | Digital Ocean does not provide any way to boot
    -- the kernel provided by the distribution, except using kexec.
    -- Without this, some old, and perhaps insecure kernel will be used.
    --
    -- This property causes the distro kernel to be loaded on reboot, using kexec.
    --
    -- When the power is cycled, the non-distro kernel still boots up.
    -- So, this property also checks if the running kernel is present in /boot,
    -- and if not, reboots immediately into a distro kernel.
    distroKernel :: Property DebianLike
    distroKernel :: Property DebianLike
    distroKernel = Desc -> Props DebianLike -> Property DebianLike
    forall k (metatypes :: k).
    SingI metatypes =>
    Desc
    -> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)
    propertyList "digital ocean distro kernel hack" (Props DebianLike -> Property DebianLike)
    -> Props DebianLike -> Property DebianLike
    forall a b. (a -> b) -> a -> b
    $ Props UnixLike
    props
    	Props UnixLike
    -> Property DebianLike
    -> Props
         (MetaTypes
            (Combine
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]))
    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))
    & [Desc] -> Property DebianLike
    Apt.installed ["grub-pc", "kexec-tools", "file"]
    	Props DebianLike
    -> Property UnixLike
    -> Props
         (MetaTypes
            (Combine
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux, 'Targeting 'OSFreeBSD]))
    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))
    & "/etc/default/kexec" Desc -> [Desc] -> Property UnixLike
    `File.containsLines`
    		[ "LOAD_KEXEC=true"
    		, "USE_GRUB_CONFIG=true"
    		] Property UnixLike -> Desc -> Property UnixLike
    forall p. IsProp p => p -> Desc -> p
    `describe` "kexec configured"
    	Props DebianLike
    -> Property DebianLike
    -> Props
         (MetaTypes
            (Combine
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]))
    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