    module Propellor.Property.HostingProvider.Linode where

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

    -- | Configures grub to use the serial console as set up by Linode.
    -- Useful when running a distribution supplied kernel.
    -- <https://www.linode.com/docs/tools-reference/custom-kernels-distros/run-a-distribution-supplied-kernel-with-kvm>
    serialGrub :: Property (HasInfo + DebianLike)
    serialGrub :: Property (HasInfo + DebianLike)
    serialGrub = "/etc/default/grub" FilePath -> [FilePath] -> Property UnixLike
    `File.containsLines`
    	[ "GRUB_CMDLINE_LINUX=\"console=ttyS0,19200n8\""
    	, "GRUB_DISABLE_LINUX_UUID=true"
    	, "GRUB_SERIAL_COMMAND=\"serial --speed=19200 --unit=0 --word=8 --parity=no --stop=1\""
    	, "GRUB_TERMINAL=serial"
    	]
    	Property UnixLike
    -> Property DebianLike
    -> CombinedType (Property UnixLike) (Property DebianLike)
    forall x y. Combines x y => x -> y -> CombinedType x y
    `onChange` Property DebianLike
    Grub.mkConfig
    	Property DebianLike
    -> Property
         (Sing '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
    -> CombinedType
         (Property DebianLike)
         (Property
            (Sing '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish]))
    forall x y. Combines x y => x -> y -> CombinedType x y
    `requires` GrubTarget -> Property (HasInfo + DebianLike)
    Grub.installed GrubTarget
    Grub.PC
    	Property
      (Sing '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
    -> FilePath
    -> Property
         (Sing '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
    forall p. IsProp p => p -> FilePath -> p
    `describe` "GRUB configured for Linode serial console"

    -- | 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 (HasInfo + DebianLike)
    chainPVGrub :: TimeoutSecs -> Property (HasInfo + DebianLike)
    chainPVGrub = FilePath
    -> FilePath -> TimeoutSecs -> Property (HasInfo + DebianLike)
    Grub.chainPVGrub "hd0" "xen/xvda"

    -- | Linode disables mlocate's cron job's execute permissions,
    -- presumably to avoid disk IO. This ensures it's executable.
    mlocateEnabled :: Property DebianLike
    mlocateEnabled :: Property DebianLike
    mlocateEnabled = Property UnixLike -> Property DebianLike
    forall (p :: * -> *) (untightened :: [MetaType])
           (tightened :: [MetaType]).
    (TightenTargets p, TightenTargetsAllowed untightened tightened,
     SingI tightened) =>
    p (MetaTypes untightened) -> p (MetaTypes tightened)
    tightenTargets (Property UnixLike -> Property DebianLike)
    -> Property UnixLike -> Property DebianLike
    forall a b. (a -> b) -> a -> b
    $
    	"/etc/cron.daily/mlocate"
    		FilePath -> FileMode -> Property UnixLike
    `File.mode` [FileMode] -> FileMode
    combineModes ([FileMode]
    readModes [FileMode] -> [FileMode] -> [FileMode]
    forall a. [a] -> [a] -> [a]
    ++ [FileMode]
    executeModes)