    -- | 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 Property DebianLike -> KernelFlavor -> Property DebianLike
    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 = KernelFlavor
    -> Props
         (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]))
    -> 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]))
    forall {k} (metatypes :: k).
    SingI metatypes =>
    KernelFlavor
    -> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)
    combineProperties KernelFlavor
    "boots distro kernel" (Props
       (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]))
     -> 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])))
    -> Props
         (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]))
    -> 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]))
    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))
    & [KernelFlavor] -> Property DebianLike
    Apt.installed [KernelFlavor
    "grub2", KernelFlavor
    "linux-image-" KernelFlavor -> KernelFlavor -> KernelFlavor
    forall a. [a] -> [a] -> [a]
    ++ KernelFlavor
    kernelflavor]
    		Props DebianLike
    -> Property Linux
    -> Props
         (Sing
            (Combine
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux]))
    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"
    		Props
      (Sing
         (Combine
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
               'Targeting 'OSArchLinux]))
    -> Property DebianLike
    -> Props
         (Sing
            (Combine
               (Combine
                  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]
                  '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                     'Targeting 'OSArchLinux])
               '[ '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
    Grub.mkConfig
    		-- Since we're rebooting we have to manually create the flagfile
    		Props
      (Sing
         (Combine
            (Combine
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]
               '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish,
                  'Targeting 'OSArchLinux])
            '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]))
    -> Property UnixLike
    -> Props
         (Sing
            (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]))
    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
    ""]
    		Props
      (Sing
         (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]))
    -> Property DebianLike
    -> Props
         (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]))
    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"