-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | property-based host configuration management in haskell
--   
--   Propellor ensures that the system it's run in satisfies a list of
--   properties, taking action as necessary when a property is not yet met.
--   
--   It is configured using haskell.
@package propellor
@version 5.3.3

-- | Re-exports some of propellor's internal utility modules.
--   
--   These are used in the implementation of propellor, including some of
--   its properties. However, there is no API stability; any of these can
--   change or be removed without a major version number increase.
--   
--   Use outside propellor at your own risk.
module Propellor.Utilities
read :: Read a => String -> a
head :: [a] -> a
tail :: [a] -> [a]
init :: [a] -> [a]
last :: [a] -> a
readish :: Read a => String -> Maybe a
headMaybe :: [a] -> Maybe a
lastMaybe :: [a] -> Maybe a
beginning :: [a] -> [a]
end :: [a] -> [a]
data CreateProcess :: *
CreateProcess :: CmdSpec -> Maybe FilePath -> Maybe [(String, String)] -> StdStream -> StdStream -> StdStream -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe GroupID -> Maybe UserID -> CreateProcess
[cmdspec] :: CreateProcess -> CmdSpec
[cwd] :: CreateProcess -> Maybe FilePath
[env] :: CreateProcess -> Maybe [(String, String)]
[std_in] :: CreateProcess -> StdStream
[std_out] :: CreateProcess -> StdStream
[std_err] :: CreateProcess -> StdStream
[close_fds] :: CreateProcess -> Bool
[create_group] :: CreateProcess -> Bool
[delegate_ctlc] :: CreateProcess -> Bool
[detach_console] :: CreateProcess -> Bool
[create_new_console] :: CreateProcess -> Bool
[new_session] :: CreateProcess -> Bool
[child_group] :: CreateProcess -> Maybe GroupID
[child_user] :: CreateProcess -> Maybe UserID
data StdHandle
StdinHandle :: StdHandle
StdoutHandle :: StdHandle
StderrHandle :: StdHandle

-- | Normally, when reading from a process, it does not need to be fed any
--   standard input.
readProcess :: FilePath -> [String] -> IO String
readProcess' :: CreateProcess -> IO String
readProcessEnv :: FilePath -> [String] -> Maybe [(String, String)] -> IO String

-- | Runs an action to write to a process on its stdin, returns its output,
--   and also allows specifying the environment.
writeReadProcessEnv :: FilePath -> [String] -> Maybe [(String, String)] -> (Maybe (Handle -> IO ())) -> (Maybe (Handle -> IO ())) -> IO String

-- | Waits for a ProcessHandle, and throws an IOError if the process did
--   not exit successfully.
forceSuccessProcess :: CreateProcess -> ProcessHandle -> IO ()
forceSuccessProcess' :: CreateProcess -> ExitCode -> IO ()

-- | Waits for a ProcessHandle and returns True if it exited successfully.
--   Note that using this with createProcessChecked will throw away the
--   Bool, and is only useful to ignore the exit code of a process, while
--   still waiting for it. -}
checkSuccessProcess :: ProcessHandle -> IO Bool
ignoreFailureProcess :: ProcessHandle -> IO Bool

-- | Runs createProcess, then an action on its handles, and then
--   forceSuccessProcess.
createProcessSuccess :: CreateProcessRunner

-- | Runs createProcess, then an action on its handles, and then a checker
--   action on its exit code, which must wait for the process.
createProcessChecked :: (ProcessHandle -> IO b) -> CreateProcessRunner

-- | Leaves the process running, suitable for lazy streaming. Note: Zombies
--   will result, and must be waited on.
createBackgroundProcess :: CreateProcessRunner

-- | Runs a process, optionally feeding it some input, and returns a
--   transcript combining its stdout and stderr, and whether it succeeded
--   or failed.
processTranscript :: String -> [String] -> (Maybe String) -> IO (String, Bool)
processTranscript' :: CreateProcess -> Maybe String -> IO (String, Bool)

-- | Runs a CreateProcessRunner, on a CreateProcess structure, that is
--   adjusted to pipe only from/to a single StdHandle, and passes the
--   resulting Handle to an action.
withHandle :: StdHandle -> CreateProcessRunner -> CreateProcess -> (Handle -> IO a) -> IO a

-- | Like withHandle, but passes (stdin, stdout) handles to the action.
withIOHandles :: CreateProcessRunner -> CreateProcess -> ((Handle, Handle) -> IO a) -> IO a

-- | Like withHandle, but passes (stdout, stderr) handles to the action.
withOEHandles :: CreateProcessRunner -> CreateProcess -> ((Handle, Handle) -> IO a) -> IO a

-- | Forces the CreateProcessRunner to run quietly; both stdout and stderr
--   are discarded.
withQuietOutput :: CreateProcessRunner -> CreateProcess -> IO ()

-- | Stdout and stderr are discarded, while the process is fed stdin from
--   the handle.
feedWithQuietOutput :: CreateProcessRunner -> CreateProcess -> (Handle -> IO a) -> IO a

-- | Wrapper around createProcess that does debug logging.
createProcess :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)

-- | Wrapper around waitForProcess that does debug logging.
waitForProcess :: ProcessHandle -> IO ExitCode

-- | Starts an interactive process. Unlike runInteractiveProcess in
--   System.Process, stderr is inherited.
startInteractiveProcess :: FilePath -> [String] -> Maybe [(String, String)] -> IO (ProcessHandle, Handle, Handle)
stdinHandle :: HandleExtractor
stdoutHandle :: HandleExtractor
stderrHandle :: HandleExtractor
ioHandles :: (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> (Handle, Handle)
processHandle :: (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> ProcessHandle
devNull :: FilePath
giveup :: [Char] -> a
catchBoolIO :: MonadCatch m => m Bool -> m Bool
catchMaybeIO :: MonadCatch m => m a -> m (Maybe a)
catchDefaultIO :: MonadCatch m => a -> m a -> m a
catchMsgIO :: MonadCatch m => m a -> m (Either String a)
catchIO :: MonadCatch m => m a -> (IOException -> m a) -> m a
tryIO :: MonadCatch m => m a -> m (Either IOException a)
bracketIO :: (MonadMask m, MonadIO m) => IO v -> (v -> IO b) -> (v -> m a) -> m a
catchNonAsync :: MonadCatch m => m a -> (SomeException -> m a) -> m a
tryNonAsync :: MonadCatch m => m a -> m (Either SomeException a)
tryWhenExists :: MonadCatch m => m a -> m (Maybe a)
catchIOErrorType :: MonadCatch m => IOErrorType -> (IOException -> m a) -> m a -> m a
data IOErrorType :: *
AlreadyExists :: IOErrorType
NoSuchThing :: IOErrorType
ResourceBusy :: IOErrorType
ResourceExhausted :: IOErrorType
EOF :: IOErrorType
IllegalOperation :: IOErrorType
PermissionDenied :: IOErrorType
UserError :: IOErrorType
UnsatisfiedConstraints :: IOErrorType
SystemError :: IOErrorType
ProtocolError :: IOErrorType
OtherError :: IOErrorType
InvalidArgument :: IOErrorType
InappropriateType :: IOErrorType
HardwareFault :: IOErrorType
UnsupportedOperation :: IOErrorType
TimeExpired :: IOErrorType
ResourceVanished :: IOErrorType
Interrupted :: IOErrorType
catchPermissionDenied :: MonadCatch m => (IOException -> m a) -> m a -> m a
getEnv :: String -> IO (Maybe String)
getEnvDefault :: String -> String -> IO String
getEnvironment :: IO [(String, String)]
setEnv :: String -> String -> Bool -> IO ()
unsetEnv :: String -> IO ()
addEntry :: Eq k => k -> v -> [(k, v)] -> [(k, v)]
addEntries :: Eq k => [(k, v)] -> [(k, v)] -> [(k, v)]
delEntry :: Eq k => k -> [(k, v)] -> [(k, v)]
dirCruft :: FilePath -> Bool
fsCruft :: FilePath -> Bool
dirContents :: FilePath -> IO [FilePath]
dirContentsRecursive :: FilePath -> IO [FilePath]
dirContentsRecursiveSkipping :: (FilePath -> Bool) -> Bool -> FilePath -> IO [FilePath]
dirTreeRecursiveSkipping :: (FilePath -> Bool) -> FilePath -> IO [FilePath]
moveFile :: FilePath -> FilePath -> IO ()
nukeFile :: FilePath -> IO ()
data DirectoryHandle
DirectoryHandle :: IsOpen -> DirStream -> DirectoryHandle
type IsOpen = MVar ()
openDirectory :: FilePath -> IO DirectoryHandle
closeDirectory :: DirectoryHandle -> IO ()

-- | Reads the next entry from the handle. Once the end of the directory is
--   reached, returns Nothing and automatically closes the handle.
readDirectory :: DirectoryHandle -> IO (Maybe FilePath)
isDirectoryEmpty :: FilePath -> IO Bool

-- | True if the directory does not exist or contains nothing. Ignores
--   "lost+found" which can exist in an empty filesystem.
isUnpopulated :: FilePath -> IO Bool

-- | Run test on entries found in directory, return False as soon as the
--   test returns False, else return True. Throws exception if directory
--   does not exist.
testDirectory :: FilePath -> (FilePath -> Bool) -> IO Bool
type Template = String
viaTmp :: (MonadMask m, MonadIO m) => (FilePath -> String -> m ()) -> FilePath -> String -> m ()
withTmpFile :: (MonadIO m, MonadMask m) => Template -> (FilePath -> Handle -> m a) -> m a
withTmpFileIn :: (MonadIO m, MonadMask m) => FilePath -> Template -> (FilePath -> Handle -> m a) -> m a
withTmpDir :: (MonadMask m, MonadIO m) => Template -> (FilePath -> m a) -> m a
withTmpDirIn :: (MonadMask m, MonadIO m) => FilePath -> Template -> (FilePath -> m a) -> m a
removeTmpDir :: MonadIO m => FilePath -> m ()
relatedTemplate :: FilePath -> FilePath
firstM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a)
getM :: Monad m => (a -> m (Maybe b)) -> [a] -> m (Maybe b)
anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool
allM :: Monad m => (a -> m Bool) -> [a] -> m Bool
untilTrue :: Monad m => [a] -> (a -> m Bool) -> m Bool
ifM :: Monad m => m Bool -> (m a, m a) -> m a
(<||>) :: Monad m => m Bool -> m Bool -> m Bool
infixr 2 <||>
(<&&>) :: Monad m => m Bool -> m Bool -> m Bool
infixr 3 <&&>
observe :: Monad m => (a -> m b) -> m a -> m a
after :: Monad m => m b -> m a -> m a
noop :: Monad m => m ()
hGetContentsStrict :: Handle -> IO String
readFileStrict :: FilePath -> IO String
separate :: (a -> Bool) -> [a] -> ([a], [a])
firstLine :: String -> String
segment :: (a -> Bool) -> [a] -> [[a]]
prop_segment_regressionTest :: Bool
segmentDelim :: (a -> Bool) -> [a] -> [[a]]
massReplace :: [(String, String)] -> String -> String
hGetSomeString :: Handle -> Int -> IO String
reapZombies :: IO ()
exitBool :: Bool -> IO a

-- | Simple implementation of singletons, portable back to ghc 7.6.3
module Propellor.Types.Singletons

-- | The data family of singleton types.

-- | A class used to pass singleton values implicitly.
class SingI t
sing :: SingI t => Sing t
class (kparam ~ KProxy) => SingKind (kparam :: KProxy k) where type DemoteRep kparam :: * where {
    type family DemoteRep kparam :: *;
}

-- | From singleton to value.
fromSing :: SingKind kparam => Sing (a :: k) -> DemoteRep kparam
data KProxy t :: * -> *
KProxy :: KProxy t
instance forall a (x :: a) (xs :: [a]). (Propellor.Types.Singletons.SingI x, Propellor.Types.Singletons.SingI xs) => Propellor.Types.Singletons.SingI (x : xs)
instance Propellor.Types.Singletons.SingI '[]
instance Propellor.Types.Singletons.SingI 'GHC.Types.True
instance Propellor.Types.Singletons.SingI 'GHC.Types.False
instance Propellor.Types.Singletons.SingKind 'Data.Proxy.KProxy => Propellor.Types.Singletons.SingKind 'Data.Proxy.KProxy
instance Propellor.Types.Singletons.SingKind 'Data.Proxy.KProxy

module Propellor.Types.Result

-- | There can be three results of satisfying a Property.
data Result
NoChange :: Result
MadeChange :: Result
FailedChange :: Result
class ToResult t
toResult :: ToResult t => t -> Result

-- | Results of actions, with color.
class ActionResult a
getActionResult :: ActionResult a => a -> (String, ColorIntensity, Color)
instance GHC.Classes.Eq Propellor.Types.Result.Result
instance GHC.Show.Show Propellor.Types.Result.Result
instance GHC.Read.Read Propellor.Types.Result.Result
instance GHC.Base.Monoid Propellor.Types.Result.Result
instance Propellor.Types.Result.ToResult GHC.Types.Bool
instance Propellor.Types.Result.ToResult Propellor.Types.Result.Result
instance Propellor.Types.Result.ActionResult GHC.Types.Bool
instance Propellor.Types.Result.ActionResult Propellor.Types.Result.Result

module Propellor.Types.Info

-- | Information about a Host, which can be provided by its properties.
--   
--   Many different types of data can be contained in the same Info value
--   at the same time. See toInfo and fromInfo.
newtype Info
Info :: [InfoEntry] -> Info
data InfoEntry
[InfoEntry] :: (IsInfo v, Typeable v) => v -> InfoEntry

-- | Values stored in Info must be members of this class.
--   
--   This is used to avoid accidentially using other data types as info,
--   especially type aliases which coud easily lead to bugs. We want a
--   little bit of dynamic types here, but not too far..
class (Typeable v, Monoid v, Show v) => IsInfo v

-- | Should this info be propagated out of a container to its Host?
propagateInfo :: IsInfo v => v -> PropagateInfo
data PropagateInfo
PropagateInfo :: Bool -> PropagateInfo

-- | Info about PrivData generally will be propigated even in cases where
--   other Info is not, so it treated specially.
PropagatePrivData :: PropagateInfo

-- | Any value in the IsInfo type class can be added to an Info.
addInfo :: IsInfo v => Info -> v -> Info

-- | Converts any value in the IsInfo type class into an Info, which
--   is otherwise empty.
toInfo :: IsInfo v => v -> Info
fromInfo :: IsInfo v => Info -> v

-- | Maps a function over all values stored in the Info that are of the
--   appropriate type.
mapInfo :: IsInfo v => (v -> v) -> Info -> Info

-- | Use this to put a value in Info that is not a monoid. The last value
--   set will be used. This info does not propagate out of a container.
data InfoVal v
NoInfoVal :: InfoVal v
InfoVal :: v -> InfoVal v
fromInfoVal :: InfoVal v -> Maybe v
class Typeable k (a :: k)
instance GHC.Show.Show v => GHC.Show.Show (Propellor.Types.Info.InfoVal v)
instance GHC.Show.Show Propellor.Types.Info.Info
instance GHC.Base.Monoid Propellor.Types.Info.Info
instance GHC.Show.Show Propellor.Types.Info.InfoEntry
instance GHC.Base.Monoid (Propellor.Types.Info.InfoVal v)
instance (Data.Typeable.Internal.Typeable v, GHC.Show.Show v) => Propellor.Types.Info.IsInfo (Propellor.Types.Info.InfoVal v)

module Propellor.Types.Exception

-- | Normally when an exception is encountered while propellor is ensuring
--   a property, the property fails, but propellor robustly continues on to
--   the next property.
--   
--   This is the only exception that will stop the entire propellor run,
--   preventing any subsequent properties of the Host from being ensured.
--   (When propellor is running in a container in a Host, this exception
--   only stops the propellor run in the container; the outer run in the
--   Host continues.)
--   
--   You should only throw this exception when things are so badly messed
--   up that it's best for propellor to not try to do anything else.
data StopPropellorException
StopPropellorException :: String -> StopPropellorException
instance GHC.Show.Show Propellor.Types.Exception.StopPropellorException
instance GHC.Exception.Exception Propellor.Types.Exception.StopPropellorException

module Propellor.Types.Empty
class Empty t
isEmpty :: Empty t => t -> Bool
instance Propellor.Types.Empty.Empty [a]
instance Propellor.Types.Empty.Empty (Data.Map.Base.Map k v)
instance Propellor.Types.Empty.Empty (Data.Set.Base.Set v)

module Propellor.Types.Container

-- | A value that can be bound between the host and a container.
--   
--   For example, a Bound Port is a Port on the container that is bound to
--   a Port on the host.
data Bound v
Bound :: v -> v -> Bound v
[hostSide] :: Bound v -> v
[containerSide] :: Bound v -> v

-- | Create a Bound value, from two different values for the host and
--   container.
--   
--   For example, Port 8080 -<- Port 80 means that port 8080 on
--   the host is bound to port 80 from the container.
(-<-) :: (hostv ~ v, containerv ~ v) => hostv -> containerv -> Bound v

-- | Flipped version of -<- with the container value first and host
--   value second.
(->-) :: (containerv ~ v, hostv ~ v) => containerv -> hostv -> Bound v

-- | Create a Bound value, that is the same on both the host and container.
same :: v -> Bound v

module Propellor.Types.ConfigurableValue

-- | A value that can be used in a configuration file, or otherwise used to
--   configure a program.
--   
--   Unlike Show, there should only be instances of this type class for
--   values that have a standard serialization that is understood outside
--   of Haskell code.
--   
--   When converting a type alias such as "type Foo = String" or "type Foo
--   = Int" to a newtype, it's unsafe to derive a Show instance, because
--   there may be code that shows the type to configure a value. Instead,
--   define a ConfigurableValue instance.
class ConfigurableValue t
val :: ConfigurableValue t => t -> String

-- | val String does not do any quoting, unlike show String
instance Propellor.Types.ConfigurableValue.ConfigurableValue GHC.Base.String
instance Propellor.Types.ConfigurableValue.ConfigurableValue GHC.Types.Int
instance Propellor.Types.ConfigurableValue.ConfigurableValue GHC.Integer.Type.Integer
instance Propellor.Types.ConfigurableValue.ConfigurableValue GHC.Types.Float
instance Propellor.Types.ConfigurableValue.ConfigurableValue GHC.Types.Double
instance Propellor.Types.ConfigurableValue.ConfigurableValue GHC.Word.Word8
instance Propellor.Types.ConfigurableValue.ConfigurableValue GHC.Word.Word16
instance Propellor.Types.ConfigurableValue.ConfigurableValue GHC.Word.Word32

module Propellor.Types.OS

-- | High level description of a operating system.
data System
System :: Distribution -> Architecture -> System
data Distribution
Debian :: DebianKernel -> DebianSuite -> Distribution

-- | A well-known Debian derivative founded by a space tourist. The actual
--   name of this distribution is not used in Propellor per
--   http://joeyh.name/blog/entry/trademark_nonsense/
Buntish :: Release -> Distribution
ArchLinux :: Distribution
FreeBSD :: FreeBSDRelease -> Distribution

-- | Properties can target one or more OS's; the targets are part of the
--   type of the property, so need to be kept fairly simple.
data TargetOS
OSDebian :: TargetOS
OSBuntish :: TargetOS
OSArchLinux :: TargetOS
OSFreeBSD :: TargetOS

-- | Most of Debian ports are based on Linux. There also exist hurd-i386,
--   kfreebsd-i386, kfreebsd-amd64 ports
data DebianKernel
Linux :: DebianKernel
KFreeBSD :: DebianKernel
Hurd :: DebianKernel

-- | Debian has several rolling suites, and a number of stable releases,
--   such as Stable "stretch".
data DebianSuite
Experimental :: DebianSuite
Unstable :: DebianSuite
Testing :: DebianSuite
Stable :: Release -> DebianSuite

-- | FreeBSD breaks their releases into Production and
--   Legacy.
data FreeBSDRelease
FBSDProduction :: FBSDVersion -> FreeBSDRelease
FBSDLegacy :: FBSDVersion -> FreeBSDRelease
data FBSDVersion
FBSD101 :: FBSDVersion
FBSD102 :: FBSDVersion
FBSD093 :: FBSDVersion
isStable :: DebianSuite -> Bool
type Release = String

-- | Many of these architecture names are based on the names used by
--   Debian, with a few exceptions for clarity.
data Architecture

-- | 64 bit Intel, called "amd64" in Debian
X86_64 :: Architecture

-- | 32 bit Intel, called "i386" in Debian
X86_32 :: Architecture
ARMHF :: Architecture
ARMEL :: Architecture
PPC :: Architecture
PPC64 :: Architecture
SPARC :: Architecture
SPARC64 :: Architecture
MIPS :: Architecture
MIPSEL :: Architecture
MIPS64EL :: Architecture
SH4 :: Architecture

-- | Itanium
IA64 :: Architecture
S390 :: Architecture
S390X :: Architecture
ALPHA :: Architecture
HPPA :: Architecture
M68K :: Architecture
ARM64 :: Architecture

-- | New Linux ABI for 64 bit CPUs using 32-bit integers. Not widely used.
X32 :: Architecture
architectureToDebianArchString :: Architecture -> String
type HostName = String
type UserName = String
newtype User
User :: UserName -> User
newtype Group
Group :: String -> Group

-- | Makes a Group with the same name as the User.
userGroup :: User -> Group
newtype Port
Port :: Int -> Port
systemToTargetOS :: System -> TargetOS
instance GHC.Show.Show Propellor.Types.OS.Port
instance GHC.Classes.Ord Propellor.Types.OS.Port
instance GHC.Classes.Eq Propellor.Types.OS.Port
instance GHC.Show.Show Propellor.Types.OS.Group
instance GHC.Classes.Ord Propellor.Types.OS.Group
instance GHC.Classes.Eq Propellor.Types.OS.Group
instance GHC.Show.Show Propellor.Types.OS.User
instance GHC.Classes.Ord Propellor.Types.OS.User
instance GHC.Classes.Eq Propellor.Types.OS.User
instance GHC.Classes.Eq Propellor.Types.OS.System
instance GHC.Show.Show Propellor.Types.OS.System
instance GHC.Classes.Eq Propellor.Types.OS.Architecture
instance GHC.Show.Show Propellor.Types.OS.Architecture
instance GHC.Classes.Eq Propellor.Types.OS.Distribution
instance GHC.Show.Show Propellor.Types.OS.Distribution
instance GHC.Classes.Eq Propellor.Types.OS.DebianSuite
instance GHC.Show.Show Propellor.Types.OS.DebianSuite
instance GHC.Classes.Eq Propellor.Types.OS.FreeBSDRelease
instance GHC.Show.Show Propellor.Types.OS.FreeBSDRelease
instance GHC.Classes.Eq Propellor.Types.OS.FBSDVersion
instance GHC.Classes.Eq Propellor.Types.OS.DebianKernel
instance GHC.Show.Show Propellor.Types.OS.DebianKernel
instance GHC.Classes.Ord Propellor.Types.OS.TargetOS
instance GHC.Classes.Eq Propellor.Types.OS.TargetOS
instance GHC.Show.Show Propellor.Types.OS.TargetOS
instance Data.String.IsString Propellor.Types.OS.FBSDVersion
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Types.OS.FBSDVersion
instance GHC.Show.Show Propellor.Types.OS.FBSDVersion
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Types.OS.User
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Types.OS.Group
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Types.OS.Port

module Propellor.Types.Core

-- | Everything Propellor knows about a system: Its hostname, properties
--   and their collected info.
data Host
Host :: HostName -> [ChildProperty] -> Info -> Host
[hostName] :: Host -> HostName
[hostProperties] :: Host -> [ChildProperty]
[hostInfo] :: Host -> Info

-- | Propellor's monad provides read-only access to info about the host
--   it's running on, and a writer to accumulate EndActions.
newtype Propellor p
Propellor :: RWST Host [EndAction] () IO p -> Propellor p
[runWithHost] :: Propellor p -> RWST Host [EndAction] () IO p
class LiftPropellor m
liftPropellor :: LiftPropellor m => m a -> Propellor a

-- | When two actions are appended together, the second action is only run
--   if the first action does not fail.

-- | An action that Propellor runs at the end, after trying to satisfy all
--   properties. It's passed the combined Result of the entire Propellor
--   run.
data EndAction
EndAction :: Desc -> (Result -> Propellor Result) -> EndAction
type Desc = String

-- | Props is a combination of a list of properties, with their combined
--   metatypes.
data Props metatypes
Props :: [ChildProperty] -> Props metatypes

-- | Since there are many different types of Properties, they cannot be put
--   into a list. The simplified ChildProperty can be put into a list.
data ChildProperty
ChildProperty :: Desc -> (Maybe (Propellor Result)) -> Info -> [ChildProperty] -> ChildProperty
class IsProp p
setDesc :: IsProp p => p -> Desc -> p
getDesc :: IsProp p => p -> Desc
getChildren :: IsProp p => p -> [ChildProperty]
addChildren :: IsProp p => p -> [ChildProperty] -> p

-- | Gets the info of the property, combined with all info of all children
--   properties.
getInfoRecursive :: IsProp p => p -> Info

-- | Info, not including info from children.
getInfo :: IsProp p => p -> Info

-- | Gets a ChildProperty representing the Property. You should not
--   normally need to use this.
toChildProperty :: IsProp p => p -> ChildProperty

-- | Gets the action that can be run to satisfy a Property. You should
--   never run this action directly. Use ensureProperty instead.
getSatisfy :: IsProp p => p -> Maybe (Propellor Result)
instance GHC.Show.Show Propellor.Types.Core.Host
instance Control.Monad.Catch.MonadMask Propellor.Types.Core.Propellor
instance Control.Monad.Catch.MonadThrow Propellor.Types.Core.Propellor
instance Control.Monad.Catch.MonadCatch Propellor.Types.Core.Propellor
instance Control.Monad.IO.Class.MonadIO Propellor.Types.Core.Propellor
instance Control.Monad.Writer.Class.MonadWriter [Propellor.Types.Core.EndAction] Propellor.Types.Core.Propellor
instance Control.Monad.Reader.Class.MonadReader Propellor.Types.Core.Host Propellor.Types.Core.Propellor
instance GHC.Base.Applicative Propellor.Types.Core.Propellor
instance GHC.Base.Functor Propellor.Types.Core.Propellor
instance GHC.Base.Monad Propellor.Types.Core.Propellor
instance Propellor.Types.Core.LiftPropellor Propellor.Types.Core.Propellor
instance Propellor.Types.Core.LiftPropellor GHC.Types.IO
instance GHC.Base.Monoid (Propellor.Types.Core.Propellor Propellor.Types.Result.Result)
instance GHC.Show.Show Propellor.Types.Core.ChildProperty
instance Propellor.Types.Core.IsProp Propellor.Types.Core.ChildProperty

module Propellor.Types.Dns
type Domain = String
data IPAddr
IPv4 :: String -> IPAddr
IPv6 :: String -> IPAddr
newtype AliasesInfo
AliasesInfo :: (Set HostName) -> AliasesInfo
toAliasesInfo :: [HostName] -> AliasesInfo
fromAliasesInfo :: AliasesInfo -> [HostName]

-- | Use this for DNS Info that should propagate from a container to a
--   host. For example, this can be used for CNAME to make aliases of the
--   containers in the host be reflected in the DNS.
newtype DnsInfoPropagated
DnsInfoPropagated :: Set Record -> DnsInfoPropagated
[fromDnsInfoPropagated] :: DnsInfoPropagated -> Set Record
toDnsInfoPropagated :: Set Record -> DnsInfoPropagated

-- | Use this for DNS Info that should not propagate from a container to a
--   host. For example, an IP address of a container should not influence
--   the host.
newtype DnsInfoUnpropagated
DnsInfoUnpropagated :: Set Record -> DnsInfoUnpropagated
[fromDnsInfoUnpropagated] :: DnsInfoUnpropagated -> Set Record
toDnsInfoUnpropagated :: Set Record -> DnsInfoUnpropagated

-- | Get all DNS Info.
getDnsInfo :: Info -> Set Record

-- | Represents a bind 9 named.conf file.
data NamedConf
NamedConf :: Domain -> DnsServerType -> FilePath -> [IPAddr] -> [IPAddr] -> [String] -> NamedConf
[confDomain] :: NamedConf -> Domain
[confDnsServerType] :: NamedConf -> DnsServerType
[confFile] :: NamedConf -> FilePath
[confMasters] :: NamedConf -> [IPAddr]
[confAllowTransfer] :: NamedConf -> [IPAddr]
[confLines] :: NamedConf -> [String]
data DnsServerType
Master :: DnsServerType
Secondary :: DnsServerType

-- | Represents a bind 9 zone file.
data Zone
Zone :: Domain -> SOA -> [(BindDomain, Record)] -> Zone
[zDomain] :: Zone -> Domain
[zSOA] :: Zone -> SOA
[zHosts] :: Zone -> [(BindDomain, Record)]

-- | Every domain has a SOA record, which is big and complicated.
data SOA
SOA :: BindDomain -> SerialNumber -> Integer -> Integer -> Integer -> Integer -> SOA

-- | Typically ns1.your.domain
[sDomain] :: SOA -> BindDomain

-- | The most important parameter is the serial number, which must increase
--   after each change.
[sSerial] :: SOA -> SerialNumber
[sRefresh] :: SOA -> Integer
[sRetry] :: SOA -> Integer
[sExpire] :: SOA -> Integer
[sNegativeCacheTTL] :: SOA -> Integer

-- | Types of DNS records.
--   
--   This is not a complete list, more can be added.
data Record
Address :: IPAddr -> Record
CNAME :: BindDomain -> Record
MX :: Int -> BindDomain -> Record
NS :: BindDomain -> Record
TXT :: String -> Record
SRV :: Word16 -> Word16 -> Word16 -> BindDomain -> Record
SSHFP :: Int -> Int -> String -> Record
INCLUDE :: FilePath -> Record
PTR :: ReverseIP -> Record

-- | An in-addr.arpa record corresponding to an IPAddr.
type ReverseIP = String
reverseIP :: IPAddr -> ReverseIP

-- | Converts an IP address (particularly IPv6) to canonical, fully
--   expanded form.
canonicalIP :: IPAddr -> IPAddr
getIPAddr :: Record -> Maybe IPAddr
getCNAME :: Record -> Maybe BindDomain
getNS :: Record -> Maybe BindDomain

-- | Bind serial numbers are unsigned, 32 bit integers.
type SerialNumber = Word32

-- | Domains in the zone file must end with a period if they are absolute.
--   
--   Let's use a type to keep absolute domains straight from relative
--   domains.
--   
--   The RootDomain refers to the top level of the domain, so can be used
--   to add nameservers, MX's, etc to a domain.
data BindDomain
RelDomain :: Domain -> BindDomain
AbsDomain :: Domain -> BindDomain
RootDomain :: BindDomain
domainHostName :: BindDomain -> Maybe HostName
newtype NamedConfMap
NamedConfMap :: (Map Domain NamedConf) -> NamedConfMap

-- | Adding a Master NamedConf stanza for a particulr domain always
--   overrides an existing Secondary stanza for that domain, while a
--   Secondary stanza is only added when there is no existing Master
--   stanza.
fromNamedConfMap :: NamedConfMap -> Map Domain NamedConf
instance GHC.Show.Show Propellor.Types.Dns.NamedConfMap
instance GHC.Classes.Ord Propellor.Types.Dns.NamedConfMap
instance GHC.Classes.Eq Propellor.Types.Dns.NamedConfMap
instance GHC.Classes.Eq Propellor.Types.Dns.Zone
instance GHC.Show.Show Propellor.Types.Dns.Zone
instance GHC.Read.Read Propellor.Types.Dns.Zone
instance GHC.Classes.Eq Propellor.Types.Dns.SOA
instance GHC.Show.Show Propellor.Types.Dns.SOA
instance GHC.Read.Read Propellor.Types.Dns.SOA
instance GHC.Base.Monoid Propellor.Types.Dns.DnsInfoPropagated
instance GHC.Classes.Ord Propellor.Types.Dns.DnsInfoPropagated
instance GHC.Classes.Eq Propellor.Types.Dns.DnsInfoPropagated
instance GHC.Show.Show Propellor.Types.Dns.DnsInfoPropagated
instance GHC.Base.Monoid Propellor.Types.Dns.DnsInfoUnpropagated
instance GHC.Classes.Ord Propellor.Types.Dns.DnsInfoUnpropagated
instance GHC.Classes.Eq Propellor.Types.Dns.DnsInfoUnpropagated
instance GHC.Show.Show Propellor.Types.Dns.DnsInfoUnpropagated
instance GHC.Classes.Ord Propellor.Types.Dns.Record
instance GHC.Classes.Eq Propellor.Types.Dns.Record
instance GHC.Show.Show Propellor.Types.Dns.Record
instance GHC.Read.Read Propellor.Types.Dns.Record
instance GHC.Classes.Ord Propellor.Types.Dns.BindDomain
instance GHC.Classes.Eq Propellor.Types.Dns.BindDomain
instance GHC.Show.Show Propellor.Types.Dns.BindDomain
instance GHC.Read.Read Propellor.Types.Dns.BindDomain
instance GHC.Classes.Ord Propellor.Types.Dns.NamedConf
instance GHC.Classes.Eq Propellor.Types.Dns.NamedConf
instance GHC.Show.Show Propellor.Types.Dns.NamedConf
instance GHC.Classes.Ord Propellor.Types.Dns.DnsServerType
instance GHC.Classes.Eq Propellor.Types.Dns.DnsServerType
instance GHC.Show.Show Propellor.Types.Dns.DnsServerType
instance GHC.Base.Monoid Propellor.Types.Dns.AliasesInfo
instance GHC.Classes.Ord Propellor.Types.Dns.AliasesInfo
instance GHC.Classes.Eq Propellor.Types.Dns.AliasesInfo
instance GHC.Show.Show Propellor.Types.Dns.AliasesInfo
instance GHC.Classes.Ord Propellor.Types.Dns.IPAddr
instance GHC.Classes.Eq Propellor.Types.Dns.IPAddr
instance GHC.Show.Show Propellor.Types.Dns.IPAddr
instance GHC.Read.Read Propellor.Types.Dns.IPAddr
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Types.Dns.IPAddr
instance Propellor.Types.Info.IsInfo Propellor.Types.Dns.AliasesInfo
instance Propellor.Types.Info.IsInfo Propellor.Types.Dns.DnsInfoPropagated
instance Propellor.Types.Info.IsInfo Propellor.Types.Dns.DnsInfoUnpropagated
instance Propellor.Types.Info.IsInfo Propellor.Types.Dns.NamedConfMap
instance GHC.Base.Monoid Propellor.Types.Dns.NamedConfMap
instance Propellor.Types.Empty.Empty Propellor.Types.Dns.NamedConfMap

module Propellor.Types.MetaTypes
data MetaType

-- | A target OS of a Property
Targeting :: TargetOS -> MetaType

-- | Indicates that a Property has associated Info
WithInfo :: MetaType

-- | Any unix-like system
type UnixLike = MetaTypes '[Targeting OSDebian, Targeting OSBuntish, Targeting OSArchLinux, Targeting OSFreeBSD]

-- | Any linux system
type Linux = MetaTypes '[Targeting OSDebian, Targeting OSBuntish, Targeting OSArchLinux]

-- | Debian and derivatives.
type DebianLike = MetaTypes '[Targeting OSDebian, Targeting OSBuntish]
type Debian = MetaTypes '[Targeting OSDebian]
type Buntish = MetaTypes '[Targeting OSBuntish]
type ArchLinux = MetaTypes '[Targeting OSArchLinux]
type FreeBSD = MetaTypes '[Targeting OSFreeBSD]

-- | Used to indicate that a Property adds Info to the Host where it's
--   used.
type HasInfo = MetaTypes '[WithInfo]
type MetaTypes = Sing

-- | Convenience type operator to combine two MetaTypes lists.
--   
--   For example:
--   
--   
--   HasInfo + Debian
--   
--   
--   Which is shorthand for this type:
--   
--   
--   MetaTypes '[WithInfo, Targeting OSDebian]
--   
sing :: SingI t => Sing t

-- | A class used to pass singleton values implicitly.
class SingI t
sing :: SingI t => Sing t

-- | Every item in the subset must be in the superset.
--   
--   The name of this was chosen to make type errors more understandable.

-- | Combine two MetaTypes lists, yielding a list that has targets present
--   in both, and nontargets present in either.
data CheckCombine
CannotCombineTargets :: CheckCombine
CanCombine :: CheckCombine

-- | Checks if two MetaTypes lists can be safely combined.
--   
--   This should be used anywhere Combine is used, as an additional
--   constraint. For example:
--   
--   
--   foo :: (CheckCombinable x y ~ 'CanCombine) => x -> y -> Combine x y
--   

-- | Type level equality
--   
--   This is a very clumsy implmentation, but it works back to ghc 7.6.

-- | Type level union.
instance GHC.Classes.Ord Propellor.Types.MetaTypes.MetaType
instance GHC.Classes.Eq Propellor.Types.MetaTypes.MetaType
instance GHC.Show.Show Propellor.Types.MetaTypes.MetaType
instance Propellor.Types.Singletons.SingI ('Propellor.Types.MetaTypes.Targeting 'Propellor.Types.OS.OSDebian)
instance Propellor.Types.Singletons.SingI ('Propellor.Types.MetaTypes.Targeting 'Propellor.Types.OS.OSBuntish)
instance Propellor.Types.Singletons.SingI ('Propellor.Types.MetaTypes.Targeting 'Propellor.Types.OS.OSFreeBSD)
instance Propellor.Types.Singletons.SingI ('Propellor.Types.MetaTypes.Targeting 'Propellor.Types.OS.OSArchLinux)
instance Propellor.Types.Singletons.SingI 'Propellor.Types.MetaTypes.WithInfo
instance Propellor.Types.Singletons.SingKind 'Data.Proxy.KProxy

module Propellor.Types.PrivData

-- | Note that removing or changing constructors or changing types will
--   break the serialized privdata files, so don't do that! It's fine to
--   add new constructors.
data PrivDataField
DockerAuthentication :: PrivDataField

-- | Not used anymore, but retained to avoid breaking serialization of old
--   files
SshPubKey :: SshKeyType -> UserName -> PrivDataField

-- | For host key, use empty UserName
SshPrivKey :: SshKeyType -> UserName -> PrivDataField
SshAuthorizedKeys :: UserName -> PrivDataField
Password :: UserName -> PrivDataField
CryptPassword :: UserName -> PrivDataField
PrivFile :: FilePath -> PrivDataField
GpgKey :: PrivDataField
DnsSec :: DnsSecKey -> PrivDataField

-- | Combines a PrivDataField with a description of how to generate its
--   value.
data PrivDataSource
PrivDataSourceFile :: PrivDataField -> FilePath -> PrivDataSource
PrivDataSourceFileFromCommand :: PrivDataField -> FilePath -> String -> PrivDataSource
PrivDataSource :: PrivDataField -> String -> PrivDataSource
type PrivDataSourceDesc = String
class IsPrivDataSource s
privDataField :: IsPrivDataSource s => s -> PrivDataField
describePrivDataSource :: IsPrivDataSource s => s -> Maybe PrivDataSourceDesc

-- | A context in which a PrivDataField is used.
--   
--   Often this will be a domain name. For example, Context
--   "www.example.com" could be used for the SSL cert for the web server
--   serving that domain. Multiple hosts might use that privdata.
--   
--   This appears in serialized privdata files.
newtype Context
Context :: String -> Context

-- | A context that may vary depending on the HostName where it's used.
newtype HostContext
HostContext :: (HostName -> Context) -> HostContext
[mkHostContext] :: HostContext -> HostName -> Context

-- | Class of things that can be used as a Context.
class IsContext c
asContext :: IsContext c => HostName -> c -> Context
asHostContext :: IsContext c => c -> HostContext

-- | Use when a PrivDataField is not dependent on any paricular context.
anyContext :: Context

-- | Makes a HostContext that consists just of the hostname.
hostContext :: HostContext

-- | Contains the actual private data.
--   
--   Note that this may contain exta newlines at the end, or they may have
--   been stripped off, depending on how the user entered the privdata, and
--   which version of propellor stored it. Use the accessor functions below
--   to avoid newline problems.
newtype PrivData
PrivData :: String -> PrivData

-- | When PrivData is the content of a file, this is the lines thereof.
privDataLines :: PrivData -> [String]

-- | When the PrivData is a single value, like a password, this extracts
--   it. Note that if multiple lines are present in the PrivData, only the
--   first is returned; there is never a newline in the String.
privDataVal :: PrivData -> String

-- | Use to get ByteString out of PrivData.
privDataByteString :: PrivData -> ByteString
data SshKeyType
SshRsa :: SshKeyType
SshDsa :: SshKeyType
SshEcdsa :: SshKeyType
SshEd25519 :: SshKeyType

-- | Parameter that would be passed to ssh-keygen to generate key of this
--   type
sshKeyTypeParam :: SshKeyType -> String
data DnsSecKey

-- | DNSSEC Zone Signing Key (public)
PubZSK :: DnsSecKey

-- | DNSSEC Zone Signing Key (private)
PrivZSK :: DnsSecKey

-- | DNSSEC Key Signing Key (public)
PubKSK :: DnsSecKey

-- | DNSSEC Key Signing Key (private)
PrivKSK :: DnsSecKey
instance GHC.Classes.Eq Propellor.Types.PrivData.PrivDataField
instance GHC.Classes.Ord Propellor.Types.PrivData.PrivDataField
instance GHC.Show.Show Propellor.Types.PrivData.PrivDataField
instance GHC.Read.Read Propellor.Types.PrivData.PrivDataField
instance GHC.Enum.Enum Propellor.Types.PrivData.DnsSecKey
instance GHC.Enum.Bounded Propellor.Types.PrivData.DnsSecKey
instance GHC.Classes.Eq Propellor.Types.PrivData.DnsSecKey
instance GHC.Classes.Ord Propellor.Types.PrivData.DnsSecKey
instance GHC.Show.Show Propellor.Types.PrivData.DnsSecKey
instance GHC.Read.Read Propellor.Types.PrivData.DnsSecKey
instance GHC.Enum.Bounded Propellor.Types.PrivData.SshKeyType
instance GHC.Enum.Enum Propellor.Types.PrivData.SshKeyType
instance GHC.Classes.Eq Propellor.Types.PrivData.SshKeyType
instance GHC.Classes.Ord Propellor.Types.PrivData.SshKeyType
instance GHC.Show.Show Propellor.Types.PrivData.SshKeyType
instance GHC.Read.Read Propellor.Types.PrivData.SshKeyType
instance GHC.Classes.Eq Propellor.Types.PrivData.Context
instance GHC.Classes.Ord Propellor.Types.PrivData.Context
instance GHC.Show.Show Propellor.Types.PrivData.Context
instance GHC.Read.Read Propellor.Types.PrivData.Context
instance Propellor.Types.PrivData.IsPrivDataSource Propellor.Types.PrivData.PrivDataField
instance Propellor.Types.PrivData.IsPrivDataSource Propellor.Types.PrivData.PrivDataSource
instance GHC.Show.Show Propellor.Types.PrivData.HostContext
instance GHC.Classes.Ord Propellor.Types.PrivData.HostContext
instance GHC.Classes.Eq Propellor.Types.PrivData.HostContext
instance Propellor.Types.PrivData.IsContext Propellor.Types.PrivData.HostContext
instance Propellor.Types.PrivData.IsContext Propellor.Types.PrivData.Context

-- | Types for ZFS Properties.
--   
--   Copyright 2016 Evan Cofsky evan@theunixman.com License: BSD
--   2-clause
module Propellor.Types.ZFS

-- | A single ZFS filesystem.
data ZFS
ZFS :: ZPool -> ZDataset -> ZFS

-- | Represents a zpool.
data ZPool
ZPool :: String -> ZPool

-- | Represents a dataset in a zpool.
--   
--   Can be constructed from a / separated string.
data ZDataset
ZDataset :: [String] -> ZDataset
type ZFSProperties = Set ZFSProperty
fromList :: [ZFSProperty] -> ZFSProperties
toPropertyList :: ZFSProperties -> [(String, String)]
fromPropertyList :: [(String, String)] -> ZFSProperties
zfsName :: ZFS -> String
class Value a where fromValue = fromString
toValue :: Value a => a -> String
fromValue :: (Value a, IsString a) => String -> a
data ZFSYesNo
ZFSYesNo :: Bool -> ZFSYesNo
data ZFSOnOff
ZFSOnOff :: Bool -> ZFSOnOff
data ZFSSize
ZFSSize :: Integer -> ZFSSize
data ZFSString
ZFSString :: String -> ZFSString
data ZFSACLInherit
AIDiscard :: ZFSACLInherit
AINoAllow :: ZFSACLInherit
AISecure :: ZFSACLInherit
AIPassthrough :: ZFSACLInherit
data ZFSACLMode
AMDiscard :: ZFSACLMode
AMGroupmask :: ZFSACLMode
AMPassthrough :: ZFSACLMode
data ZFSProperty
Mounted :: ZFSYesNo -> ZFSProperty
Mountpoint :: ZFSString -> ZFSProperty
ReadOnly :: ZFSYesNo -> ZFSProperty
ACLInherit :: ZFSACLInherit -> ZFSProperty
ACLMode :: ZFSACLMode -> ZFSProperty
StringProperty :: String -> ZFSString -> ZFSProperty
toPair :: ZFSProperty -> (String, String)
fromPair :: (String, String) -> ZFSProperty
instance GHC.Classes.Ord Propellor.Types.ZFS.ZFSProperty
instance GHC.Classes.Eq Propellor.Types.ZFS.ZFSProperty
instance GHC.Show.Show Propellor.Types.ZFS.ZFSProperty
instance GHC.Classes.Ord Propellor.Types.ZFS.ZFSACLMode
instance GHC.Classes.Eq Propellor.Types.ZFS.ZFSACLMode
instance GHC.Show.Show Propellor.Types.ZFS.ZFSACLMode
instance GHC.Classes.Ord Propellor.Types.ZFS.ZFSACLInherit
instance GHC.Classes.Eq Propellor.Types.ZFS.ZFSACLInherit
instance GHC.Show.Show Propellor.Types.ZFS.ZFSACLInherit
instance GHC.Classes.Ord Propellor.Types.ZFS.ZFSString
instance GHC.Classes.Eq Propellor.Types.ZFS.ZFSString
instance GHC.Show.Show Propellor.Types.ZFS.ZFSString
instance GHC.Classes.Ord Propellor.Types.ZFS.ZFSSize
instance GHC.Classes.Eq Propellor.Types.ZFS.ZFSSize
instance GHC.Show.Show Propellor.Types.ZFS.ZFSSize
instance GHC.Classes.Ord Propellor.Types.ZFS.ZFSOnOff
instance GHC.Classes.Eq Propellor.Types.ZFS.ZFSOnOff
instance GHC.Show.Show Propellor.Types.ZFS.ZFSOnOff
instance GHC.Classes.Ord Propellor.Types.ZFS.ZFSYesNo
instance GHC.Classes.Eq Propellor.Types.ZFS.ZFSYesNo
instance GHC.Show.Show Propellor.Types.ZFS.ZFSYesNo
instance GHC.Classes.Ord Propellor.Types.ZFS.ZFS
instance GHC.Classes.Eq Propellor.Types.ZFS.ZFS
instance GHC.Show.Show Propellor.Types.ZFS.ZFS
instance GHC.Classes.Ord Propellor.Types.ZFS.ZDataset
instance GHC.Classes.Eq Propellor.Types.ZFS.ZDataset
instance GHC.Classes.Ord Propellor.Types.ZFS.ZPool
instance GHC.Classes.Eq Propellor.Types.ZFS.ZPool
instance GHC.Show.Show Propellor.Types.ZFS.ZPool
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Types.ZFS.ZDataset
instance GHC.Show.Show Propellor.Types.ZFS.ZDataset
instance Data.String.IsString Propellor.Types.ZFS.ZDataset
instance Data.String.IsString Propellor.Types.ZFS.ZPool
instance Propellor.Types.ZFS.Value Propellor.Types.ZFS.ZFSYesNo
instance Propellor.Types.ZFS.Value Propellor.Types.ZFS.ZFSOnOff
instance Propellor.Types.ZFS.Value Propellor.Types.ZFS.ZFSSize
instance Propellor.Types.ZFS.Value Propellor.Types.ZFS.ZFSString
instance Data.String.IsString Propellor.Types.ZFS.ZFSString
instance Data.String.IsString Propellor.Types.ZFS.ZFSYesNo
instance Data.String.IsString Propellor.Types.ZFS.ZFSOnOff
instance Data.String.IsString Propellor.Types.ZFS.ZFSACLInherit
instance Propellor.Types.ZFS.Value Propellor.Types.ZFS.ZFSACLInherit
instance Data.String.IsString Propellor.Types.ZFS.ZFSACLMode
instance Propellor.Types.ZFS.Value Propellor.Types.ZFS.ZFSACLMode

module Propellor.Types.CmdLine

-- | All the command line actions that propellor can perform.
data CmdLine
Run :: HostName -> CmdLine
Spin :: [HostName] -> (Maybe HostName) -> CmdLine
SimpleRun :: HostName -> CmdLine
Set :: PrivDataField -> Context -> CmdLine
Unset :: PrivDataField -> Context -> CmdLine
UnsetUnused :: CmdLine
Dump :: PrivDataField -> Context -> CmdLine
Edit :: PrivDataField -> Context -> CmdLine
ListFields :: CmdLine
AddKey :: String -> CmdLine
RmKey :: String -> CmdLine
Merge :: CmdLine
Serialized :: CmdLine -> CmdLine
Continue :: CmdLine -> CmdLine
Update :: (Maybe HostName) -> CmdLine
Relay :: HostName -> CmdLine
DockerInit :: HostName -> CmdLine
DockerChain :: HostName -> String -> CmdLine
ChrootChain :: HostName -> FilePath -> Bool -> Bool -> CmdLine
GitPush :: Fd -> Fd -> CmdLine
Check :: CmdLine
Build :: CmdLine
instance GHC.Classes.Eq Propellor.Types.CmdLine.CmdLine
instance GHC.Show.Show Propellor.Types.CmdLine.CmdLine
instance GHC.Read.Read Propellor.Types.CmdLine.CmdLine

module Propellor.Types

-- | Everything Propellor knows about a system: Its hostname, properties
--   and their collected info.
data Host
Host :: HostName -> [ChildProperty] -> Info -> Host
[hostName] :: Host -> HostName
[hostProperties] :: Host -> [ChildProperty]
[hostInfo] :: Host -> Info

-- | The core data type of Propellor, this represents a property that the
--   system should have, with a descrition, and an action to ensure it has
--   the property.
--   
--   There are different types of properties that target different OS's,
--   and so have different metatypes. For example: "Property DebianLike"
--   and "Property FreeBSD".
--   
--   Also, some properties have associated Info, which is indicated
--   in their type: "Property (HasInfo + DebianLike)"
--   
--   There are many associated type families, which are mostly used
--   internally, so you needn't worry about them.
data Property metatypes
Property :: metatypes -> Desc -> (Maybe (Propellor Result)) -> Info -> [ChildProperty] -> Property metatypes

-- | Constructs a Property, from a description and an action to run to
--   ensure the Property is met.
--   
--   Due to the polymorphic return type of this function, most uses will
--   need to specify a type signature. This lets you specify what OS the
--   property targets, etc.
--   
--   For example:
--   
--   
--   foo :: Property Debian
--   foo = property "foo" $ do
--   ...
--   	return MadeChange
--   
property :: SingI metatypes => Desc -> Propellor Result -> Property (MetaTypes metatypes)
property'' :: SingI metatypes => Desc -> Maybe (Propellor Result) -> Property (MetaTypes metatypes)
type Desc = String

-- | A property that can be reverted. The first Property is run normally
--   and the second is run when it's reverted.
--   
--   See Versioned for a way to use RevertableProperty to define
--   different versions of a host.
data RevertableProperty setupmetatypes undometatypes
RevertableProperty :: Property setupmetatypes -> Property undometatypes -> RevertableProperty setupmetatypes undometatypes
[setupRevertableProperty] :: RevertableProperty setupmetatypes undometatypes -> Property setupmetatypes
[undoRevertableProperty] :: RevertableProperty setupmetatypes undometatypes -> Property undometatypes

-- | Shorthand to construct a revertable property from any two Properties.
(<!>) :: Property setupmetatypes -> Property undometatypes -> RevertableProperty setupmetatypes undometatypes

-- | Propellor's monad provides read-only access to info about the host
--   it's running on, and a writer to accumulate EndActions.
newtype Propellor p
Propellor :: RWST Host [EndAction] () IO p -> Propellor p
[runWithHost] :: Propellor p -> RWST Host [EndAction] () IO p
class LiftPropellor m
liftPropellor :: LiftPropellor m => m a -> Propellor a

-- | Information about a Host, which can be provided by its properties.
--   
--   Many different types of data can be contained in the same Info value
--   at the same time. See toInfo and fromInfo.
data Info

-- | Any unix-like system
type UnixLike = MetaTypes '[Targeting OSDebian, Targeting OSBuntish, Targeting OSArchLinux, Targeting OSFreeBSD]

-- | Any linux system
type Linux = MetaTypes '[Targeting OSDebian, Targeting OSBuntish, Targeting OSArchLinux]

-- | Debian and derivatives.
type DebianLike = MetaTypes '[Targeting OSDebian, Targeting OSBuntish]
type Debian = MetaTypes '[Targeting OSDebian]
type Buntish = MetaTypes '[Targeting OSBuntish]
type ArchLinux = MetaTypes '[Targeting OSArchLinux]
type FreeBSD = MetaTypes '[Targeting OSFreeBSD]

-- | Used to indicate that a Property adds Info to the Host where it's
--   used.
type HasInfo = MetaTypes '[WithInfo]

-- | Convenience type operator to combine two MetaTypes lists.
--   
--   For example:
--   
--   
--   HasInfo + Debian
--   
--   
--   Which is shorthand for this type:
--   
--   
--   MetaTypes '[WithInfo, Targeting OSDebian]
--   
class TightenTargets p

-- | Tightens the MetaType list of a Property (or similar), to contain
--   fewer targets.
--   
--   For example, to make a property that uses apt-get, which is only
--   available on DebianLike systems:
--   
--   
--   upgraded :: Property DebianLike
--   upgraded = tightenTargets $ cmdProperty "apt-get" ["upgrade"]
--   
tightenTargets :: (TightenTargets p, (Targets untightened `NotSuperset` Targets tightened) ~ CanCombine, (NonTargets tightened `NotSuperset` NonTargets untightened) ~ CanCombine, SingI tightened) => p (MetaTypes untightened) -> p (MetaTypes tightened)
class Combines x y

-- | Combines together two properties, yielding a property that has the
--   description and info of the first, and that has the second property as
--   a child property.
combineWith :: Combines x y => ResultCombiner -> ResultCombiner -> x -> y -> CombinedType x y

-- | Type level calculation of the type that results from combining two
--   types of properties.
type ResultCombiner = Maybe (Propellor Result) -> Maybe (Propellor Result) -> Maybe (Propellor Result)

-- | Changes the action that is performed to satisfy a property.
adjustPropertySatisfy :: Property metatypes -> (Propellor Result -> Propellor Result) -> Property metatypes
instance GHC.Show.Show (Propellor.Types.Property metatypes)
instance GHC.Show.Show (Propellor.Types.RevertableProperty setupmetatypes undometatypes)
instance Propellor.Types.Core.IsProp (Propellor.Types.Property metatypes)
instance Propellor.Types.Core.IsProp (Propellor.Types.RevertableProperty setupmetatypes undometatypes)
instance forall a (x :: [a]) (y :: [a]). (Propellor.Types.MetaTypes.CheckCombinable x y ~ 'Propellor.Types.MetaTypes.CanCombine, Propellor.Types.Singletons.SingI (Propellor.Types.MetaTypes.Combine x y)) => Propellor.Types.Combines (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes x)) (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes y))
instance forall a a1 (x :: [a1]) (y :: [a1]) (x' :: [a]) (y' :: [a]). (Propellor.Types.MetaTypes.CheckCombinable x y ~ 'Propellor.Types.MetaTypes.CanCombine, Propellor.Types.MetaTypes.CheckCombinable x' y' ~ 'Propellor.Types.MetaTypes.CanCombine, Propellor.Types.Singletons.SingI (Propellor.Types.MetaTypes.Combine x y), Propellor.Types.Singletons.SingI (Propellor.Types.MetaTypes.Combine x' y')) => Propellor.Types.Combines (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes x) (Propellor.Types.MetaTypes.MetaTypes x')) (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes y) (Propellor.Types.MetaTypes.MetaTypes y'))
instance forall k a (x :: [a]) (y :: [a]) (x' :: k). (Propellor.Types.MetaTypes.CheckCombinable x y ~ 'Propellor.Types.MetaTypes.CanCombine, Propellor.Types.Singletons.SingI (Propellor.Types.MetaTypes.Combine x y)) => Propellor.Types.Combines (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes x) (Propellor.Types.MetaTypes.MetaTypes x')) (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes y))
instance forall k a (x :: [a]) (y :: [a]) (y' :: k). (Propellor.Types.MetaTypes.CheckCombinable x y ~ 'Propellor.Types.MetaTypes.CanCombine, Propellor.Types.Singletons.SingI (Propellor.Types.MetaTypes.Combine x y)) => Propellor.Types.Combines (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes x)) (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes y) (Propellor.Types.MetaTypes.MetaTypes y'))
instance Propellor.Types.TightenTargets Propellor.Types.Property
instance forall k (metatypes :: k). Propellor.Types.Singletons.SingI metatypes => GHC.Base.Monoid (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes metatypes))
instance (GHC.Base.Monoid (Propellor.Types.Property setupmetatypes), GHC.Base.Monoid (Propellor.Types.Property undometatypes)) => GHC.Base.Monoid (Propellor.Types.RevertableProperty setupmetatypes undometatypes)

module Propellor.Types.Bootloader

-- | Boot loader installed on a host.
data BootloaderInstalled
GrubInstalled :: GrubTarget -> BootloaderInstalled
FlashKernelInstalled :: BootloaderInstalled
UbootInstalled :: (FilePath -> FilePath -> Property Linux) -> BootloaderInstalled

-- | Platforms that grub can boot.
data GrubTarget
PC :: GrubTarget
EFI64 :: GrubTarget
EFI32 :: GrubTarget
Coreboot :: GrubTarget
Xen :: GrubTarget
instance GHC.Show.Show Propellor.Types.Bootloader.BootloaderInstalled
instance Propellor.Types.Info.IsInfo [Propellor.Types.Bootloader.BootloaderInstalled]

module Propellor.Types.Chroot
data ChrootInfo
ChrootInfo :: Map FilePath Host -> ChrootCfg -> ChrootInfo
[_chroots] :: ChrootInfo -> Map FilePath Host
[_chrootCfg] :: ChrootInfo -> ChrootCfg
data ChrootCfg
NoChrootCfg :: ChrootCfg
SystemdNspawnCfg :: [(String, Bool)] -> ChrootCfg
instance GHC.Show.Show Propellor.Types.Chroot.ChrootInfo
instance GHC.Classes.Eq Propellor.Types.Chroot.ChrootCfg
instance GHC.Show.Show Propellor.Types.Chroot.ChrootCfg
instance Propellor.Types.Info.IsInfo Propellor.Types.Chroot.ChrootInfo
instance GHC.Base.Monoid Propellor.Types.Chroot.ChrootInfo
instance Propellor.Types.Empty.Empty Propellor.Types.Chroot.ChrootInfo
instance GHC.Base.Monoid Propellor.Types.Chroot.ChrootCfg
instance Propellor.Types.Empty.Empty Propellor.Types.Chroot.ChrootCfg

module Propellor.Types.Docker
data DockerInfo
DockerInfo :: [DockerRunParam] -> Map String Host -> DockerInfo
[_dockerRunParams] :: DockerInfo -> [DockerRunParam]
[_dockerContainers] :: DockerInfo -> Map String Host
newtype DockerRunParam
DockerRunParam :: (HostName -> String) -> DockerRunParam
instance GHC.Show.Show Propellor.Types.Docker.DockerInfo
instance Propellor.Types.Info.IsInfo Propellor.Types.Docker.DockerInfo
instance GHC.Base.Monoid Propellor.Types.Docker.DockerInfo
instance Propellor.Types.Empty.Empty Propellor.Types.Docker.DockerInfo
instance GHC.Show.Show Propellor.Types.Docker.DockerRunParam

module Propellor.Property.Installer.Types

-- | The disk device to install to.
newtype TargetDiskDevice
TargetDiskDevice :: FilePath -> TargetDiskDevice
data DiskEraseConfirmed
DiskEraseConfirmed :: DiskEraseConfirmed

-- | Class of user input that an installer might prompt for.
class UserInput i

-- | Get the disk device the user selected to install to.
targetDiskDevice :: UserInput i => i -> Maybe TargetDiskDevice

-- | Check if the user has confirmed they want to erase the target disk
--   device.
diskEraseConfirmed :: UserInput i => i -> Maybe DiskEraseConfirmed
instance GHC.Show.Show Propellor.Property.Installer.Types.DiskEraseConfirmed
instance GHC.Read.Read Propellor.Property.Installer.Types.DiskEraseConfirmed
instance GHC.Show.Show Propellor.Property.Installer.Types.TargetDiskDevice
instance GHC.Read.Read Propellor.Property.Installer.Types.TargetDiskDevice


-- | This module handles all display of output to the console when
--   propellor is ensuring Properties.
--   
--   When two threads both try to display a message concurrently, the
--   messages will be displayed sequentially.
module Propellor.Message

-- | Serializable tracing. Export `PROPELLOR_TRACE=1` in the environment to
--   make propellor emit these to stdout, in addition to its other output.
data Trace
ActionStart :: (Maybe HostName) -> Desc -> Trace
ActionEnd :: (Maybe HostName) -> Desc -> Result -> Trace

-- | Given a line read from propellor, if it's a serialized Trace, parses
--   it.
parseTrace :: String -> Maybe Trace

-- | Gets the global MessageHandle.
getMessageHandle :: IO MessageHandle
isConsole :: MessageHandle -> Bool

-- | Force console output. This can be used when stdout is not directly
--   connected to a console, but is eventually going to be displayed at a
--   console.
forceConsole :: IO ()

-- | Shows a message while performing an action, with a colored status
--   display.
actionMessage :: (MonadIO m, MonadMask m, ActionResult r, ToResult r) => Desc -> m r -> m r

-- | Shows a message while performing an action on a specified host, with a
--   colored status display.
actionMessageOn :: (MonadIO m, MonadMask m, ActionResult r, ToResult r) => HostName -> Desc -> m r -> m r
warningMessage :: MonadIO m => String -> m ()
infoMessage :: MonadIO m => [String] -> m ()

-- | Displays the error message in red, and throws an exception.
--   
--   When used inside a property, the exception will make the current
--   property fail. Propellor will continue to the next property.
errorMessage :: MonadIO m => String -> m a

-- | Like errorMessage, but throws a StopPropellorException,
--   preventing propellor from continuing to the next property.
--   
--   Think twice before using this. Is the problem so bad that propellor
--   cannot try to ensure other properties? If not, use errorMessage
--   instead.
stopPropellorMessage :: MonadIO m => String -> m a

-- | Called when all messages about properties have been printed.
messagesDone :: IO ()

-- | Wrapper around createProcess that prevents multiple processes
--   that are running concurrently from writing to stdout/stderr at the
--   same time.
--   
--   If the process does not output to stdout or stderr, it's run by
--   createProcess entirely as usual. Only processes that can generate
--   output are handled specially:
--   
--   A process is allowed to write to stdout and stderr in the usual way,
--   assuming it can successfully take the output lock.
--   
--   When the output lock is held (ie, by another concurrent process, or
--   because outputConcurrent is being called at the same time), the
--   process is instead run with its stdout and stderr redirected to a
--   buffer. The buffered output will be displayed as soon as the output
--   lock becomes free.
--   
--   Currently only available on Unix systems, not Windows.
createProcessConcurrent :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ConcurrentProcessHandle)

-- | Use this around any actions that use outputConcurrent or
--   createProcessConcurrent
--   
--   This is necessary to ensure that buffered concurrent output actually
--   gets displayed before the program exits.
withConcurrentOutput :: (MonadIO m, MonadMask m) => m a -> m a
instance GHC.Show.Show Propellor.Message.Trace
instance GHC.Read.Read Propellor.Message.Trace

module Propellor.Location

-- | This is where propellor installs itself when deploying a host.
localdir :: FilePath

module Propellor.Info

-- | Specifies that a host's operating system is Debian, and further
--   indicates the suite and architecture.
--   
--   This provides info for other Properties, so they can act conditionally
--   on the details of the OS.
--   
--   It also lets the type checker know that all the properties of the host
--   must support Debian.
--   
--   
--   & osDebian (Stable "stretch") X86_64
--   
osDebian :: DebianSuite -> Architecture -> Property (HasInfo + Debian)

-- | Specifies that a host's operating system is a well-known Debian
--   derivative founded by a space tourist.
--   
--   (The actual name of this distribution is not used in Propellor per
--   http://joeyh.name/blog/entry/trademark_nonsense/)
osBuntish :: Release -> Architecture -> Property (HasInfo + Buntish)

-- | Specifies that a host's operating system is Arch Linux
osArchLinux :: Architecture -> Property (HasInfo + ArchLinux)

-- | Specifies that a host's operating system is FreeBSD and further
--   indicates the release and architecture.
osFreeBSD :: FreeBSDRelease -> Architecture -> Property (HasInfo + FreeBSD)

-- | Adds info to a Property.
--   
--   The new Property will include HasInfo in its metatypes.
setInfoProperty :: (MetaTypes metatypes' ~ (+) HasInfo metatypes, SingI metatypes') => Property metatypes -> Info -> Property (MetaTypes metatypes')

-- | Adds more info to a Property that already HasInfo.
addInfoProperty :: (IncludesInfo metatypes ~ True) => Property metatypes -> Info -> Property metatypes

-- | Makes a property that does nothing but set some Info.
pureInfoProperty :: (IsInfo v) => Desc -> v -> Property (HasInfo + UnixLike)
pureInfoProperty' :: Desc -> Info -> Property (HasInfo + UnixLike)

-- | Gets a value from the host's Info.
askInfo :: (IsInfo v) => Propellor v
getOS :: Propellor (Maybe System)

-- | Indicate that a host has an A record in the DNS.
--   
--   When propellor is used to deploy a DNS server for a domain, the hosts
--   in the domain are found by looking for these and similar properites.
--   
--   When propellor --spin is used to deploy a host, it checks if the
--   host's IP Property matches the DNS. If the DNS is missing or out of
--   date, the host will instead be contacted directly by IP address.
ipv4 :: String -> Property (HasInfo + UnixLike)

-- | Indicate that a host has an AAAA record in the DNS.
ipv6 :: String -> Property (HasInfo + UnixLike)

-- | Indicates another name for the host in the DNS.
--   
--   When the host's ipv4/ipv6 addresses are known, the alias is set up to
--   use their address, rather than using a CNAME. This avoids various
--   problems with CNAMEs, and also means that when multiple hosts have the
--   same alias, a DNS round-robin is automatically set up.
alias :: Domain -> Property (HasInfo + UnixLike)

-- | Add a DNS Record.
addDNS :: Bool -> Record -> Property (HasInfo + UnixLike)
hostMap :: [Host] -> Map HostName Host
aliasMap :: [Host] -> Map HostName Host
findHost :: [Host] -> HostName -> Maybe Host
findHostNoAlias :: [Host] -> HostName -> Maybe Host
getAddresses :: Info -> [IPAddr]
hostAddresses :: HostName -> [Host] -> [IPAddr]

module Propellor.PrivData

-- | Allows a Property to access the value of a specific PrivDataField, for
--   use in a specific Context or HostContext.
--   
--   Example use:
--   
--   
--   withPrivData (PrivFile pemfile) (Context "joeyh.name") $ \getdata ->
--       property "joeyh.name ssl cert" $ getdata $ \privdata ->
--         liftIO $ writeFile pemfile (privDataVal privdata)
--     where pemfile = "/etc/ssl/certs/web.pem"
--   
--   
--   Note that if the value is not available, the action is not run and
--   instead it prints a message to help the user make the necessary
--   private data available.
--   
--   The resulting Property includes Info about the PrivDataField being
--   used, which is necessary to ensure that the privdata is sent to the
--   remote host by propellor.
withPrivData :: (IsContext c, IsPrivDataSource s, IncludesInfo metatypes ~ True) => s -> c -> (((PrivData -> Propellor Result) -> Propellor Result) -> Property metatypes) -> Property metatypes
withSomePrivData :: (IsContext c, IsPrivDataSource s, IncludesInfo metatypes ~ True) => [s] -> c -> ((((PrivDataField, PrivData) -> Propellor Result) -> Propellor Result) -> Property metatypes) -> Property metatypes
addPrivData :: (PrivDataField, Maybe PrivDataSourceDesc, HostContext) -> Property (HasInfo + UnixLike)
setPrivData :: PrivDataField -> Context -> IO ()
unsetPrivData :: PrivDataField -> Context -> IO ()
unsetPrivDataUnused :: [Host] -> IO ()
dumpPrivData :: PrivDataField -> Context -> IO ()
editPrivData :: PrivDataField -> Context -> IO ()

-- | Get only the set of PrivData that the Host's Info says it uses.
filterPrivData :: Host -> PrivMap -> PrivMap
listPrivDataFields :: [Host] -> IO ()
makePrivDataDir :: IO ()
decryptPrivData :: IO PrivMap
readPrivData :: String -> PrivMap
readPrivDataFile :: FilePath -> IO PrivMap
type PrivMap = Map (PrivDataField, Context) String
data PrivInfo

-- | Sets the context of any privdata that uses HostContext to the provided
--   name.
forceHostContext :: String -> PrivInfo -> PrivInfo
instance GHC.Base.Monoid Propellor.PrivData.PrivInfo
instance GHC.Show.Show Propellor.PrivData.PrivInfo
instance GHC.Classes.Ord Propellor.PrivData.PrivInfo
instance GHC.Classes.Eq Propellor.PrivData.PrivInfo
instance Propellor.Types.Info.IsInfo Propellor.PrivData.PrivInfo

module Propellor.Exception

-- | Catches all exceptions (except for StopPropellorException and
--   AsyncException and SomeAsyncException) and returns
--   FailedChange.
catchPropellor :: (MonadIO m, MonadCatch m) => m Result -> m Result
catchPropellor' :: MonadCatch m => m a -> (SomeException -> m a) -> m a

-- | Catches all exceptions (except for StopPropellorException and
--   AsyncException).
tryPropellor :: MonadCatch m => m a -> m (Either SomeException a)

module Propellor.Types.ResultCheck

-- | This is a Property but its Result is not accurate; in
--   particular it may return NoChange despite having made a change.
--   
--   However, when it returns MadeChange, it really did make a
--   change, and FailedChange is still an error.
data UncheckedProperty i

-- | Use to indicate that a Property is unchecked.
unchecked :: Property i -> UncheckedProperty i

-- | Checks the result of a property. Mostly used to convert a
--   UncheckedProperty to a Property, but can also be used to
--   further check a Property.
checkResult :: (Checkable p i, LiftPropellor m) => m a -> (a -> m Result) -> p i -> Property i

-- | Makes a Property or an UncheckedProperty only run when a
--   test succeeds.
check :: (Checkable p i, LiftPropellor m) => m Bool -> p i -> Property i
class Checkable p i

-- | Sometimes it's not practical to test if a property made a change. In
--   such a case, it's often fine to say:
--   
--   
--   someprop `assume` MadeChange
--   
--   
--   However, beware assuming NoChange, as that will make
--   combinators like onChange not work.
assume :: Checkable p i => p i -> Result -> Property i
instance Propellor.Types.TightenTargets Propellor.Types.ResultCheck.UncheckedProperty
instance Propellor.Types.ResultCheck.Checkable Propellor.Types.Property i
instance Propellor.Types.ResultCheck.Checkable Propellor.Types.ResultCheck.UncheckedProperty i

module Propellor.EnsureProperty

-- | For when code running in the Propellor monad needs to ensure a
--   Property.
--   
--   Use property' to get the OuterMetaTypesWithness. For
--   example:
--   
--   
--   foo = Property Debian
--   foo = property' "my property" $ \w -> do
--   	ensureProperty w (aptInstall "foo")
--   
--   
--   The type checker will prevent using ensureProperty with a property
--   that does not support the target OSes needed by the
--   OuterMetaTypesWitness. In the example above, aptInstall must support
--   Debian, since foo is supposed to support Debian.
--   
--   The type checker will also prevent using ensureProperty with a
--   property with HasInfo in its MetaTypes. Doing so would cause the
--   Info associated with the property to be lost.
ensureProperty :: (Cannot_ensureProperty_WithInfo inner ~ True, (Targets inner `NotSuperset` Targets outer) ~ CanCombine) => OuterMetaTypesWitness outer -> Property (MetaTypes inner) -> Propellor Result

-- | Constructs a property, like property, but provides its
--   OuterMetaTypesWitness.
property' :: SingI metatypes => Desc -> (OuterMetaTypesWitness metatypes -> Propellor Result) -> Property (MetaTypes metatypes)

-- | Used to provide the metatypes of a Property to calls to
--   ensureProperty within it.
newtype OuterMetaTypesWitness metatypes
OuterMetaTypesWitness :: (MetaTypes metatypes) -> OuterMetaTypesWitness metatypes

module Propellor.Property

-- | Indicates that the first property depends on the second, so before the
--   first is ensured, the second must be ensured.
--   
--   The combined property uses the description of the first property.
requires :: Combines x y => x -> y -> CombinedType x y

-- | Combines together two properties, resulting in one property that
--   ensures the first, and if the first succeeds, ensures the second.
--   
--   The combined property uses the description of the first property.
before :: Combines x y => x -> y -> CombinedType x y

-- | Whenever a change has to be made for a Property, causes a hook
--   Property to also be run, but not otherwise.
onChange :: (Combines x y) => x -> y -> CombinedType x y

-- | Same as onChange except that if property y fails, a flag file
--   is generated. On next run, if the flag file is present, property y is
--   executed even if property x doesn't change.
--   
--   With onChange, if y fails, the property x onChange y
--   returns FailedChange. But if this property is applied again, it
--   returns NoChange. This behavior can cause trouble...
onChangeFlagOnFail :: (Combines x y) => FilePath -> x -> y -> CombinedType x y

-- | Makes a perhaps non-idempotent Property be idempotent by using a flag
--   file to indicate whether it has run before. Use with caution.
flagFile :: Property i -> FilePath -> Property i
flagFile' :: Property i -> IO FilePath -> Property i

-- | Makes a Property or an UncheckedProperty only run when a
--   test succeeds.
check :: (Checkable p i, LiftPropellor m) => m Bool -> p i -> Property i

-- | Tries the first property, but if it fails to work, instead uses the
--   second.
fallback :: (Combines p1 p2) => p1 -> p2 -> CombinedType p1 p2

-- | Undoes the effect of a RevertableProperty.
revert :: RevertableProperty setup undo -> RevertableProperty undo setup

-- | Changes the description of a property.
describe :: IsProp p => p -> Desc -> p

-- | Alias for flip describe
(==>) :: IsProp (Property i) => Desc -> Property i -> Property i
infixl 1 ==>

-- | Propellor's monad provides read-only access to info about the host
--   it's running on, and a writer to accumulate EndActions.
data Propellor p

-- | Constructs a Property, from a description and an action to run to
--   ensure the Property is met.
--   
--   Due to the polymorphic return type of this function, most uses will
--   need to specify a type signature. This lets you specify what OS the
--   property targets, etc.
--   
--   For example:
--   
--   
--   foo :: Property Debian
--   foo = property "foo" $ do
--   ...
--   	return MadeChange
--   
property :: SingI metatypes => Desc -> Propellor Result -> Property (MetaTypes metatypes)

-- | Constructs a property, like property, but provides its
--   OuterMetaTypesWitness.
property' :: SingI metatypes => Desc -> (OuterMetaTypesWitness metatypes -> Propellor Result) -> Property (MetaTypes metatypes)

-- | Used to provide the metatypes of a Property to calls to
--   ensureProperty within it.
data OuterMetaTypesWitness metatypes

-- | For when code running in the Propellor monad needs to ensure a
--   Property.
--   
--   Use property' to get the OuterMetaTypesWithness. For
--   example:
--   
--   
--   foo = Property Debian
--   foo = property' "my property" $ \w -> do
--   	ensureProperty w (aptInstall "foo")
--   
--   
--   The type checker will prevent using ensureProperty with a property
--   that does not support the target OSes needed by the
--   OuterMetaTypesWitness. In the example above, aptInstall must support
--   Debian, since foo is supposed to support Debian.
--   
--   The type checker will also prevent using ensureProperty with a
--   property with HasInfo in its MetaTypes. Doing so would cause the
--   Info associated with the property to be lost.
ensureProperty :: (Cannot_ensureProperty_WithInfo inner ~ True, (Targets inner `NotSuperset` Targets outer) ~ CanCombine) => OuterMetaTypesWitness outer -> Property (MetaTypes inner) -> Propellor Result

-- | Picks one of the two input properties to use, depending on the
--   targeted OS.
--   
--   If both input properties support the targeted OS, then the first will
--   be used.
--   
--   The resulting property will use the description of the first property
--   no matter which property is used in the end. So, it's often a good
--   idea to change the description to something clearer.
--   
--   For example:
--   
--   
--   upgraded :: Property (DebianLike + FreeBSD)
--   upgraded = (Apt.upgraded `pickOS` Pkg.upgraded)
--   	`describe` "OS upgraded"
--   
--   
--   If neither input property supports the targeted OS, calls
--   unsupportedOS. Using the example above on a Fedora system would
--   fail that way.
pickOS :: HasCallStack => (SingKind (KProxy :: KProxy ka), SingKind (KProxy :: KProxy kb), DemoteRep (KProxy :: KProxy ka) ~ [MetaType], DemoteRep (KProxy :: KProxy kb) ~ [MetaType], SingI c) => Property (MetaTypes (a :: ka)) -> Property (MetaTypes (b :: kb)) -> Property (MetaTypes c)

-- | Makes a property that is satisfied differently depending on specifics
--   of the host's operating system.
--   
--   
--   myproperty :: Property Debian
--   myproperty = withOS "foo installed" $ \w o -> case o of
--   	(Just (System (Debian kernel (Stable release)) arch)) -> ensureProperty w ...
--   	(Just (System (Debian kernel suite) arch)) -> ensureProperty w ...
--   _ -> unsupportedOS'
--   
--   
--   Note that the operating system specifics may not be declared for all
--   hosts, which is where Nothing comes in.
withOS :: (SingI metatypes) => Desc -> (OuterMetaTypesWitness '[] -> Maybe System -> Propellor Result) -> Property (MetaTypes metatypes)

-- | A property that always fails with an unsupported OS error.
unsupportedOS :: Property UnixLike

-- | Throws an error, for use in withOS when a property is lacking
--   support for an OS.
unsupportedOS' :: HasCallStack => Propellor Result
makeChange :: IO () -> Propellor Result
noChange :: Propellor Result

-- | A no-op property.
--   
--   This is the same as mempty from the Monoid instance.
doNothing :: SingI t => Property (MetaTypes t)

-- | In situations where it's not possible to provide a property that
--   works, this can be used to make a property that always fails with an
--   error message you provide.
impossible :: SingI t => String -> Property (MetaTypes t)

-- | Registers an action that should be run at the very end, after
--   propellor has checks all the properties of a host.
endAction :: Desc -> (Result -> Propellor Result) -> Propellor ()

-- | This is a Property but its Result is not accurate; in
--   particular it may return NoChange despite having made a change.
--   
--   However, when it returns MadeChange, it really did make a
--   change, and FailedChange is still an error.
data UncheckedProperty i

-- | Use to indicate that a Property is unchecked.
unchecked :: Property i -> UncheckedProperty i

-- | Indicates that a Property may change a particular file. When the file
--   is modified in any way (including changing its permissions or mtime),
--   the property will return MadeChange instead of NoChange.
changesFile :: Checkable p i => p i -> FilePath -> Property i

-- | Like changesFile, but compares the content of the file. Changes
--   to mtime etc that do not change file content are treated as NoChange.
changesFileContent :: Checkable p i => p i -> FilePath -> Property i

-- | Determines if the first file is newer than the second file.
--   
--   This can be used with check to only run a command when a file
--   has changed.
--   
--   
--   check ("/etc/aliases" `isNewerThan` "/etc/aliases.db")
--   	(cmdProperty "newaliases" [] `assume` MadeChange) -- updates aliases.db
--   
--   
--   Or it can be used with checkResult to test if a command made a
--   change.
--   
--   
--   checkResult (return ())
--   	(\_ -> "/etc/aliases.db" `isNewerThan` "/etc/aliases")
--   	(cmdProperty "newaliases" [])
--   
--   
--   (If one of the files does not exist, the file that does exist is
--   considered to be the newer of the two.)
isNewerThan :: FilePath -> FilePath -> IO Bool

-- | Checks the result of a property. Mostly used to convert a
--   UncheckedProperty to a Property, but can also be used to
--   further check a Property.
checkResult :: (Checkable p i, LiftPropellor m) => m a -> (a -> m Result) -> p i -> Property i
class Checkable p i

-- | Sometimes it's not practical to test if a property made a change. In
--   such a case, it's often fine to say:
--   
--   
--   someprop `assume` MadeChange
--   
--   
--   However, beware assuming NoChange, as that will make
--   combinators like onChange not work.
assume :: Checkable p i => p i -> Result -> Property i

module Propellor.PropAccum

-- | Defines a host and its properties.
--   
--   
--   host "example.com" $ props
--   	& someproperty
--   	! oldproperty
--   	& otherproperty
--   
host :: HostName -> Props metatypes -> Host

-- | Props is a combination of a list of properties, with their combined
--   metatypes.
data Props metatypes
Props :: [ChildProperty] -> Props metatypes

-- | Start accumulating a list of properties.
--   
--   Properties can be added to it using `(&amp;)` etc.
props :: Props UnixLike

-- | Adds a property to a Props.
--   
--   Can add Properties and RevertableProperties
(&) :: (IsProp p, MetaTypes y ~ GetMetaTypes p, CheckCombinable x y ~ CanCombine) => Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
infixl 1 &

-- | Adds a property before any other properties.
(&^) :: (IsProp p, MetaTypes y ~ GetMetaTypes p, CheckCombinable x y ~ CanCombine) => Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
infixl 1 &^

-- | Adds a property in reverted form.
(!) :: (CheckCombinable x z ~ CanCombine) => Props (MetaTypes x) -> RevertableProperty (MetaTypes y) (MetaTypes z) -> Props (MetaTypes (Combine x z))
infixl 1 !

-- | This module lets you construct Properties by running commands and
--   scripts. To get from an UncheckedProperty to a Property,
--   it's up to the user to check if the command made a change to the
--   system.
--   
--   The best approach is to check a property, so that the command
--   is only run when it needs to be. With this method, you avoid running
--   the cmdProperty unnecessarily.
--   
--   
--   check (not <$> userExists "bob")
--   	(cmdProperty "useradd" ["bob"])
--   
--   
--   Sometimes it's just as expensive to check a property as it would be to
--   run the command that ensures the property. So you can let the command
--   run every time, and use changesFile or checkResult to
--   determine if anything changed:
--   
--   
--   cmdProperty "chmod" ["600", "/etc/secret"]
--   	`changesFile` "/etc/secret"
--   
--   
--   Or you can punt and assume a change was made, but then
--   propellor will always say it make a change, and onChange will
--   always fire.
--   
--   
--   cmdProperty "service" ["foo", "reload"]
--   	`assume` MadeChange
--   
module Propellor.Property.Cmd

-- | A property that can be satisfied by running a command.
--   
--   The command must exit 0 on success.
cmdProperty :: String -> [String] -> UncheckedProperty UnixLike
cmdProperty' :: String -> [String] -> (CreateProcess -> CreateProcess) -> UncheckedProperty UnixLike

-- | A property that can be satisfied by running a command, with added
--   environment variables in addition to the standard environment.
cmdPropertyEnv :: String -> [String] -> [(String, String)] -> UncheckedProperty UnixLike

-- | A series of shell commands. (Without a leading hashbang.)
type Script = [String]

-- | A property that can be satisfied by running a script.
scriptProperty :: Script -> UncheckedProperty UnixLike

-- | A property that can satisfied by running a script as user (cd'd to
--   their home directory).
userScriptProperty :: User -> Script -> UncheckedProperty UnixLike
cmdResult :: Bool -> Result

-- | Parameters that can be passed to a shell command.
data CommandParam

-- | A parameter
Param :: String -> CommandParam

-- | The name of a file
File :: FilePath -> CommandParam

-- | Run a system command, and returns True or False if it succeeded or
--   failed.
--   
--   This and other command running functions in this module log the
--   commands run at debug level, using System.Log.Logger.
boolSystem :: FilePath -> [CommandParam] -> IO Bool
boolSystemEnv :: FilePath -> [CommandParam] -> Maybe [(String, String)] -> IO Bool

-- | Runs a system command, returning the exit status.
safeSystem :: FilePath -> [CommandParam] -> IO ExitCode
safeSystemEnv :: FilePath -> [CommandParam] -> Maybe [(String, String)] -> IO ExitCode

-- | Escapes a filename or other parameter to be safely able to be exposed
--   to the shell.
--   
--   This method works for POSIX shells, as well as other shells like csh.
shellEscape :: String -> String

-- | Wrapper around createProcess that does debug logging.
createProcess :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)

-- | Wrapper around waitForProcess that does debug logging.
waitForProcess :: ProcessHandle -> IO ExitCode

module Propellor.Engine

-- | Gets the Properties of a Host, and ensures them all, with nice display
--   of what's being done.
mainProperties :: Host -> IO ()

-- | Runs a Propellor action with the specified host.
--   
--   If the Result is not FailedChange, any EndActions that were
--   accumulated while running the action are then also run.
runPropellor :: Host -> Propellor Result -> IO Result

-- | Ensures the child properties, with a display of each as it runs.
ensureChildProperties :: [ChildProperty] -> Propellor Result

-- | Lifts an action into the context of a different host.
--   
--   
--   fromHost hosts "otherhost" Ssh.getHostPubKey
--   
fromHost :: [Host] -> HostName -> Propellor a -> Propellor (Maybe a)
fromHost' :: Host -> Propellor a -> Propellor a
onlyProcess :: FilePath -> IO a -> IO a

-- | Chains to a propellor sub-Process, forwarding its output on to the
--   display, except for the last line which is a Result.
chainPropellor :: CreateProcess -> IO Result

-- | Used by propellor sub-Processes that are run by chainPropellor.
runChainPropellor :: Host -> Propellor Result -> IO ()

module Propellor.Property.List

-- | Start accumulating a list of properties.
--   
--   Properties can be added to it using `(&amp;)` etc.
props :: Props UnixLike

-- | Props is a combination of a list of properties, with their combined
--   metatypes.
data Props metatypes
toProps :: [Property (MetaTypes metatypes)] -> Props (MetaTypes metatypes)

-- | Combines a list of properties, resulting in a single property that
--   when run will run each property in the list in turn, and print out the
--   description of each as it's run. Does not stop on failure; does
--   propagate overall success/failure.
--   
--   For example:
--   
--   
--   propertyList "foo" $ props
--   	& bar
--   	& baz
--   
propertyList :: SingI metatypes => Desc -> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)

-- | Combines a list of properties, resulting in one property that ensures
--   each in turn. Stops if a property fails.
--   
--   
--   combineProperties "foo" $ props
--   	& bar
--   	& baz
--   
--   
--   This is similar to using mconcat with a list of properties,
--   except it can combine together different types of properties.
combineProperties :: SingI metatypes => Desc -> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)

module Propellor.Debug
debug :: [String] -> IO ()
checkDebugMode :: IO ()
enableDebugMode :: IO ()

module Propellor.Container
class IsContainer c
containerProperties :: IsContainer c => c -> [ChildProperty]
containerInfo :: IsContainer c => c -> Info
setContainerProperties :: IsContainer c => c -> [ChildProperty] -> c

-- | Note that the metatype of a container's properties is not retained, so
--   this defaults to UnixLike. So, using this with setContainerProps can
--   add properties to a container that conflict with properties already in
--   it. Use caution when using this; only add properties that do not have
--   restricted targets.
containerProps :: IsContainer c => c -> Props UnixLike
setContainerProps :: IsContainer c => c -> Props metatypes -> c

-- | Adjust the provided Property, adding to its propertyChidren the
--   properties of the provided container.
--   
--   The Info of the propertyChildren is adjusted to only include info that
--   should be propagated out to the Property.
--   
--   Any PrivInfo that uses HostContext is adjusted to use the name of the
--   container as its context.
propagateContainer :: (IncludesInfo metatypes ~ True, IsContainer c) => String -> c -> (PropagateInfo -> Bool) -> Property metatypes -> Property metatypes

-- | Filters out parts of the Info that should not propagate out of a
--   container.
propagatableInfo :: (PropagateInfo -> Bool) -> Info -> Info
normalContainerInfo :: PropagateInfo -> Bool
onlyPrivData :: PropagateInfo -> Bool
instance Propellor.Container.IsContainer Propellor.Types.Core.Host

-- | Pulls in lots of useful modules for building and using Properties.
module Propellor.Base

-- | Propellor properties can be made to run concurrently, using this
--   module. This can speed up propellor, at the expense of using more CPUs
--   and other resources.
--   
--   It's up to you to make sure that properties that you make run
--   concurrently don't implicitly depend on one-another. The worst that
--   can happen though, is that propellor fails to ensure some of the
--   properties, and tells you what went wrong.
--   
--   Another potential problem is that output of concurrent properties
--   could interleave into a scrambled mess. This is mostly prevented; all
--   messages output by propellor are concurrency safe, including
--   errorMessage, infoMessage, etc. However, if you write a
--   property that directly uses print or putStrLn, you can
--   still experience this problem.
--   
--   Similarly, when properties run external commands, the command's output
--   can be a problem for concurrency. No need to worry;
--   createProcess is concurrent output safe (it actually uses
--   createProcessConcurrent), and everything else in propellor that
--   runs external commands is built on top of that. Of course, if you
--   import System.Process and use it in a property, you can bypass that
--   and shoot yourself in the foot.
--   
--   Finally, anything that directly accesses the tty can bypass these
--   protections. That's sometimes done for eg, password prompts. A
--   well-written property should avoid running interactive commands
--   anyway.
module Propellor.Property.Concurrent

-- | Ensures two properties concurrently.
--   
--   
--   & foo `concurrently` bar
--   
--   
--   To ensure three properties concurrently, just use this combinator
--   twice:
--   
--   
--   & foo `concurrently` bar `concurrently` baz
--   
concurrently :: (IsProp p1, IsProp p2, Combines p1 p2, IsProp (CombinedType p1 p2)) => p1 -> p2 -> CombinedType p1 p2

-- | Ensures all the properties in the list, with a specified amount of
--   concurrency.
--   
--   
--   concurrentList (pure 2) "demo" $ props
--   & foo
--   & bar
--   & baz
--   
--   
--   The above example will run foo and bar concurrently, and once either
--   of those 2 properties finishes, will start running baz.
concurrentList :: SingI metatypes => IO Int -> Desc -> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)

-- | Start accumulating a list of properties.
--   
--   Properties can be added to it using `(&amp;)` etc.
props :: Props UnixLike
getNumProcessors :: IO Int

-- | Running Propellor actions concurrently.
concurrentSatisfy :: Propellor Result -> Propellor Result -> Propellor Result

module Propellor.Property.File
type Line = String

-- | Replaces all the content of a file.
hasContent :: FilePath -> [Line] -> Property UnixLike

-- | Ensures that a line is present in a file, adding it to the end if not.
--   
--   For example:
--   
--   
--   & "/etc/default/daemon.conf" `File.containsLine` ("cachesize = " ++ val 1024)
--   
--   
--   The above example uses val to serialize a
--   ConfigurableValue
containsLine :: FilePath -> Line -> Property UnixLike

-- | Ensures that a list of lines are present in a file, adding any that
--   are not to the end of the file.
--   
--   Note that this property does not guarantee that the lines will appear
--   consecutively, nor in the order specified. If you need either of
--   these, use containsBlock.
containsLines :: FilePath -> [Line] -> Property UnixLike

-- | Ensures that a block of consecutive lines is present in a file, adding
--   it to the end if not. Revert to ensure that the block is not present
--   (though the lines it contains could be present, non-consecutively).
containsBlock :: FilePath -> [Line] -> RevertableProperty UnixLike UnixLike

-- | Ensures that a line is not present in a file. Note that the file is
--   ensured to exist, so if it doesn't, an empty file will be written.
lacksLine :: FilePath -> Line -> Property UnixLike
lacksLines :: FilePath -> [Line] -> Property UnixLike

-- | Replaces all the content of a file, ensuring that its modes do not
--   allow it to be read or written by anyone other than the current user
hasContentProtected :: FilePath -> [Line] -> Property UnixLike

-- | Ensures a file has contents that comes from PrivData.
--   
--   The file's permissions are preserved if the file already existed.
--   Otherwise, they're set to 600.
hasPrivContent :: IsContext c => FilePath -> c -> Property (HasInfo + UnixLike)

-- | Like hasPrivContent, but allows specifying a source for PrivData,
--   rather than using PrivDataSourceFile.
hasPrivContentFrom :: (IsContext c, IsPrivDataSource s) => s -> FilePath -> c -> Property (HasInfo + UnixLike)

-- | Leaves the file at its default or current mode, allowing "private"
--   data to be read.
--   
--   Use with caution!
hasPrivContentExposed :: IsContext c => FilePath -> c -> Property (HasInfo + UnixLike)
hasPrivContentExposedFrom :: (IsContext c, IsPrivDataSource s) => s -> FilePath -> c -> Property (HasInfo + UnixLike)
hasPrivContent' :: (IsContext c, IsPrivDataSource s) => FileWriteMode -> s -> FilePath -> c -> Property (HasInfo + UnixLike)

-- | Replaces the content of a file with the transformed content of another
--   file
basedOn :: FilePath -> (FilePath, [Line] -> [Line]) -> Property UnixLike

-- | Removes a file. Does not remove symlinks or non-plain-files.
notPresent :: FilePath -> Property UnixLike

-- | Ensures a directory exists.
dirExists :: FilePath -> Property UnixLike

-- | The location that a symbolic link points to.
newtype LinkTarget
LinkTarget :: FilePath -> LinkTarget

-- | Creates or atomically updates a symbolic link.
--   
--   Revert to ensure no symlink is present.
--   
--   Does not overwrite or delete regular files or directories.
isSymlinkedTo :: FilePath -> LinkTarget -> RevertableProperty UnixLike UnixLike

-- | Ensures that a file is a copy of another (regular) file.
isCopyOf :: FilePath -> FilePath -> Property UnixLike

-- | Ensures that a file/dir has the specified owner and group.
ownerGroup :: FilePath -> User -> Group -> Property UnixLike

-- | Given a base directory, and a relative path under that directory,
--   applies a property to each component of the path in turn, starting
--   with the base directory.
--   
--   For example, to make a file owned by a user, making sure their home
--   directory and the subdirectories to it are also owned by them:
--   
--   
--   "/home/user/program/file" `hasContent` ["foo"]
--   	`before` applyPath "/home/user" ".config/program/file" 
--   		(\f -> ownerGroup f (User "user") (Group "user"))
--   
applyPath :: Monoid (Property metatypes) => FilePath -> FilePath -> (FilePath -> Property metatypes) -> Property metatypes

-- | Ensures that a file/dir has the specfied mode.
mode :: FilePath -> FileMode -> Property UnixLike
class FileContent c
emptyFileContent :: FileContent c => c
readFileContent :: FileContent c => FilePath -> IO c
writeFileContent :: FileContent c => FileWriteMode -> FilePath -> c -> IO ()
data FileWriteMode
NormalWrite :: FileWriteMode
ProtectedWrite :: FileWriteMode

-- | A property that applies a pure function to the content of a file.
fileProperty :: (FileContent c, Eq c) => Desc -> (c -> c) -> FilePath -> Property UnixLike
fileProperty' :: (FileContent c, Eq c) => FileWriteMode -> Desc -> (c -> c) -> FilePath -> Property UnixLike

-- | A temp file to use when writing new content for a file.
--   
--   This is a stable name so it can be removed idempotently.
--   
--   It ends with "~" so that programs that read many config files from a
--   directory will treat it as an editor backup file, and not read it.
stableTmpFor :: FilePath -> FilePath

-- | Creates/updates a file atomically, running the action to create the
--   stable tmp file, and then renaming it into place.
viaStableTmp :: (MonadMask m, MonadIO m) => (FilePath -> m ()) -> FilePath -> m ()

-- | Generates a base configuration file name from a String, which can be
--   put in a configuration directory, such as
--   /etc/apt/sources.list.d/
--   
--   The generated file name is limited to using ASCII alphanumerics, '_'
--   and '.' , so that programs that only accept a limited set of
--   characters will accept it. Any other characters will be encoded in
--   escaped form.
--   
--   Some file extensions, such as ".old" may be filtered out by programs
--   that use configuration directories. To avoid such problems, it's a
--   good idea to add an static prefix and extension to the result of this
--   function. For example:
--   
--   
--   aptConf foo = "/etc/apt/apt.conf.d" </> "propellor_" ++ configFileName foo <.> ".conf"
--   
configFileName :: String -> FilePath

-- | Applies configFileName to any value that can be shown.
showConfigFileName :: Show v => v -> FilePath

-- | Inverse of showConfigFileName.
readConfigFileName :: Read v => FilePath -> Maybe v
data Overwrite
OverwriteExisting :: Overwrite
PreserveExisting :: Overwrite

-- | When passed PreserveExisting, only ensures the property when the file
--   does not exist.
checkOverwrite :: Overwrite -> FilePath -> (FilePath -> Property i) -> Property i
instance Propellor.Property.File.FileContent [Propellor.Property.File.Line]
instance Propellor.Property.File.FileContent Data.ByteString.Lazy.Internal.ByteString

module Propellor.Property.ConfFile

-- | find the line that is the start of the wanted section (eg, ==
--   "Foo")
type SectionStart = Line -> Bool

-- | find a line that indicates we are past the section (eg, a new section
--   header)
type SectionPast = Line -> Bool

-- | run on all lines in the section, including the SectionStart line; can
--   add, delete, and modify lines, or even delete entire section
type AdjustSection = [Line] -> [Line]

-- | if SectionStart does not find the section in the file, this is used to
--   insert the section somewhere within it
type InsertSection = [Line] -> [Line]

-- | Adjusts a section of conffile.
adjustSection :: Desc -> SectionStart -> SectionPast -> AdjustSection -> InsertSection -> FilePath -> Property UnixLike

-- | Name of a section of an .ini file. This value is put in square braces
--   to generate the section header.
type IniSection = String

-- | Name of a configuration setting within a .ini file.
type IniKey = String

-- | Ensures that a .ini file exists and contains a section with a
--   key=value setting.
containsIniSetting :: FilePath -> (IniSection, IniKey, String) -> Property UnixLike

-- | Removes a key=value setting from a section of an .ini file. Note that
--   the section heading is left in the file, so this is not a perfect
--   reversion of containsIniSetting.
lacksIniSetting :: FilePath -> (IniSection, IniKey, String) -> Property UnixLike

-- | Ensures that a .ini file exists and contains a section with a given
--   key=value list of settings.
hasIniSection :: FilePath -> IniSection -> [(IniKey, String)] -> Property UnixLike

-- | Ensures that a .ini file does not contain the specified section.
lacksIniSection :: FilePath -> IniSection -> Property UnixLike

-- | Specifies the whole content of a .ini file.
--   
--   Revertijg this causes the file not to exist.
iniFileContains :: FilePath -> [(IniSection, [(IniKey, String)])] -> RevertableProperty UnixLike UnixLike

module Propellor.Property.DnsSec

-- | Puts the DNSSEC key files in place from PrivData.
--   
--   signedPrimary uses this, so this property does not normally need to be
--   used directly.
keysInstalled :: Domain -> RevertableProperty (HasInfo + UnixLike) UnixLike

-- | Uses dnssec-signzone to sign a domain's zone file.
--   
--   signedPrimary uses this, so this property does not normally need to be
--   used directly.
zoneSigned :: Domain -> FilePath -> RevertableProperty (HasInfo + UnixLike) UnixLike
forceZoneSigned :: Domain -> FilePath -> Property UnixLike
saltSha1 :: IO String

-- | The file used for a given key.
keyFn :: Domain -> DnsSecKey -> FilePath

-- | These are the extensions that dnssec-keygen looks for.
keyExt :: DnsSecKey -> String
isPublic :: DnsSecKey -> Bool
isZoneSigningKey :: DnsSecKey -> Bool

-- | dnssec-signzone makes a .signed file
signedZoneFile :: FilePath -> FilePath

-- | FreeBSD pkgng properties
module Propellor.Property.FreeBSD.Pkg
noninteractiveEnv :: [([Char], [Char])]
pkgCommand :: String -> [String] -> (String, [String])
runPkg :: String -> [String] -> IO [String]
pkgCmdProperty :: String -> [String] -> UncheckedProperty FreeBSD
pkgCmd :: String -> [String] -> IO [String]
newtype PkgUpdate
PkgUpdate :: String -> PkgUpdate
pkgUpdated :: PkgUpdate -> Bool
update :: Property (HasInfo + FreeBSD)
newtype PkgUpgrade
PkgUpgrade :: String -> PkgUpgrade
pkgUpgraded :: PkgUpgrade -> Bool
upgrade :: Property (HasInfo + FreeBSD)
type Package = String
installed :: Package -> Property FreeBSD
isInstallable :: Package -> IO Bool
isInstalled :: Package -> IO Bool
exists :: Package -> IO Bool
instance GHC.Show.Show Propellor.Property.FreeBSD.Pkg.PkgUpgrade
instance GHC.Base.Monoid Propellor.Property.FreeBSD.Pkg.PkgUpgrade
instance GHC.Show.Show Propellor.Property.FreeBSD.Pkg.PkgUpdate
instance GHC.Base.Monoid Propellor.Property.FreeBSD.Pkg.PkgUpdate
instance Propellor.Types.Info.IsInfo Propellor.Property.FreeBSD.Pkg.PkgUpdate
instance Propellor.Types.Info.IsInfo Propellor.Property.FreeBSD.Pkg.PkgUpgrade

-- | Freedesktop.org configuration file properties.
module Propellor.Property.FreeDesktop
desktopFile :: String -> FilePath

-- | Name used in a desktop file; user visible.
type Name = String

-- | Command that a dekstop file runs. May include parameters.
type Exec = String

-- | Specifies an autostart file. By default it will be located in the
--   system-wide autostart directory.
autostart :: FilePath -> Name -> Exec -> RevertableProperty UnixLike UnixLike

-- | Properties in this module ensure that things are currently mounted,
--   but without making the mount persistent. Use Fstab to configure
--   persistent mounts.
module Propellor.Property.Mount

-- | type of filesystem to mount ("auto" to autodetect)
type FsType = String

-- | A device or other thing to be mounted.
type Source = String

-- | A mount point for a filesystem.
type MountPoint = FilePath

-- | Filesystem mount options. Eg, MountOpts ["errors=remount-ro"]
--   
--   For default mount options, use mempty.
newtype MountOpts
MountOpts :: [String] -> MountOpts
class ToMountOpts a
toMountOpts :: ToMountOpts a => a -> MountOpts
formatMountOpts :: MountOpts -> String

-- | Mounts a device, without listing it in /etc/fstab.
--   
--   Note that this property will fail if the device is already mounted at
--   the MountPoint.
mounted :: FsType -> Source -> MountPoint -> MountOpts -> Property UnixLike

-- | Bind mounts the first directory so its contents also appear in the
--   second directory.
bindMount :: FilePath -> FilePath -> Property Linux

-- | Enables swapping to a device, which must be formatted already as a
--   swap partition.
swapOn :: Source -> RevertableProperty Linux Linux
mount :: FsType -> Source -> MountPoint -> MountOpts -> IO Bool

-- | Lists all mount points of the system.
mountPoints :: IO [MountPoint]

-- | Checks if anything is mounted at the MountPoint.
isMounted :: MountPoint -> IO Bool

-- | Finds all filesystems mounted inside the specified directory.
mountPointsBelow :: FilePath -> IO [MountPoint]

-- | Filesystem type mounted at a given location.
getFsType :: MountPoint -> IO (Maybe FsType)

-- | Mount options for the filesystem mounted at a given location.
getFsMountOpts :: MountPoint -> IO MountOpts
type UUID = String

-- | UUID of filesystem mounted at a given location.
getMountUUID :: MountPoint -> IO (Maybe UUID)

-- | UUID of a device
getSourceUUID :: Source -> IO (Maybe UUID)
type Label = String

-- | Label of filesystem mounted at a given location.
getMountLabel :: MountPoint -> IO (Maybe Label)

-- | Label of a device
getSourceLabel :: Source -> IO (Maybe UUID)

-- | Device mounted at a given location.
getMountSource :: MountPoint -> IO (Maybe Source)

-- | Device that a given path is located within.
getMountContaining :: FilePath -> IO (Maybe Source)
findmntField :: String -> [String] -> IO (Maybe String)
blkidTag :: String -> Source -> IO (Maybe String)

-- | Unmounts a device or mountpoint, lazily so any running processes don't
--   block it.
--   
--   Note that this will fail if it's not mounted.
umountLazy :: FilePath -> IO ()

-- | Unmounts anything mounted inside the specified directory, not
--   including the directory itself.
unmountBelow :: FilePath -> IO ()
instance GHC.Base.Monoid Propellor.Property.Mount.MountOpts
instance Propellor.Property.Mount.ToMountOpts Propellor.Property.Mount.MountOpts
instance Propellor.Property.Mount.ToMountOpts GHC.Base.String

module Propellor.Property.Fstab

-- | type of filesystem to mount ("auto" to autodetect)
type FsType = String

-- | A device or other thing to be mounted.
type Source = String

-- | A mount point for a filesystem.
type MountPoint = FilePath

-- | Filesystem mount options. Eg, MountOpts ["errors=remount-ro"]
--   
--   For default mount options, use mempty.
newtype MountOpts
MountOpts :: [String] -> MountOpts

-- | Ensures that /etc/fstab contains a line mounting the specified
--   Source on the specified MountPoint, and that it's
--   currently mounted.
--   
--   For example:
--   
--   
--   mounted "auto" "/dev/sdb1" "/srv" mempty
--   
--   
--   Note that if anything else is already mounted at the
--   MountPoint, it will be left as-is by this property.
mounted :: FsType -> Source -> MountPoint -> MountOpts -> Property Linux

-- | Ensures that /etc/fstab contains a line mounting the specified
--   Source on the specified MountPoint. Does not ensure that
--   it's currently mounted.
listed :: FsType -> Source -> MountPoint -> MountOpts -> Property UnixLike

-- | Ensures that /etc/fstab contains a line enabling the specified
--   Source to be used as swap space, and that it's enabled.
swap :: Source -> Property Linux
newtype SwapPartition
SwapPartition :: FilePath -> SwapPartition

-- | Replaces /etc/fstab with a file that should cause the currently
--   mounted partitions to be re-mounted the same way on boot.
--   
--   For each specified MountPoint, the UUID of each partition (or if there
--   is no UUID, its label), its filesystem type, and its mount options are
--   all automatically probed.
--   
--   The SwapPartitions are also included in the generated fstab.
fstabbed :: [MountPoint] -> [SwapPartition] -> Property Linux
genFstab :: [MountPoint] -> [SwapPartition] -> (MountPoint -> MountPoint) -> IO [String]

-- | Checks if /etc/fstab is not configured. This is the case if it
--   doesn't exist, or consists entirely of blank lines or comments.
--   
--   So, if you want to only replace the fstab once, and then never touch
--   it again, allowing local modifications:
--   
--   
--   check noFstab (fstabbed mnts [])
--   
noFstab :: IO Bool

module Propellor.Property.Network
type Interface = String

-- | Options to put in a stanza of an ifupdown interfaces file.
type InterfaceOptions = [(String, String)]
ifUp :: Interface -> Property DebianLike

-- | Resets etcnetwork/interfaces to a clean and empty state,
--   containing just the standard loopback interface, and with interfacesD
--   enabled.
--   
--   This can be used as a starting point to defining other interfaces.
--   
--   No interfaces are brought up or down by this property.
cleanInterfacesFile :: Property DebianLike

-- | Configures an interface to get its address via dhcp.
dhcp :: Interface -> Property DebianLike
dhcp' :: Interface -> InterfaceOptions -> Property DebianLike
newtype Gateway
Gateway :: IPAddr -> Gateway

-- | Configures an interface with a static address and gateway.
static :: Interface -> IPAddr -> Maybe Gateway -> Property DebianLike
static' :: Interface -> IPAddr -> Maybe Gateway -> InterfaceOptions -> Property DebianLike

-- | Writes a static interface file for the specified interface to preserve
--   its current configuration.
--   
--   The interface has to be up already. It could have been brought up by
--   DHCP, or by other means. The current ipv4 addresses and routing
--   configuration of the interface are written into the file.
--   
--   If the interface file already exists, this property does nothing, no
--   matter its content.
--   
--   (ipv6 addresses are not included because it's assumed they come up
--   automatically in most situations.)
preserveStatic :: Interface -> Property DebianLike

-- | 6to4 ipv6 connection, should work anywhere
ipv6to4 :: Property DebianLike
interfacesFile :: FilePath

-- | A file in the interfaces.d directory.
interfaceDFile :: Interface -> FilePath

-- | etcnetworkinterfaces.d files have to match --
--   ^[a-zA-Z0-9_-]+$ see "man 5 interfaces"
escapeInterfaceDName :: Interface -> FilePath

-- | Ensures that files in the the interfaces.d directory are used.
--   interfacesDEnabled :: Property DebianLike
interfacesDEnabled :: Property DebianLike
interfaceFileContains :: FilePath -> [String] -> InterfaceOptions -> Property DebianLike

-- | Support for the Pacman package manager
--   https://www.archlinux.org/pacman/
module Propellor.Property.Pacman
runPacman :: [String] -> UncheckedProperty ArchLinux

-- | Have pacman update its lists of packages, but without upgrading
--   anything.
update :: Property ArchLinux
upgrade :: Property ArchLinux
type Package = String
installed :: [Package] -> Property ArchLinux
installed' :: [String] -> [Package] -> Property ArchLinux
removed :: [Package] -> Property ArchLinux
isInstalled :: Package -> IO Bool
isInstalled' :: [Package] -> IO Bool
data InstallStatus
IsInstalled :: InstallStatus
NotInstalled :: InstallStatus
getInstallStatus :: [Package] -> IO [InstallStatus]
succeeds :: String -> [String] -> IO Bool
instance GHC.Classes.Eq Propellor.Property.Pacman.InstallStatus
instance GHC.Show.Show Propellor.Property.Pacman.InstallStatus

module Propellor.Property.PropellorRepo

-- | Sets the url to use as the origin of propellor's git repository.
--   
--   By default, the url is taken from the deploy or origin remote of the
--   repository that propellor --spin is run in. Setting this property
--   overrides that default behavior with a different url.
--   
--   When hosts are being updated without using -- --spin, eg when using
--   the runPropellor cron job, this property can be set to redirect
--   them to a new git repository url.
hasOriginUrl :: String -> Property (HasInfo + UnixLike)
newtype OriginUrl
OriginUrl :: String -> OriginUrl
instance GHC.Show.Show Propellor.Property.PropellorRepo.OriginUrl

module Propellor.Property.Reboot

-- | Using this property causes an immediate reboot.
--   
--   So, this is not a useful property on its own, but it can be useful to
--   compose with other properties. For example:
--   
--   
--   Apt.installed ["new-kernel"]
--   `onChange` Reboot.now
--   
now :: Property Linux

-- | Schedules a reboot at the end of the current propellor run.
--   
--   The Result code of the entire propellor run can be checked; the
--   reboot proceeds only if the function returns True.
--   
--   The reboot can be forced to run, which bypasses the init system.
--   Useful if the init system might not be running for some reason.
atEnd :: Force -> (Result -> Bool) -> Property Linux

-- | Reboots immediately if a kernel other than the distro-installed kernel
--   is running.
--   
--   This will only work if you have taken measures to ensure that the
--   other kernel won't just get booted again. See DigitalOcean for
--   an example of how to do this.
toDistroKernel :: Property DebianLike

-- | Given a kernel version string v, reboots immediately if the
--   running kernel version is strictly less than v and there is
--   an installed kernel version is greater than or equal to v.
--   Fails if the requested kernel version is not installed.
--   
--   For this to be useful, you need to have ensured that the installed
--   kernel with the highest version number is the one that will be started
--   after a reboot.
--   
--   This is useful when upgrading to a new version of Debian where you
--   need to ensure that a new enough kernel is running before ensuring
--   other properties.
toKernelNewerThan :: KernelVersion -> Property DebianLike

-- | Kernel version number, in a string.
type KernelVersion = String

module Propellor.Property.Scheduled

-- | Makes a Property only be checked every so often.
--   
--   This uses the description of the Property to keep track of when it was
--   last run.
period :: (IsProp (Property i)) => Property i -> Recurrance -> Property i

-- | Like period, but parse a human-friendly string.
periodParse :: (IsProp (Property i)) => Property i -> String -> Property i
data Recurrance
Daily :: Recurrance
Weekly :: (Maybe WeekDay) -> Recurrance
Monthly :: (Maybe MonthDay) -> Recurrance
Yearly :: (Maybe YearDay) -> Recurrance

-- | Days, Weeks, or Months of the year evenly divisible by a number.
--   (Divisible Year is years evenly divisible by a number.)
Divisible :: Int -> Recurrance -> Recurrance
type WeekDay = Int
type MonthDay = Int
type YearDay = Int

module Propellor.Property.Service
type ServiceName = String

-- | Ensures that a service is running. Does not ensure that any package
--   providing that service is installed. See Apt.serviceInstalledRunning
--   
--   Note that due to the general poor state of init scripts, the best we
--   can do is try to start the service, and if it fails, assume this means
--   it's already running.
running :: ServiceName -> Property DebianLike
restarted :: ServiceName -> Property DebianLike
reloaded :: ServiceName -> Property DebianLike
signaled :: String -> Desc -> ServiceName -> Property DebianLike

-- | This property prevents daemons and other services from being started,
--   which is often something you want to prevent when building a chroot.
--   
--   When this is set, running and restarted will not start
--   services.
--   
--   On Debian this installs a /usr/sbin/policy-rc.d script to
--   further prevent any packages that get installed from starting daemons.
--   Reverting the property removes the script.
noServices :: RevertableProperty (HasInfo + UnixLike) UnixLike

-- | Check if the noServices property is in effect.
servicesDisabled :: Propellor Bool
data NoServices
NoServices :: NoServices
instance GHC.Show.Show Propellor.Property.Service.NoServices
instance GHC.Classes.Eq Propellor.Property.Service.NoServices

module Propellor.Property.Apt
data HostMirror
HostMirror :: Url -> HostMirror
data HostAptProxy
HostAptProxy :: Url -> HostAptProxy

-- | Indicate host's preferred apt mirror
mirror :: Url -> Property (HasInfo + UnixLike)
getMirror :: Propellor Url
withMirror :: Desc -> (Url -> Property DebianLike) -> Property DebianLike
sourcesList :: FilePath
type Url = String
type Section = String
type SourcesGenerator = DebianSuite -> [Line]
showSuite :: DebianSuite -> String
backportSuite :: DebianSuite -> Maybe String
stableUpdatesSuite :: DebianSuite -> Maybe String
debLine :: String -> Url -> [Section] -> Line
srcLine :: Line -> Line
stdSections :: [Section]
binandsrc :: String -> SourcesGenerator
stdArchiveLines :: Propellor SourcesGenerator

-- | Only available for Stable and Testing
securityUpdates :: SourcesGenerator

-- | Makes sources.list have a standard content using the Debian mirror CDN
--   (or other host specified using the mirror property), with the
--   Debian suite configured by the os.
stdSourcesList :: Property Debian
stdSourcesListFor :: DebianSuite -> Property Debian

-- | Adds additional sources.list generators.
--   
--   Note that if a Property needs to enable an apt source, it's better to
--   do so via a separate file in /etc/apt/sources.list.d/
stdSourcesList' :: DebianSuite -> [SourcesGenerator] -> Property Debian
type PinPriority = Int

-- | Adds an apt source for a suite, and pins that suite to a given pin
--   value (see apt_preferences(5)). Revert to drop the source and unpin
--   the suite.
--   
--   If the requested suite is the host's OS suite, the suite is pinned,
--   but no source is added. That apt source should already be available,
--   or you can use a property like stdSourcesList.
suiteAvailablePinned :: DebianSuite -> PinPriority -> RevertableProperty Debian Debian
setSourcesList :: [Line] -> Property DebianLike
setSourcesListD :: [Line] -> FilePath -> Property DebianLike
runApt :: [String] -> UncheckedProperty DebianLike
noninteractiveEnv :: [(String, String)]

-- | Have apt update its lists of packages, but without upgrading anything.
update :: Property DebianLike

-- | Have apt upgrade packages, adding new packages and removing old as
--   necessary. Often used in combination with the update property.
upgrade :: Property DebianLike
upgrade' :: String -> Property DebianLike

-- | Have apt upgrade packages, but never add new packages or remove old
--   packages. Not suitable for upgrading acrocess major versions of the
--   distribution.
safeUpgrade :: Property DebianLike

-- | Have dpkg try to configure any packages that are not fully configured.
pendingConfigured :: Property DebianLike
type Package = String
installed :: [Package] -> Property DebianLike
installed' :: [String] -> [Package] -> Property DebianLike
installedBackport :: [Package] -> Property Debian

-- | Minimal install of package, without recommends.
installedMin :: [Package] -> Property DebianLike
removed :: [Package] -> Property DebianLike
buildDep :: [Package] -> Property DebianLike

-- | Installs the build deps for the source package unpacked in the
--   specifed directory, with a dummy package also installed so that
--   autoRemove won't remove them.
buildDepIn :: FilePath -> Property DebianLike

-- | The name of a package, a glob to match the names of packages, or a
--   regexp surrounded by slashes to match the names of packages. See
--   apt_preferences(5), "Regular expressions and glob(7) syntax"
type AptPackagePref = String

-- | Pins a list of packages, package wildcards and/or regular expressions
--   to a list of suites and corresponding pin priorities (see
--   apt_preferences(5)). Revert to unpin.
--   
--   Each package, package wildcard or regular expression will be pinned to
--   all of the specified suites.
--   
--   Note that this will have no effect unless there is an apt source for
--   each of the suites. One way to add an apt source is
--   suiteAvailablePinned.
--   
--   For example, to obtain Emacs Lisp addon packages not present in your
--   release of Debian from testing, falling back to sid if they're not
--   available in testing, you could use
--   
--   
--   & Apt.suiteAvailablePinned Testing (-10)
--   & Apt.suiteAvailablePinned Unstable (-10)
--   & ["elpa-*"] `Apt.pinnedTo` [(Testing, 100), (Unstable, 50)]
--   
pinnedTo :: [AptPackagePref] -> [(DebianSuite, PinPriority)] -> RevertableProperty Debian Debian
pinnedTo' :: AptPackagePref -> [(DebianSuite, PinPriority)] -> RevertableProperty Debian Debian

-- | Package installation may fail becuse the archive has changed. Run an
--   update in that case and retry.
robustly :: Property DebianLike -> Property DebianLike
isInstalled :: Package -> IO Bool
isInstalled' :: [Package] -> IO Bool
data InstallStatus
IsInstalled :: InstallStatus
NotInstalled :: InstallStatus
getInstallStatus :: [Package] -> IO [InstallStatus]
autoRemove :: Property DebianLike

-- | Enables unattended upgrades. Revert to disable.
unattendedUpgrades :: RevertableProperty DebianLike DebianLike

-- | Enable periodic updates (but not upgrades), including download of
--   packages.
periodicUpdates :: Property DebianLike
type DebconfTemplate = String
type DebconfTemplateType = String
type DebconfTemplateValue = String

-- | Preseeds debconf values and reconfigures the package so it takes
--   effect.
reConfigure :: Package -> [(DebconfTemplate, DebconfTemplateType, DebconfTemplateValue)] -> Property DebianLike

-- | Ensures that a service is installed and running.
--   
--   Assumes that there is a 1:1 mapping between service names and apt
--   package names.
serviceInstalledRunning :: Package -> Property DebianLike
data AptKey
AptKey :: String -> String -> AptKey
[keyname] :: AptKey -> String
[pubkey] :: AptKey -> String
trustsKey :: AptKey -> RevertableProperty DebianLike DebianLike
trustsKey' :: AptKey -> Property DebianLike
untrustKey :: AptKey -> Property DebianLike
aptKeyFile :: AptKey -> FilePath

-- | Cleans apt's cache of downloaded packages to avoid using up disk
--   space.
cacheCleaned :: Property DebianLike

-- | Add a foreign architecture to dpkg and apt.
hasForeignArch :: String -> Property DebianLike

-- | Disable the use of PDiffs for machines with high-bandwidth
--   connections.
noPDiffs :: Property DebianLike
suitePin :: DebianSuite -> String
suitePinBlock :: AptPackagePref -> DebianSuite -> PinPriority -> [Line]
dpkgStatus :: FilePath

-- | Set apt's proxy
proxy :: Url -> Property (HasInfo + DebianLike)
proxy' :: Url -> Property DebianLike

-- | Cause apt to proxy downloads via an apt cacher on localhost
useLocalCacher :: Property (HasInfo + DebianLike)
instance GHC.Classes.Eq Propellor.Property.Apt.InstallStatus
instance GHC.Show.Show Propellor.Property.Apt.InstallStatus
instance GHC.Show.Show Propellor.Property.Apt.HostMirror
instance GHC.Classes.Eq Propellor.Property.Apt.HostMirror
instance GHC.Show.Show Propellor.Property.Apt.HostAptProxy
instance GHC.Classes.Eq Propellor.Property.Apt.HostAptProxy

module Propellor.Property.Aiccu
installed :: Property DebianLike
restarted :: Property DebianLike
confPath :: FilePath
type UserName = String
type TunnelId = String

-- | Configures an ipv6 tunnel using sixxs.net, with the given TunneId and
--   sixx.net UserName.
hasConfig :: TunnelId -> UserName -> Property (HasInfo + DebianLike)

-- | Personal Package Archives
module Propellor.Property.Apt.PPA

-- | Ensure software-properties-common is installed.
installed :: Property DebianLike

-- | Personal Package Archives are people's individual package
--   contributions to the Buntish distro. There's a well-known format for
--   representing them, and this type represents that. It's also an
--   instance of Show and IsString so it can work with
--   OverloadedStrings. More on PPAs can be found at
--   https://help.launchpad.net/Packaging/PPA
data PPA
PPA :: String -> String -> PPA

-- | The Launchpad account hosting this archive.
[ppaAccount] :: PPA -> String

-- | The name of the archive.
[ppaArchive] :: PPA -> String

-- | Adds a PPA to the local system repositories.
addPpa :: PPA -> Property DebianLike

-- | A repository key ID to be downloaded with apt-key.
data AptKeyId
AptKeyId :: String -> String -> String -> AptKeyId
[akiName] :: AptKeyId -> String
[akiId] :: AptKeyId -> String
[akiServer] :: AptKeyId -> String

-- | Adds an AptKeyId from the specified GPG server.
addKeyId :: AptKeyId -> Property DebianLike

-- | An Apt source line that apt-add-repository will just add to
--   sources.list. It's also an instance of both ConfigurableValue
--   and IsString to make using OverloadedStrings in the
--   configuration file easier.
--   
--   | FIXME there's apparently an optional "options" fragment that I've
--   definitely not parsed here.
data AptSource
AptSource :: Url -> String -> [String] -> AptSource

-- | The URL hosting the repository
[asURL] :: AptSource -> Url

-- | The operating system suite
[asSuite] :: AptSource -> String

-- | The list of components to install from this repository.
[asComponents] :: AptSource -> [String]

-- | A repository for apt-add-source, either a PPA or a regular repository
--   line.
data AptRepository
AptRepositoryPPA :: PPA -> AptRepository
AptRepositorySource :: AptSource -> AptRepository

-- | Adds an AptRepository using apt-add-source.
addRepository :: AptRepository -> Property DebianLike
instance GHC.Classes.Ord Propellor.Property.Apt.PPA.AptSource
instance GHC.Classes.Eq Propellor.Property.Apt.PPA.AptSource
instance GHC.Classes.Ord Propellor.Property.Apt.PPA.AptKeyId
instance GHC.Classes.Eq Propellor.Property.Apt.PPA.AptKeyId
instance GHC.Classes.Ord Propellor.Property.Apt.PPA.PPA
instance GHC.Classes.Eq Propellor.Property.Apt.PPA.PPA
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Property.Apt.PPA.PPA
instance Data.String.IsString Propellor.Property.Apt.PPA.PPA
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Property.Apt.PPA.AptSource
instance Data.String.IsString Propellor.Property.Apt.PPA.AptSource

module Propellor.Property.Ccache

-- | Configures a ccache in varcache for a group
--   
--   If you say
--   
--   
--   & (Group "foo") `Ccache.hasGroupCache`
--   	(Ccache.MaxSize "4G" <> Ccache.MaxFiles 10000)
--   
--   
--   you instruct propellor to create a ccache in
--   varcache/ccache-foo owned and writeable by the foo group, with
--   a maximum cache size of 4GB or 10000 files.
hasCache :: Group -> Limit -> RevertableProperty DebianLike UnixLike

-- | Set limits on a given ccache
hasLimits :: FilePath -> Limit -> Property DebianLike

-- | Limits on the size of a ccache
data Limit

-- | The maximum size of the cache, as a string such as "4G"
MaxSize :: DataSize -> Limit

-- | The maximum number of files in the cache
MaxFiles :: Integer -> Limit

-- | A cache with no limit specified
NoLimit :: Limit
(:+) :: Limit -> Limit -> Limit

-- | A string that will be parsed to get a data size.
--   
--   Examples: "100 megabytes" or "0.5tb"
type DataSize = String
instance GHC.Base.Monoid Propellor.Property.Ccache.Limit

module Propellor.Property.Cron

-- | When to run a cron job.
--   
--   The Daily, Monthly, and Weekly options allow the cron job to be run by
--   anacron, which is useful for non-servers.
data Times

-- | formatted as in crontab(5)
Times :: String -> Times
Daily :: Times
Weekly :: Times
Monthly :: Times

-- | Installs a cron job, that will run as a specified user in a particular
--   directory. Note that the Desc must be unique, as it is used for the
--   cron job filename.
--   
--   Only one instance of the cron job is allowed to run at a time, no
--   matter how long it runs. This is accomplished using flock locking of
--   the cron job file.
--   
--   The cron job's output will only be emailed if it exits nonzero.
job :: Desc -> Times -> User -> FilePath -> String -> Property DebianLike

-- | Installs a cron job, and runs it niced and ioniced.
niceJob :: Desc -> Times -> User -> FilePath -> String -> Property DebianLike

-- | Installs a cron job to run propellor.
runPropellor :: Times -> Property UnixLike

-- | Support for the Attic backup tool https://attic-backup.org/
--   
--   This module is deprecated because Attic is not available in debian
--   stable any longer (so the installed property no longer works), and it
--   appears to have been mostly supersceded by Borg.

-- | Deprecated: Use Borg instead
module Propellor.Property.Attic
installed :: Property DebianLike
repoExists :: AtticRepo -> IO Bool

-- | Inits a new attic repository
init :: AtticRepo -> Property DebianLike

-- | Restores a directory from an attic backup.
--   
--   Only does anything if the directory does not exist, or exists, but is
--   completely empty.
--   
--   The restore is performed atomically; restoring to a temp directory and
--   then moving it to the directory.
restored :: FilePath -> AtticRepo -> Property DebianLike

-- | Installs a cron job that causes a given directory to be backed up, by
--   running attic with some parameters.
--   
--   If the directory does not exist, or exists but is completely empty,
--   this Property will immediately restore it from an existing backup.
--   
--   So, this property can be used to deploy a directory of content to a
--   host, while also ensuring any changes made to it get backed up. For
--   example:
--   
--   
--   & Attic.backup "/srv/git" "root@myserver:/mnt/backup/git.attic" Cron.Daily
--   	["--exclude=/srv/git/tobeignored"]
--   	[Attic.KeepDays 7, Attic.KeepWeeks 4, Attic.KeepMonths 6, Attic.KeepYears 1]
--   
--   
--   Note that this property does not make attic encrypt the backup
--   repository.
--   
--   Since attic uses a fair amount of system resources, only one attic
--   backup job will be run at a time. Other jobs will wait their turns to
--   run.
backup :: FilePath -> AtticRepo -> Times -> [AtticParam] -> [KeepPolicy] -> Property DebianLike

-- | Policy for backup generations to keep. For example, KeepDays 30 will
--   keep the latest backup for each day when a backup was made, and keep
--   the last 30 such backups. When multiple KeepPolicies are combined
--   together, backups meeting any policy are kept. See attic's man page
--   for details.
data KeepPolicy
KeepHours :: Int -> KeepPolicy
KeepDays :: Int -> KeepPolicy
KeepWeeks :: Int -> KeepPolicy
KeepMonths :: Int -> KeepPolicy
KeepYears :: Int -> KeepPolicy

-- | Support for the Borg backup tool https://github.com/borgbackup
module Propellor.Property.Borg

-- | Parameter to pass to a borg command.
type BorgParam = String

-- | A borg repository.
data BorgRepo

-- | Location of the repository, eg `BorgRepo
--   "root@myserver:mntbackup/git.borg"`
BorgRepo :: String -> BorgRepo

-- | Location of the repository, and additional options to use when
--   accessing the repository.
BorgRepoUsing :: [BorgRepoOpt] -> String -> BorgRepo
data BorgRepoOpt

-- | Use to specify a ssh private key to use when accessing a BorgRepo.
UseSshKey :: FilePath -> BorgRepoOpt
installed :: Property DebianLike
repoExists :: BorgRepo -> IO Bool

-- | Inits a new borg repository
init :: BorgRepo -> Property DebianLike

-- | Restores a directory from a borg backup.
--   
--   Only does anything if the directory does not exist, or exists, but is
--   completely empty.
--   
--   The restore is performed atomically; restoring to a temp directory and
--   then moving it to the directory.
restored :: FilePath -> BorgRepo -> Property DebianLike

-- | Installs a cron job that causes a given directory to be backed up, by
--   running borg with some parameters.
--   
--   If the directory does not exist, or exists but is completely empty,
--   this Property will immediately restore it from an existing backup.
--   
--   So, this property can be used to deploy a directory of content to a
--   host, while also ensuring any changes made to it get backed up. For
--   example:
--   
--   
--   & Borg.backup "/srv/git"
--   	(BorgRepo "root@myserver:/mnt/backup/git.borg") 
--   	Cron.Daily
--   	["--exclude=/srv/git/tobeignored"]
--   	[Borg.KeepDays 7, Borg.KeepWeeks 4, Borg.KeepMonths 6, Borg.KeepYears 1]
--   
--   
--   Note that this property does not initialize the backup repository, so
--   that will need to be done once, before-hand.
--   
--   Since borg uses a fair amount of system resources, only one borg
--   backup job will be run at a time. Other jobs will wait their turns to
--   run.
backup :: FilePath -> BorgRepo -> Times -> [BorgParam] -> [KeepPolicy] -> Property DebianLike

-- | Policy for backup generations to keep. For example, KeepDays 30 will
--   keep the latest backup for each day when a backup was made, and keep
--   the last 30 such backups. When multiple KeepPolicies are combined
--   together, backups meeting any policy are kept. See borg's man page for
--   details.
data KeepPolicy
KeepHours :: Int -> KeepPolicy
KeepDays :: Int -> KeepPolicy
KeepWeeks :: Int -> KeepPolicy
KeepMonths :: Int -> KeepPolicy
KeepYears :: Int -> KeepPolicy

module Propellor.Property.Firejail

-- | Ensures that Firejail is installed
installed :: Property DebianLike

-- | For each program name passed, create symlinks in usrlocal/bin
--   that will launch that program in a Firejail sandbox.
--   
--   The profile for the sandbox will be the same as if the user had run
--   firejail directly without passing --profile (see
--   "SECURITY PROFILES" in firejail(1)).
--   
--   See "DESKTOP INTEGRATION" in firejail(1).
jailed :: [String] -> Property DebianLike

-- | Properties for configuring firewall (iptables) rules
module Propellor.Property.Firewall
rule :: Chain -> Table -> Target -> Rules -> Property Linux
installed :: Property DebianLike
data Chain
INPUT :: Chain
OUTPUT :: Chain
FORWARD :: Chain
PREROUTING :: Chain
POSTROUTING :: Chain
ChainCustom :: String -> Chain
data Table
Filter :: Table
Nat :: Table
Mangle :: Table
Raw :: Table
Security :: Table
data Target
ACCEPT :: Target
REJECT :: Target
DROP :: Target
LOG :: Target
TargetCustom :: String -> Target
data Proto
TCP :: Proto
UDP :: Proto
ICMP :: Proto
data Rules
Everything :: Rules

-- | There is actually some order dependency between proto and port so this
--   should be a specific data type with proto + ports
Proto :: Proto -> Rules
DPort :: Port -> Rules
DPortRange :: (Port, Port) -> Rules
InIFace :: Interface -> Rules
OutIFace :: Interface -> Rules
Ctstate :: [ConnectionState] -> Rules
ICMPType :: ICMPTypeMatch -> Rules
RateLimit :: Frequency -> Rules
TCPFlags :: TCPFlagMask -> TCPFlagComp -> Rules
TCPSyn :: Rules
GroupOwner :: Group -> Rules
Source :: [IPWithMask] -> Rules
Destination :: [IPWithMask] -> Rules
NotDestination :: [IPWithMask] -> Rules
NatDestination :: IPAddr -> (Maybe Port) -> Rules

-- | Combine two rules
(:-) :: Rules -> Rules -> Rules
data ConnectionState
ESTABLISHED :: ConnectionState
RELATED :: ConnectionState
NEW :: ConnectionState
INVALID :: ConnectionState
data ICMPTypeMatch
ICMPTypeName :: String -> ICMPTypeMatch
ICMPTypeCode :: Int -> ICMPTypeMatch
data TCPFlag
SYN :: TCPFlag
ACK :: TCPFlag
FIN :: TCPFlag
RST :: TCPFlag
URG :: TCPFlag
PSH :: TCPFlag
ALL :: TCPFlag
NONE :: TCPFlag
data Frequency
NumBySecond :: Int -> Frequency
data IPWithMask
IPWithNoMask :: IPAddr -> IPWithMask
IPWithIPMask :: IPAddr -> IPAddr -> IPWithMask
IPWithNumMask :: IPAddr -> Int -> IPWithMask
instance GHC.Show.Show Propellor.Property.Firewall.Rule
instance GHC.Classes.Eq Propellor.Property.Firewall.Rule
instance GHC.Show.Show Propellor.Property.Firewall.Rules
instance GHC.Classes.Eq Propellor.Property.Firewall.Rules
instance GHC.Show.Show Propellor.Property.Firewall.TCPFlag
instance GHC.Classes.Eq Propellor.Property.Firewall.TCPFlag
instance GHC.Show.Show Propellor.Property.Firewall.Frequency
instance GHC.Classes.Eq Propellor.Property.Firewall.Frequency
instance GHC.Show.Show Propellor.Property.Firewall.ICMPTypeMatch
instance GHC.Classes.Eq Propellor.Property.Firewall.ICMPTypeMatch
instance GHC.Show.Show Propellor.Property.Firewall.ConnectionState
instance GHC.Classes.Eq Propellor.Property.Firewall.ConnectionState
instance GHC.Show.Show Propellor.Property.Firewall.Proto
instance GHC.Classes.Eq Propellor.Property.Firewall.Proto
instance GHC.Show.Show Propellor.Property.Firewall.Chain
instance GHC.Classes.Eq Propellor.Property.Firewall.Chain
instance GHC.Show.Show Propellor.Property.Firewall.Target
instance GHC.Classes.Eq Propellor.Property.Firewall.Target
instance GHC.Show.Show Propellor.Property.Firewall.Table
instance GHC.Classes.Eq Propellor.Property.Firewall.Table
instance GHC.Show.Show Propellor.Property.Firewall.IPWithMask
instance GHC.Classes.Eq Propellor.Property.Firewall.IPWithMask
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Property.Firewall.IPWithMask
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Property.Firewall.Table
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Property.Firewall.Target
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Property.Firewall.Chain
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Property.Firewall.ICMPTypeMatch
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Property.Firewall.Frequency
instance GHC.Base.Monoid Propellor.Property.Firewall.Rules

-- | Make ARM systems bootable using Debian's flash-kernel package.
module Propellor.Property.FlashKernel

-- | A machine name, such as "Cubietech Cubietruck" or "Olimex
--   A10-OLinuXino-LIME"
--   
--   flash-kernel supports many different machines, see its file
--   usrshareflash-kerneldb/all.db for a list.
type Machine = String

-- | Uses flash-kernel to make a machine bootable.
--   
--   Before using this, an appropriate kernel needs to already be
--   installed, and on many machines, u-boot needs to be installed too.
installed :: Machine -> Property (HasInfo + DebianLike)

-- | Runs flash-kernel with whatever machine installed configured.
flashKernel :: Property DebianLike

-- | Runs flash-kernel in the system mounted at a particular directory.
flashKernelMounted :: FilePath -> Property Linux

module Propellor.Property.Gpg
installed :: Property DebianLike
newtype GpgKeyId
GpgKeyId :: String -> GpgKeyId
[getGpgKeyId] :: GpgKeyId -> String
data GpgKeyType
GpgPubKey :: GpgKeyType
GpgPrivKey :: GpgKeyType

-- | Sets up a user with a gpg key from the privdata.
--   
--   Note that if a secret key is exported using gpg -a
--   --export-secret-key, the public key is also included. Or just a public
--   key could be exported, and this would set it up just as well.
--   
--   Recommend only using this for low-value dedicated role keys. No
--   attempt has been made to scrub the key out of memory once it's used.
keyImported :: GpgKeyId -> User -> Property (HasInfo + DebianLike)
hasPrivKey :: GpgKeyId -> User -> IO Bool
hasPubKey :: GpgKeyId -> User -> IO Bool
dotDir :: User -> IO FilePath

module Propellor.Property.HostingProvider.DigitalOcean

-- | 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

-- | This module gets LetsEncrypt https://letsencrypt.org/
--   certificates using CertBot https://certbot.eff.org/
module Propellor.Property.LetsEncrypt
installed :: Property DebianLike

-- | Tell the letsencrypt client that you agree with the Let's Encrypt
--   Subscriber Agreement. Providing an email address is recommended, so
--   that letcencrypt can contact you about problems.
data AgreeTOS
AgreeTOS :: (Maybe Email) -> AgreeTOS
type Email = String
type WebRoot = FilePath

-- | Uses letsencrypt to obtain a certificate for a domain.
--   
--   This should work with any web server, as long as letsencrypt can write
--   its temp files to the web root. The letsencrypt client does not modify
--   the web server's configuration in any way; this only obtains the
--   certificate it does not make the web server use it.
--   
--   This also handles renewing the certificate. For renewel to work well,
--   propellor needs to be run periodically (at least a couple times per
--   month).
--   
--   This property returns MadeChange when the certificate is
--   initially obtained, and when it's renewed. So, it can be combined with
--   a property to make the webserver (or other server) use the
--   certificate:
--   
--   
--   letsEncrypt (AgreeTOS (Just "me@example.com")) "example.com" "/var/www"
--   	`onChange` Apache.reload
--   
--   
--   See httpsVirtualHost for a more complete integration of apache
--   with letsencrypt, that's built on top of this.
letsEncrypt :: AgreeTOS -> Domain -> WebRoot -> Property DebianLike

-- | Like letsEncrypt, but the certificate can be obtained for
--   multiple domains.
letsEncrypt' :: AgreeTOS -> Domain -> [Domain] -> WebRoot -> Property DebianLike

-- | The cerificate files that letsencrypt will make available for a
--   domain.
liveCertDir :: Domain -> FilePath
certFile :: Domain -> FilePath
privKeyFile :: Domain -> FilePath
chainFile :: Domain -> FilePath
fullChainFile :: Domain -> FilePath

module Propellor.Property.Apache
installed :: Property DebianLike
restarted :: Property DebianLike
reloaded :: Property DebianLike
type ConfigLine = String
type ConfigFile = [ConfigLine]
siteEnabled :: Domain -> ConfigFile -> RevertableProperty DebianLike DebianLike
siteEnabled' :: Domain -> ConfigFile -> Property DebianLike
siteDisabled :: Domain -> Property DebianLike
siteAvailable :: Domain -> ConfigFile -> Property DebianLike
modEnabled :: String -> RevertableProperty DebianLike DebianLike

-- | Control whether an apache configuration file is enabled.
--   
--   The String is the base name of the configuration, eg "charset" or
--   "gitweb".
confEnabled :: String -> RevertableProperty DebianLike DebianLike

-- | Make apache listen on the specified ports.
--   
--   Note that ports are also specified inside a site's config file, so
--   that also needs to be changed.
listenPorts :: [Port] -> Property DebianLike
siteCfg :: Domain -> [FilePath]

-- | Configure apache to use SNI to differentiate between https hosts.
--   
--   This was off by default in apache 2.2.22. Newver versions enable it by
--   default. This property uses the filename used by the old version.
multiSSL :: Property DebianLike

-- | Config file fragment that can be inserted into a Directory
--   stanza to allow global read access to the directory.
--   
--   Works with multiple versions of apache that have different ways to do
--   it.
allowAll :: ConfigLine

-- | Config file fragment that can be inserted into a VirtualHost
--   stanza to allow apache to display directory index icons.
iconDir :: ConfigLine
type WebRoot = FilePath

-- | A basic virtual host, publishing a directory, and logging to the
--   combined apache log file. Not https capable.
virtualHost :: Domain -> Port -> WebRoot -> RevertableProperty DebianLike DebianLike

-- | Like virtualHost but with additional config lines added.
virtualHost' :: Domain -> Port -> WebRoot -> [ConfigLine] -> RevertableProperty DebianLike DebianLike

-- | A virtual host using https, with the certificate obtained using
--   letsEncrypt.
--   
--   http connections are redirected to https.
--   
--   Example:
--   
--   
--   httpsVirtualHost "example.com" "/var/www"
--   	(LetsEncrypt.AgreeTOS (Just "me@my.domain"))
--   
--   
--   Note that reverting this property does not remove the certificate from
--   letsencrypt's cert store.
httpsVirtualHost :: Domain -> WebRoot -> AgreeTOS -> RevertableProperty DebianLike DebianLike

-- | Like httpsVirtualHost but with additional config lines added.
httpsVirtualHost' :: Domain -> WebRoot -> AgreeTOS -> [ConfigLine] -> RevertableProperty DebianLike DebianLike

module Propellor.Property.LightDM
installed :: Property DebianLike

-- | Configures LightDM to skip the login screen and autologin as a user.
autoLogin :: User -> RevertableProperty DebianLike DebianLike

module Propellor.Property.Locale
type Locale = String
type LocaleVariable = String

-- | Select a locale for a list of global locale variables.
--   
--   A locale variable is of the form LC_BLAH, LANG or
--   LANGUAGE. See locale(5). One might say
--   
--   
--   & "en_GB.UTF-8" `Locale.selectedFor` ["LC_PAPER", "LC_MONETARY"]
--   
--   
--   to select the British English locale for paper size and currency
--   conventions.
--   
--   Note that reverting this property does not make a locale unavailable.
--   That's because it might be required for other Locale.selectedFor
--   statements.
selectedFor :: Locale -> [LocaleVariable] -> RevertableProperty DebianLike DebianLike
isSelectedFor :: Locale -> [LocaleVariable] -> IO Bool

-- | Ensures a locale is generated (or, if reverted, ensure it's not).
--   
--   Fails if a locale is not available to be generated. That is, a
--   commented out entry for the locale and an accompanying charset must be
--   present in etclocale.gen.
--   
--   Per Debian bug #684134 we cannot ensure a locale is generated by means
--   of Apt.reConfigure. So localeAvailable edits etclocale.gen
--   manually.
available :: Locale -> RevertableProperty DebianLike DebianLike

module Propellor.Property.Logcheck
data ReportLevel
Workstation :: ReportLevel
Server :: ReportLevel
Paranoid :: ReportLevel
type Service = String
defaultPrefix :: String
ignoreFilePath :: ReportLevel -> Service -> FilePath
ignoreLines :: ReportLevel -> Service -> [String] -> Property UnixLike
installed :: Property DebianLike
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Property.Logcheck.ReportLevel

-- | Support for the Obnam backup tool http://obnam.org/
--   
--   This module is deprecated because Obnam has been retired by its
--   author.

-- | Deprecated: Obnam has been retired; time to transition to something
--   else
module Propellor.Property.Obnam
type ObnamParam = String

-- | An obnam repository can be used by multiple clients. Obnam uses
--   locking to allow only one client to write at a time. Since stale lock
--   files can prevent backups from happening, it's more robust, if you
--   know a repository has only one client, to force the lock before
--   starting a backup. Using OnlyClient allows propellor to do so when
--   running obnam.
data NumClients
OnlyClient :: NumClients
MultipleClients :: NumClients

-- | Installs a cron job that causes a given directory to be backed up, by
--   running obnam with some parameters.
--   
--   If the directory does not exist, or exists but is completely empty,
--   this Property will immediately restore it from an existing backup.
--   
--   So, this property can be used to deploy a directory of content to a
--   host, while also ensuring any changes made to it get backed up. For
--   example:
--   
--   
--   & Obnam.backup "/srv/git" "33 3 * * *"
--   	[ "--repository=sftp://2318@usw-s002.rsync.net/~/mygitrepos.obnam"
--   	] Obnam.OnlyClient
--   	`requires` Ssh.keyImported SshRsa "root" (Context hostname)
--   
--   
--   How awesome is that?
--   
--   Note that this property does not make obnam encrypt the backup
--   repository.
--   
--   Since obnam uses a fair amount of system resources, only one obnam
--   backup job will be run at a time. Other jobs will wait their turns to
--   run.
backup :: FilePath -> Times -> [ObnamParam] -> NumClients -> Property DebianLike

-- | Like backup, but the specified gpg key id is used to encrypt the
--   repository.
--   
--   The gpg secret key will be automatically imported into root's keyring
--   using Propellor.Property.Gpg.keyImported
backupEncrypted :: FilePath -> Times -> [ObnamParam] -> NumClients -> GpgKeyId -> Property (HasInfo + DebianLike)

-- | Does a backup, but does not automatically restore.
backup' :: FilePath -> Times -> [ObnamParam] -> NumClients -> Property DebianLike

-- | Restores a directory from an obnam backup.
--   
--   Only does anything if the directory does not exist, or exists, but is
--   completely empty.
--   
--   The restore is performed atomically; restoring to a temp directory and
--   then moving it to the directory.
restored :: FilePath -> [ObnamParam] -> Property DebianLike

-- | Policy for backup generations to keep. For example, KeepDays 30 will
--   keep the latest backup for each day when a backup was made, and keep
--   the last 30 such backups. When multiple KeepPolicies are combined
--   together, backups meeting any policy are kept. See obnam's man page
--   for details.
data KeepPolicy
KeepHours :: Int -> KeepPolicy
KeepDays :: Int -> KeepPolicy
KeepWeeks :: Int -> KeepPolicy
KeepMonths :: Int -> KeepPolicy
KeepYears :: Int -> KeepPolicy

-- | Constructs an ObnamParam that specifies which old backup generations
--   to keep. By default, all generations are kept. However, when this
--   parameter is passed to the backup or backupEncrypted
--   properties, they will run obnam forget to clean out generations not
--   specified here.
keepParam :: [KeepPolicy] -> ObnamParam
isKeepParam :: ObnamParam -> Bool
installed :: Property DebianLike
instance GHC.Classes.Eq Propellor.Property.Obnam.NumClients

module Propellor.Property.OpenId

-- | Openid provider, using the simpleid PHP CGI, with apache.
--   
--   Runs on usual port by default. When a nonstandard port is specified,
--   apache is limited to listening only on that port. Warning: Specifying
--   a port won't compose well with other apache properties on the same
--   host.
--   
--   It's probably a good idea to put this property inside a docker or
--   systemd-nspawn container.
providerFor :: [User] -> HostName -> Maybe Port -> Property (HasInfo + DebianLike)

module Propellor.Property.Openssl
installed :: Property DebianLike
dhparamsLength :: Int
dhparams :: FilePath
safeDhparams :: Property DebianLike
createDhparams :: FilePath -> Int -> Property UnixLike

module Propellor.Property.Partition

-- | Filesystems etc that can be used for a partition.
data Fs
EXT2 :: Fs
EXT3 :: Fs
EXT4 :: Fs
BTRFS :: Fs
REISERFS :: Fs
XFS :: Fs
FAT :: Fs
VFAT :: Fs
NTFS :: Fs
LinuxSwap :: Fs

-- | Parse commonly used names of filesystems.
parseFs :: String -> Maybe Fs
data Eep
YesReallyFormatPartition :: Eep

-- | Formats a partition.
formatted :: Eep -> Fs -> FilePath -> Property DebianLike

-- | Options passed to a mkfs.* command when making a filesystem.
--   
--   Eg, ["-m0"]
type MkfsOpts = [String]
formatted' :: MkfsOpts -> Eep -> Fs -> FilePath -> Property DebianLike
data LoopDev
LoopDev :: FilePath -> FilePath -> LoopDev

-- | device for a loop partition
[partitionLoopDev] :: LoopDev -> FilePath

-- | corresponding device for the whole loop disk
[wholeDiskLoopDev] :: LoopDev -> FilePath
isLoopDev :: LoopDev -> IO Bool
isLoopDev' :: FilePath -> IO Bool

-- | Uses the kpartx utility to create device maps for partitions contained
--   within a disk image file. The resulting loop devices are passed to the
--   property, which can operate on them. Always cleans up after itself, by
--   removing the device maps after the property is run.
kpartx :: FilePath -> ([LoopDev] -> Property DebianLike) -> Property DebianLike
kpartxParse :: String -> [LoopDev]
instance GHC.Show.Show Propellor.Property.Partition.LoopDev
instance GHC.Classes.Eq Propellor.Property.Partition.Fs
instance GHC.Show.Show Propellor.Property.Partition.Fs

module Propellor.Property.Parted.Types
class PartedVal a
pval :: PartedVal a => a -> String

-- | Types of partition tables supported by parted.
data TableType
MSDOS :: TableType
GPT :: TableType
AIX :: TableType
AMIGA :: TableType
BSD :: TableType
DVH :: TableType
LOOP :: TableType
MAC :: TableType
PC98 :: TableType
SUN :: TableType

-- | A disk's partition table.
data PartTable
PartTable :: TableType -> Alignment -> [Partition] -> PartTable

-- | A partition on the disk.
data Partition
Partition :: PartType -> PartSize -> Maybe Fs -> MkfsOpts -> [(PartFlag, Bool)] -> Maybe String -> Partition
[partType] :: Partition -> PartType
[partSize] :: Partition -> PartSize
[partFs] :: Partition -> Maybe Fs
[partMkFsOpts] :: Partition -> MkfsOpts

-- | flags can be set or unset (parted may set some flags by default)
[partFlags] :: Partition -> [(PartFlag, Bool)]

-- | optional name for partition (only works for GPT, PC98, MAC)
[partName] :: Partition -> Maybe String

-- | Makes a Partition with defaults for non-important values.
mkPartition :: Maybe Fs -> PartSize -> Partition

-- | Type of a partition.
data PartType
Primary :: PartType
Logical :: PartType
Extended :: PartType

-- | Size of a partition.
data PartSize
MegaBytes :: Integer -> PartSize
Bytes :: Integer -> PartSize

-- | Rounds up to the nearest MegaByte.
toPartSize :: ByteSize -> PartSize
toPartSize' :: (Double -> Integer) -> ByteSize -> PartSize
fromPartSize :: PartSize -> ByteSize
reducePartSize :: PartSize -> PartSize -> PartSize

-- | Partitions need to be aligned for optimal efficiency. The alignment is
--   a number of bytes.
newtype Alignment
Alignment :: ByteSize -> Alignment

-- | 4MiB alignment is optimal for inexpensive flash drives and is a good
--   safe default for all drives.
safeAlignment :: Alignment
fromAlignment :: Alignment -> ByteSize

-- | Flags that can be set on a partition.
data PartFlag
BootFlag :: PartFlag
RootFlag :: PartFlag
SwapFlag :: PartFlag
HiddenFlag :: PartFlag
RaidFlag :: PartFlag
LvmFlag :: PartFlag
LbaFlag :: PartFlag
LegacyBootFlag :: PartFlag
IrstFlag :: PartFlag
EspFlag :: PartFlag
PaloFlag :: PartFlag
BiosGrubFlag :: PartFlag
instance GHC.Show.Show Propellor.Property.Parted.Types.PartTable
instance GHC.Show.Show Propellor.Property.Parted.Types.Partition
instance GHC.Show.Show Propellor.Property.Parted.Types.PartFlag
instance GHC.Classes.Ord Propellor.Property.Parted.Types.Alignment
instance GHC.Classes.Eq Propellor.Property.Parted.Types.Alignment
instance GHC.Show.Show Propellor.Property.Parted.Types.Alignment
instance GHC.Show.Show Propellor.Property.Parted.Types.PartSize
instance GHC.Show.Show Propellor.Property.Parted.Types.PartType
instance GHC.Show.Show Propellor.Property.Parted.Types.TableType
instance Propellor.Property.Parted.Types.PartedVal Propellor.Property.Parted.Types.TableType
instance GHC.Base.Monoid Propellor.Property.Parted.Types.PartTable
instance Propellor.Property.Parted.Types.PartedVal Propellor.Property.Parted.Types.PartType
instance GHC.Base.Monoid Propellor.Property.Parted.Types.PartSize
instance Propellor.Property.Parted.Types.PartedVal Propellor.Property.Parted.Types.PartFlag
instance Propellor.Property.Parted.Types.PartedVal GHC.Types.Bool
instance Propellor.Property.Parted.Types.PartedVal Propellor.Property.Partition.Fs

module Propellor.Types.PartSpec

-- | Specifies a mount point, mount options, and a constructor for a
--   Partition that determines its size.
type PartSpec t = (Maybe MountPoint, MountOpts, PartSize -> Partition, t)

-- | Specifies a partition table.
data PartTableSpec
PartTableSpec :: TableType -> [PartSpec ()] -> PartTableSpec
instance GHC.Show.Show Propellor.Types.PartSpec.PartTableSpec

module Propellor.Property.Parted

-- | Types of partition tables supported by parted.
data TableType
MSDOS :: TableType
GPT :: TableType
AIX :: TableType
AMIGA :: TableType
BSD :: TableType
DVH :: TableType
LOOP :: TableType
MAC :: TableType
PC98 :: TableType
SUN :: TableType

-- | A disk's partition table.
data PartTable
PartTable :: TableType -> Alignment -> [Partition] -> PartTable

-- | Gets the total size of the disk specified by the partition table.
partTableSize :: PartTable -> ByteSize

-- | A partition on the disk.
data Partition
Partition :: PartType -> PartSize -> Maybe Fs -> MkfsOpts -> [(PartFlag, Bool)] -> Maybe String -> Partition
[partType] :: Partition -> PartType
[partSize] :: Partition -> PartSize
[partFs] :: Partition -> Maybe Fs
[partMkFsOpts] :: Partition -> MkfsOpts

-- | flags can be set or unset (parted may set some flags by default)
[partFlags] :: Partition -> [(PartFlag, Bool)]

-- | optional name for partition (only works for GPT, PC98, MAC)
[partName] :: Partition -> Maybe String

-- | Makes a Partition with defaults for non-important values.
mkPartition :: Maybe Fs -> PartSize -> Partition

-- | Filesystems etc that can be used for a partition.
data Fs
EXT2 :: Fs
EXT3 :: Fs
EXT4 :: Fs
BTRFS :: Fs
REISERFS :: Fs
XFS :: Fs
FAT :: Fs
VFAT :: Fs
NTFS :: Fs
LinuxSwap :: Fs

-- | Size of a partition.
data PartSize
MegaBytes :: Integer -> PartSize
Bytes :: Integer -> PartSize
type ByteSize = Integer

-- | Rounds up to the nearest MegaByte.
toPartSize :: ByteSize -> PartSize
fromPartSize :: PartSize -> ByteSize
reducePartSize :: PartSize -> PartSize -> PartSize

-- | Partitions need to be aligned for optimal efficiency. The alignment is
--   a number of bytes.
newtype Alignment
Alignment :: ByteSize -> Alignment

-- | 4MiB alignment is optimal for inexpensive flash drives and is a good
--   safe default for all drives.
safeAlignment :: Alignment

-- | Options passed to a mkfs.* command when making a filesystem.
--   
--   Eg, ["-m0"]
type MkfsOpts = [String]

-- | Type of a partition.
data PartType
Primary :: PartType
Logical :: PartType
Extended :: PartType

-- | Flags that can be set on a partition.
data PartFlag
BootFlag :: PartFlag
RootFlag :: PartFlag
SwapFlag :: PartFlag
HiddenFlag :: PartFlag
RaidFlag :: PartFlag
LvmFlag :: PartFlag
LbaFlag :: PartFlag
LegacyBootFlag :: PartFlag
IrstFlag :: PartFlag
EspFlag :: PartFlag
PaloFlag :: PartFlag
BiosGrubFlag :: PartFlag

-- | Partitions a disk using parted, and formats the partitions.
--   
--   The FilePath can be a block device (eg, /dev/sda), or a disk image
--   file.
--   
--   This deletes any existing partitions in the disk! Use with EXTREME
--   caution!
partitioned :: Eep -> FilePath -> PartTable -> Property DebianLike

-- | Runs parted on a disk with the specified parameters.
--   
--   Parted is run in script mode, so it will never prompt for input.
parted :: Eep -> FilePath -> [String] -> Property (DebianLike + ArchLinux)
data Eep
YesReallyDeleteDiskContents :: Eep

-- | Gets parted installed.
installed :: Property (DebianLike + ArchLinux)

-- | Calculate a partition table, for a given size of disk.
--   
--   For example:
--   
--   
--   calcPartTable (DiskSize (1024 * 1024 * 1024 * 100)) MSDOS safeAlignment
--   		[ partition EXT2 `mountedAt` "/boot"
--   			`setSize` MegaBytes 256
--   			`setFlag` BootFlag
--   	, partition EXT4 `mountedAt` "/"
--   		`useDiskSpace` RemainingSpace
--   	]
--   
calcPartTable :: DiskSize -> TableType -> Alignment -> [PartSpec DiskPart] -> PartTable

-- | Size of a disk, in bytes.
newtype DiskSize
DiskSize :: ByteSize -> DiskSize
data DiskPart
data DiskSpaceUse
Percent :: Int -> DiskSpaceUse
RemainingSpace :: DiskSpaceUse

-- | Make a partition use some percentage of the size of the disk (less all
--   fixed size partitions), or the remaining space in the disk.
useDiskSpace :: PartSpec DiskPart -> DiskSpaceUse -> PartSpec DiskPart

-- | Default partition size when not otherwize specified is 128 MegaBytes.
defSz :: PartSize

-- | When a partition is sized to fit the files that live in it, this fudge
--   factor is added to the size of the files. This is necessary since
--   filesystems have some space overhead.
--   
--   Add 2% for filesystem overhead. Rationalle for picking 2%: A
--   filesystem with 1% overhead might just sneak by as acceptable. Double
--   that just in case. Add an additional 3 mb to deal with non-scaling
--   overhead of filesystems (eg, superblocks). Add an additional 200 mb
--   for temp files, journals, etc.
fudgeSz :: PartSize -> PartSize
instance GHC.Show.Show Propellor.Property.Parted.DiskSize
instance GHC.Base.Monoid Propellor.Property.Parted.DiskPart

-- | Disk image partition specification.
module Propellor.Property.DiskImage.PartSpec

-- | Specifies a mount point, mount options, and a constructor for a
--   Partition that determines its size.
type PartSpec t = (Maybe MountPoint, MountOpts, PartSize -> Partition, t)

-- | Filesystems etc that can be used for a partition.
data Fs
EXT2 :: Fs
EXT3 :: Fs
EXT4 :: Fs
BTRFS :: Fs
REISERFS :: Fs
XFS :: Fs
FAT :: Fs
VFAT :: Fs
NTFS :: Fs
LinuxSwap :: Fs

-- | Size of a partition.
data PartSize
MegaBytes :: Integer -> PartSize
Bytes :: Integer -> PartSize

-- | Specifies a partition with a given filesystem.
--   
--   The partition is not mounted anywhere by default; use the combinators
--   below to configure it.
partition :: Monoid t => Fs -> PartSpec t

-- | Specifies a swap partition of a given size.
swapPartition :: Monoid t => PartSize -> PartSpec t

-- | Specifies a partition without any filesystem, of a given size.
rawPartition :: Monoid t => PartSize -> PartSpec t

-- | Specifies where to mount a partition.
mountedAt :: PartSpec t -> MountPoint -> PartSpec t

-- | Partitions in disk images default to being sized large enough to hold
--   the files that live in that partition.
--   
--   This adds additional free space to a partition.
addFreeSpace :: PartSpec t -> PartSize -> PartSpec t

-- | Specify a fixed size for a partition.
setSize :: PartSpec t -> PartSize -> PartSpec t

-- | Specifies a mount option, such as "noexec"
mountOpt :: ToMountOpts o => PartSpec t -> o -> PartSpec t

-- | Mount option to make a partition be remounted readonly when there's an
--   error accessing it.
errorReadonly :: MountOpts

-- | Sets the percent of the filesystem blocks reserved for the super-user.
--   
--   The default is 5% for ext2 and ext4. Some filesystems may not support
--   this.
reservedSpacePercentage :: PartSpec t -> Int -> PartSpec t

-- | Sets a flag on the partition.
setFlag :: PartSpec t -> PartFlag -> PartSpec t

-- | Makes a MSDOS partition be Extended, rather than Primary.
extended :: PartSpec t -> PartSpec t

-- | Indicates that a host has a partition.
--   
--   For example:
--   
--   
--   & hasPartiton (partition EXT2 `mountedAt` "/boot" `partLocation` Beginning)
--   & hasPartiton (partition EXT4 `mountedAt` "/")
--   & hasPartiton (partition EXT4 `mountedAt` "/home" `partLocation` End `reservedSpacePercentage` 0)
--   
hasPartition :: PartSpec PartLocation -> Property (HasInfo + UnixLike)

-- | Adjusts the PartSpec for the partition mounted at the specified
--   location.
--   
--   For example:
--   
--   
--   & adjustPartition "/boot" (`addFreeSpace` MegaBytes 150)
--   
adjustPartition :: MountPoint -> (PartSpec PartLocation -> PartSpec PartLocation) -> Property (HasInfo + UnixLike)

-- | Indicates partition layout in a disk. Default is somewhere in the
--   middle.
data PartLocation
Beginning :: PartLocation
Middle :: PartLocation
End :: PartLocation
partLocation :: PartSpec PartLocation -> PartLocation -> PartSpec PartLocation

-- | Indicates the partition table type of a host.
--   
--   When not specified, the default is MSDOS.
--   
--   For example:
--   
--   
--   & hasPartitionTableType GPT
--   
hasPartitionTableType :: TableType -> Property (HasInfo + UnixLike)

-- | Types of partition tables supported by parted.
data TableType
MSDOS :: TableType
GPT :: TableType
AIX :: TableType
AMIGA :: TableType
BSD :: TableType
DVH :: TableType
LOOP :: TableType
MAC :: TableType
PC98 :: TableType
SUN :: TableType
data PartInfo
toPartTableSpec :: PartInfo -> PartTableSpec

-- | Specifies a partition table.
data PartTableSpec
PartTableSpec :: TableType -> [PartSpec ()] -> PartTableSpec
instance GHC.Base.Monoid Propellor.Property.DiskImage.PartSpec.PartInfo
instance GHC.Classes.Ord Propellor.Property.DiskImage.PartSpec.PartLocation
instance GHC.Classes.Eq Propellor.Property.DiskImage.PartSpec.PartLocation
instance Propellor.Types.Info.IsInfo Propellor.Property.DiskImage.PartSpec.PartInfo
instance GHC.Show.Show Propellor.Property.DiskImage.PartSpec.PartInfo
instance GHC.Base.Monoid Propellor.Property.DiskImage.PartSpec.PartLocation

module Propellor.Property.Qemu

-- | Installs qemu user mode emulation binaries, built statically, which
--   allow foreign binaries to run directly.
foreignBinariesEmulated :: RevertableProperty Linux Linux

-- | Removes qemu user mode emulation binary for the host CPU. This binary
--   is copied into a chroot by qemu-debootstrap, and is not part of any
--   package.
--   
--   Note that removing the binary will prevent using the chroot on the
--   host system.
--   
--   The FilePath is the path to the top of the chroot.
removeHostEmulationBinary :: FilePath -> Property Linux

-- | Check if the given System supports an Architecture.
--   
--   For example, on Debian, X86_64 supports X86_32, and vice-versa.
supportsArch :: System -> Architecture -> Bool

module Propellor.Property.Debootstrap
type Url = String

-- | A monoid for debootstrap configuration. mempty is a default
--   debootstrapped system.
data DebootstrapConfig
DefaultConfig :: DebootstrapConfig
MinBase :: DebootstrapConfig
BuilddD :: DebootstrapConfig
DebootstrapParam :: String -> DebootstrapConfig
UseEmulation :: DebootstrapConfig
(:+) :: DebootstrapConfig -> DebootstrapConfig -> DebootstrapConfig

-- | Builds a chroot in the given directory using debootstrap.
--   
--   The System can be any OS and architecture that debootstrap and the
--   kernel support.
--   
--   When the System is architecture that the kernel does not support, it
--   can still be bootstrapped using emulation. This is determined by
--   checking supportsArch, or can be configured with
--   UseEmulation.
--   
--   When emulation is used, the chroot will have an additional binary
--   installed in it. To get a completelty clean chroot (eg for producing a
--   bootable disk image), use the removeHostEmulationBinary
--   property.
built :: FilePath -> System -> DebootstrapConfig -> Property Linux

-- | Like built, but uses the provided Property to install
--   debootstrap.
built' :: Property Linux -> FilePath -> System -> DebootstrapConfig -> Property Linux
extractSuite :: System -> Maybe String

-- | Ensures debootstrap is installed.
--   
--   When necessary, falls back to installing debootstrap from source. Note
--   that installation from source is done by downloading the tarball from
--   a Debian mirror, with no cryptographic verification.
installed :: RevertableProperty Linux Linux
sourceInstall :: Property Linux
instance GHC.Show.Show Propellor.Property.Debootstrap.DebootstrapConfig
instance GHC.Base.Monoid Propellor.Property.Debootstrap.DebootstrapConfig

-- | Support for the restic backup tool
--   https://github.com/restic/restic
module Propellor.Property.Restic
data ResticRepo
Direct :: FilePath -> ResticRepo
SFTP :: User -> HostName -> FilePath -> ResticRepo
REST :: Url -> ResticRepo
installed :: Property DebianLike
repoExists :: ResticRepo -> IO Bool

-- | Inits a new restic repository
init :: ResticRepo -> Property (HasInfo + DebianLike)

-- | Restores a directory from a restic backup.
--   
--   Only does anything if the directory does not exist, or exists, but is
--   completely empty.
--   
--   The restore is performed atomically; restoring to a temp directory and
--   then moving it to the directory.
restored :: FilePath -> ResticRepo -> Property (HasInfo + DebianLike)

-- | Installs a cron job that causes a given directory to be backed up, by
--   running restic with some parameters.
--   
--   If the directory does not exist, or exists but is completely empty,
--   this Property will immediately restore it from an existing backup.
--   
--   So, this property can be used to deploy a directory of content to a
--   host, while also ensuring any changes made to it get backed up. For
--   example:
--   
--   
--   & Restic.backup "/srv/git"
--   	(Restic.SFTP (User root) (HostName myserver) /mnt/backup/git.restic")
--   	Cron.Daily
--   	["--exclude=/srv/git/tobeignored"]
--   	[Restic.KeepDays 7, Restic.KeepWeeks 4, Restic.KeepMonths 6, Restic.KeepYears 1]
--   
--   
--   Since restic uses a fair amount of system resources, only one restic
--   backup job will be run at a time. Other jobs will wait their turns to
--   run.
backup :: FilePath -> ResticRepo -> Times -> [ResticParam] -> [KeepPolicy] -> Property (HasInfo + DebianLike)

-- | Does a backup, but does not automatically restore.
backup' :: [FilePath] -> ResticRepo -> Times -> [ResticParam] -> [KeepPolicy] -> Property (HasInfo + DebianLike)

-- | Policy for backup generations to keep. For example, KeepDays 30 will
--   keep the latest backup for each day when a backup was made, and keep
--   the last 30 such backups. When multiple KeepPolicies are combined
--   together, backups meeting any policy are kept. See restic's man page
--   for details.
data KeepPolicy
KeepLast :: Int -> KeepPolicy
KeepHours :: Int -> KeepPolicy
KeepDays :: Int -> KeepPolicy
KeepWeeks :: Int -> KeepPolicy
KeepMonths :: Int -> KeepPolicy
KeepYears :: Int -> KeepPolicy
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Property.Restic.ResticRepo

module Propellor.Property.Rsync
type Src = FilePath
type Dest = FilePath
class RsyncParam p
toRsync :: RsyncParam p => p -> String

-- | A pattern that matches all files under a directory, but does not match
--   the directory itself.
filesUnder :: FilePath -> Pattern

-- | Ensures that the Dest directory exists and has identical contents as
--   the Src directory.
syncDir :: Src -> Dest -> Property (DebianLike + ArchLinux)
data Filter
Include :: Pattern -> Filter
Exclude :: Pattern -> Filter
Protect :: Pattern -> Filter

-- | A pattern to match against files that rsync is going to transfer.
--   
--   See "INCLUDE/EXCLUDE PATTERN RULES" in the rsync(1) man page.
--   
--   For example, Pattern "foo*" matches all files under the "foo"
--   directory, relative to the Src that rsync is acting on.
newtype Pattern
Pattern :: String -> Pattern

-- | Like syncDir, but avoids copying anything that the filter list
--   excludes. Anything that's filtered out will be deleted from Dest.
--   
--   Rsync checks each name to be transferred against its list of Filter
--   rules, and the first matching one is acted on. If no matching rule is
--   found, the file is processed.
syncDirFiltered :: [Filter] -> Src -> Dest -> Property (DebianLike + ArchLinux)
rsync :: [String] -> Property (DebianLike + ArchLinux)
installed :: Property (DebianLike + ArchLinux)
instance Propellor.Property.Rsync.RsyncParam Propellor.Property.Rsync.Filter

module Propellor.Property.Atomic

-- | Applies a Property to a directory such that the directory is updated
--   fully atomically; there is no point in time in which the directory
--   will be in an inconsistent state.
--   
--   For example, git repositories are not usually updated atomically, and
--   so while the repository is being updated, the files in it can be a
--   mixture of two different versions, which could cause unexpected
--   behavior to consumers. To avoid such problems:
--   
--   
--   & atomicDirUpdate "/srv/web/example.com"
--   	(\d -> Git.pulled "joey" "http://.." d Nothing)
--   
--   
--   This operates by making a second copy of the directory, and passing it
--   to the Property, which can make whatever changes it needs to that
--   copy, non-atomically. After the Property successfully makes a change,
--   the copy is swapped into place, fully atomically.
--   
--   This necessarily uses double the disk space, since there are two
--   copies of the directory. The parent directory will actually contain
--   three children: a symlink with the name of the directory itself, and
--   two copies of the directory, with names suffixed with ".1" and ".2"
atomicDirUpdate :: (Cannot_ensureProperty_WithInfo t ~ True, (Targets t `NotSuperset` Targets t) ~ CanCombine) => SingI t => FilePath -> (FilePath -> Property (MetaTypes t)) -> Property (MetaTypes t)

-- | This can optionally be used after atomicDirUpdate to rsync the changes
--   that were made over to the other copy of the directory. It's not
--   necessary to use this, but it can improve efficiency.
--   
--   For example:
--   
--   
--   & atomicDirUpdate "/srv/web/example.com"
--   	(\d -> Git.pulled "joey" "http://.." d Nothing)
--   	`onChange` atomicDirSync "/srv/web/example.com"
--   
--   
--   Using atomicDirSync in the above example lets git only download the
--   changes once, rather than the same changes being downloaded a second
--   time to update the other copy of the directory the next time propellor
--   runs.
--   
--   Suppose that a web server program is run from the git repository, and
--   needs to be restarted after the pull. That restart should be done
--   after the atomicDirUpdate, but before the atomicDirSync. That way, the
--   old web server process will not have its files changed out from under
--   it.
--   
--   
--   & atomicDirUpdate "/srv/web/example.com"
--   	(\d -> Git.pulled "joey" "http://.." d Nothing)
--   	`onChange` (webServerRestart `before` atomicDirSync "/srv/web/example.com")
--   
atomicDirSync :: FilePath -> Property (DebianLike + ArchLinux)

-- | Makes a non-atomic Property be atomic, by applying it to the
--   inactiveAtomicResource, and if it was successful, atomically
--   activating that resource.
atomicUpdate :: (Cannot_ensureProperty_WithInfo t ~ True, (Targets t `NotSuperset` Targets t) ~ CanCombine) => SingI t => AtomicResourcePair a -> CheckAtomicResourcePair a -> SwapAtomicResourcePair a -> (a -> Property (MetaTypes t)) -> Property (MetaTypes t)

-- | A pair of resources, one active and one inactive, which can swap
--   positions atomically.
data AtomicResourcePair a
AtomicResourcePair :: a -> a -> AtomicResourcePair a
[activeAtomicResource] :: AtomicResourcePair a -> a
[inactiveAtomicResource] :: AtomicResourcePair a -> a
flipAtomicResourcePair :: AtomicResourcePair a -> AtomicResourcePair a

-- | Action that activates the inactiveAtomicResource, and deactivates the
--   activeAtomicResource. This action must be fully atomic.
type SwapAtomicResourcePair a = AtomicResourcePair a -> Propellor Bool

-- | Checks which of the pair of resources is currently active and which is
--   inactive, and puts them in the correct poisition in the
--   AtomicResourcePair.
type CheckAtomicResourcePair a = AtomicResourcePair a -> Propellor (AtomicResourcePair a)

module Propellor.Property.Schroot
data UseOverlays
UseOverlays :: UseOverlays

-- | Indicate that a schroots on a host should use
--   union-type=overlay
--   
--   Setting this property does not actually ensure that the line
--   union-type=overlay is present in any schroot config files.
--   See built for example usage.
useOverlays :: Property (HasInfo + UnixLike)

-- | Gets whether a host uses overlays.
usesOverlays :: Propellor Bool

-- | Configure schroot such that all schroots with
--   union-type=overlay in their configuration will run their
--   overlays in a tmpfs.
--   
--   Implicitly sets useOverlays info property.
--   
--   Shell script from https://wiki.debian.org/sbuild.
overlaysInTmpfs :: Property (HasInfo + DebianLike)
installed :: Property DebianLike
instance GHC.Show.Show Propellor.Property.Schroot.UseOverlays
instance GHC.Classes.Eq Propellor.Property.Schroot.UseOverlays

module Propellor.Property.Fail2Ban
installed :: Property DebianLike
reloaded :: Property DebianLike
type Jail = String
type Filter = String
type Action = String

-- | By default, fail2ban only enables the ssh jail, but many others are
--   available to be enabled, for example "postfix-sasl"
jailEnabled :: Jail -> Property DebianLike
jailEnabled' :: Jail -> [(IniKey, String)] -> Property DebianLike

-- | Configures a jail. For example:
--   
--   
--   jailConfigured' "sshd" [("port", "2222")]
--   
jailConfigured' :: Jail -> [(IniKey, String)] -> Property UnixLike

-- | Adds a setting to a given jail. For example:
--   
--   
--   jailConfigured "sshd" "port"  "2222"
--   
jailConfigured :: Jail -> IniKey -> String -> Property UnixLike
oldJailConfFile :: Jail -> FilePath
jailConfFile :: Jail -> FilePath
filterConfFile :: Filter -> FilePath
actionConfFile :: Action -> FilePath

module Propellor.Property.Git

-- | Exports all git repos in a directory (that user nobody can read) using
--   git-daemon, run from inetd.
--   
--   Note that reverting this property does not remove or stop inetd.
daemonRunning :: FilePath -> RevertableProperty DebianLike DebianLike
installed :: Property DebianLike
type RepoUrl = String
type Branch = String

-- | Specified git repository is cloned to the specified directory.
--   
--   If the directory exists with some other content (either a non-git
--   repository, or a git repository cloned from some other location), it
--   will be recursively deleted first.
--   
--   A branch can be specified, to check out.
--   
--   Does not make subsequent changes be pulled into the repository after
--   it's cloned.
cloned :: User -> RepoUrl -> FilePath -> Maybe Branch -> Property DebianLike

-- | Specified git repository is cloned to the specified directory, and any
--   new commits are pulled into it each time this property runs.
pulled :: User -> RepoUrl -> FilePath -> Maybe Branch -> Property DebianLike
isGitDir :: FilePath -> IO Bool
data GitShared
Shared :: Group -> GitShared
SharedAll :: GitShared
NotShared :: GitShared

-- | Sets up a new, empty bare git repository.
bareRepo :: FilePath -> User -> GitShared -> Property UnixLike

-- | Set a key value pair in a git repo's configuration.
repoConfigured :: FilePath -> (String, String) -> Property UnixLike

-- | Gets the value that a key is set to in a git repo's configuration.
getRepoConfig :: FilePath -> String -> IO [String]

-- | Whether a repo accepts non-fast-forward pushes.
repoAcceptsNonFFs :: FilePath -> RevertableProperty UnixLike UnixLike

-- | Sets a bare repository's default branch, which will be checked out
--   when cloning it.
bareRepoDefaultBranch :: FilePath -> String -> Property UnixLike

module Propellor.Property.Nginx
type ConfigFile = [String]
siteEnabled :: HostName -> ConfigFile -> RevertableProperty DebianLike DebianLike
siteAvailable :: HostName -> ConfigFile -> Property DebianLike
siteCfg :: HostName -> FilePath
siteVal :: HostName -> FilePath
siteValRelativeCfg :: HostName -> LinkTarget
installed :: Property DebianLike
restarted :: Property DebianLike
reloaded :: Property DebianLike

module Propellor.Property.Prosody
type ConfigFile = [String]
type Conf = String
confEnabled :: Conf -> ConfigFile -> RevertableProperty DebianLike DebianLike
confAvailable :: Conf -> ConfigFile -> Property DebianLike
confAvailPath :: Conf -> FilePath
confValPath :: Conf -> FilePath
installed :: Property DebianLike
restarted :: Property DebianLike
reloaded :: Property DebianLike

module Propellor.Property.Systemd.Core
installed :: Property DebianLike

module Propellor.Property.Timezone

-- | A timezone from usrshare/zoneinfo
type Timezone = String

-- | Sets the system's timezone
configured :: Timezone -> Property DebianLike

module Propellor.Property.Tor
type HiddenServiceName = String
type NodeName = String

-- | Sets up a tor bridge. (Not a relay or exit node.)
--   
--   Uses port 443
isBridge :: Property DebianLike

-- | Sets up a tor relay.
--   
--   Uses port 443
isRelay :: Property DebianLike

-- | Makes the tor node be named, with a known private key.
--   
--   This can be moved to a different IP without needing to wait to
--   accumulate trust.
named :: NodeName -> Property (HasInfo + DebianLike)

-- | Configures tor with secret_id_key, ed25519_master_id_public_key, and
--   ed25519_master_id_secret_key from privdata.
torPrivKey :: Context -> Property (HasInfo + DebianLike)
torPrivKeyDirExists :: Property DebianLike
torPrivKeyDir :: FilePath

-- | A tor server (bridge, relay, or exit) Don't use if you just want to
--   run tor for personal use.
server :: Property DebianLike
installed :: Property DebianLike

-- | Specifies configuration settings. Any lines in the config file that
--   set other values for the specified settings will be removed, while
--   other settings are left as-is. Tor is restarted when configuration is
--   changed.
configured :: [(String, String)] -> Property DebianLike
data BwLimit
PerSecond :: String -> BwLimit
PerDay :: String -> BwLimit
PerMonth :: String -> BwLimit

-- | Limit incoming and outgoing traffic to the specified amount each.
--   
--   For example, PerSecond "30 kibibytes" is the minimum limit for a
--   useful relay.
bandwidthRate :: BwLimit -> Property DebianLike
bandwidthRate' :: String -> Integer -> Property DebianLike

-- | Enables a hidden service for a given port.
--   
--   If used without hiddenServiceData, tor will generate a new
--   private key.
hiddenService :: HiddenServiceName -> Port -> Property DebianLike
hiddenService' :: HiddenServiceName -> [Port] -> Property DebianLike

-- | Same as hiddenService but also causes propellor to display the
--   onion address of the hidden service.
hiddenServiceAvailable :: HiddenServiceName -> Port -> Property DebianLike
hiddenServiceAvailable' :: HiddenServiceName -> [Port] -> Property DebianLike

-- | Load the private key for a hidden service from the privdata.
hiddenServiceData :: IsContext c => HiddenServiceName -> c -> Property (HasInfo + DebianLike)
restarted :: Property DebianLike
mainConfig :: FilePath
varLib :: FilePath
varRun :: FilePath
user :: User
type NickName = String

-- | Convert String to a valid tor NickName.
saneNickname :: String -> NickName

-- | Properties for the Unbound caching DNS server
module Propellor.Property.Unbound
installed :: Property DebianLike
restarted :: Property DebianLike
reloaded :: Property DebianLike
type UnboundSection = (ConfSection, [UnboundSetting])
type UnboundZone = (BindDomain, ZoneType)
type UnboundHost = (BindDomain, Record)
type UnboundSetting = (UnboundKey, UnboundValue)
type UnboundValue = String
type UnboundKey = String
type ConfSection = String
type ZoneType = String

-- | Provided a [UnboundSection], a [UnboundZone] and a [UnboundHost],
--   cachingDnsServer ensure unbound is configured accordingly.
--   
--   Example property:
--   
--   
--   cachingDnsServer
--        [ ("remote-control", [("control-enable", "no")]
--        , ("server",
--        	[ ("interface", "0.0.0.0")
--        	, ("access-control", "192.168.1.0/24 allow")
--        	, ("do-tcp", "no")
--        	])
--        [ (AbsDomain "example.com", "transparent")
--        , (AbsDomain $ reverseIP $ IPv4 "192.168.1", "static")
--        ]
--        [ (AbsDomain "example.com", Address $ IPv4 "192.168.1.2")
--        , (AbsDomain "myhost.example.com", Address $ IPv4 "192.168.1.2")
--        , (AbsDomain "myrouter.example.com", Address $ IPv4 "192.168.1.1")
--        , (AbsDomain "www.example.com", Address $ IPv4 "192.168.1.2")
--        , (AbsDomain "example.com", MX 10 "mail.example.com")
--        , (AbsDomain "mylaptop.example.com", Address $ IPv4 "192.168.1.2")
--        -- ^ connected via ethernet
--        , (AbsDomain "mywifi.example.com", Address $ IPv4 "192.168.2.1")
--        , (AbsDomain "mylaptop.example.com", Address $ IPv4 "192.168.2.2")
--        -- ^ connected via wifi, use round robin
--        , (AbsDomain "myhost.example.com", PTR $ reverseIP $ IPv4 "192.168.1.2")
--        , (AbsDomain "myrouter.example.com", PTR $ reverseIP $ IPv4 "192.168.1.1")
--        , (AbsDomain "mylaptop.example.com", PTR $ reverseIP $ IPv4 "192.168.1.2")
--        ]
--   
cachingDnsServer :: [UnboundSection] -> [UnboundZone] -> [UnboundHost] -> Property DebianLike

module Propellor.Property.User
data Eep
YesReallyDeleteHome :: Eep
accountFor :: User -> Property DebianLike
systemAccountFor :: User -> Property DebianLike
systemAccountFor' :: User -> Maybe FilePath -> Maybe Group -> Property DebianLike
systemGroup :: Group -> Property UnixLike

-- | Removes user home directory!! Use with caution.
nuked :: User -> Eep -> Property Linux

-- | Only ensures that the user has some password set. It may or may not be
--   a password from the PrivData.
hasSomePassword :: User -> Property (HasInfo + DebianLike)

-- | While hasSomePassword uses the name of the host as context, this
--   allows specifying a different context. This is useful when you want to
--   use the same password on multiple hosts, for example.
hasSomePassword' :: IsContext c => User -> c -> Property (HasInfo + DebianLike)

-- | Ensures that a user's password is set to a password from the PrivData.
--   (Will change any existing password.)
--   
--   A user's password can be stored in the PrivData in either of two
--   forms; the full cleartext Password or a CryptPassword
--   hash. The latter is obviously more secure.
hasPassword :: User -> Property (HasInfo + DebianLike)
hasPassword' :: IsContext c => User -> c -> Property (HasInfo + DebianLike)
setPassword :: (((PrivDataField, PrivData) -> Propellor Result) -> Propellor Result) -> Propellor Result

-- | Makes a user's password be the passed String. Highly insecure: The
--   password is right there in your config file for anyone to see!
hasInsecurePassword :: User -> String -> Property DebianLike
chpasswd :: User -> String -> [String] -> Propellor Result
lockedPassword :: User -> Property DebianLike
data PasswordStatus
NoPassword :: PasswordStatus
LockedPassword :: PasswordStatus
HasPassword :: PasswordStatus
getPasswordStatus :: User -> IO PasswordStatus
isLockedPassword :: User -> IO Bool
homedir :: User -> IO FilePath
hasGroup :: User -> Group -> Property DebianLike

-- | Gives a user access to the secondary groups, including audio and
--   video, that the OS installer normally gives a desktop user access to.
--   
--   Note that some groups may only exit after installation of other
--   software. When a group does not exist yet, the user won't be added to
--   it.
hasDesktopGroups :: User -> Property DebianLike

-- | Controls whether shadow passwords are enabled or not.
shadowConfig :: Bool -> Property DebianLike
shadowExists :: IO Bool

-- | Ensures that a user has a specified login shell, and that the shell is
--   enabled in etcshells.
hasLoginShell :: User -> FilePath -> Property DebianLike
shellSetTo :: User -> FilePath -> Property DebianLike

-- | Ensures that etcshells contains a shell.
shellEnabled :: FilePath -> Property DebianLike
instance GHC.Classes.Eq Propellor.Property.User.PasswordStatus

module Propellor.Property.DebianMirror
data DebianPriority
Essential :: DebianPriority
Required :: DebianPriority
Important :: DebianPriority
Standard :: DebianPriority
Optional :: DebianPriority
Extra :: DebianPriority
showPriority :: DebianPriority -> String
mirror :: DebianMirror -> Property DebianLike
data RsyncExtra
Doc :: RsyncExtra
Indices :: RsyncExtra
Tools :: RsyncExtra
Trace :: RsyncExtra
data Method
Ftp :: Method
Http :: Method
Https :: Method
Rsync :: Method
MirrorFile :: Method

-- | To get a new DebianMirror and set options, use:
--   
--   
--   mkDebianMirror mymirrordir mycrontimes
--   	. debianMirrorHostName "otherhostname"
--   	. debianMirrorSourceBool True
--   
data DebianMirror
debianMirrorHostName :: HostName -> DebianMirror -> DebianMirror
debianMirrorSuites :: [DebianSuite] -> DebianMirror -> DebianMirror
debianMirrorArchitectures :: [Architecture] -> DebianMirror -> DebianMirror
debianMirrorSections :: [Section] -> DebianMirror -> DebianMirror
debianMirrorSourceBool :: Bool -> DebianMirror -> DebianMirror
debianMirrorPriorities :: [DebianPriority] -> DebianMirror -> DebianMirror
debianMirrorMethod :: Method -> DebianMirror -> DebianMirror
debianMirrorKeyring :: FilePath -> DebianMirror -> DebianMirror
debianMirrorRsyncExtra :: [RsyncExtra] -> DebianMirror -> DebianMirror
mkDebianMirror :: FilePath -> Times -> DebianMirror
instance GHC.Classes.Eq Propellor.Property.DebianMirror.RsyncExtra
instance GHC.Show.Show Propellor.Property.DebianMirror.RsyncExtra
instance GHC.Classes.Eq Propellor.Property.DebianMirror.DebianPriority
instance GHC.Show.Show Propellor.Property.DebianMirror.DebianPriority

module Propellor.Property.Group
type GID = Int
exists :: Group -> Maybe GID -> Property UnixLike
hasUser :: Group -> User -> Property DebianLike

module Propellor.Property.Kerberos
type Realm = String
type Principal = String
type Kvno = Integer
defaultKeyTab :: FilePath
kadmAclPath :: FilePath
kpropdAclPath :: FilePath
kdcConfPath :: FilePath
keyTabPath :: Maybe FilePath -> FilePath

-- | Create a principal from a primary, instance and realm
principal :: String -> Maybe String -> Maybe Realm -> Principal
installed :: Property DebianLike
kdcInstalled :: Property DebianLike
adminServerInstalled :: Property DebianLike
kpropServerInstalled :: Property DebianLike
kpropAcls :: [String] -> Property UnixLike
k5srvutil :: (Maybe FilePath) -> [String] -> IO String
keytabEntries :: Maybe FilePath -> IO [(Kvno, Principal)]
checkKeyTabEntry' :: Maybe FilePath -> (Kvno, Principal) -> IO Bool
checkKeyTabEntry :: Maybe FilePath -> Principal -> IO Bool
k5loginPath :: User -> IO FilePath
k5login :: User -> [Principal] -> Property UnixLike

module Propellor.Property.Postfix
installed :: Property DebianLike
restarted :: Property DebianLike
reloaded :: Property DebianLike

-- | Configures postfix as a satellite system, which relays all mail
--   through a relay host, which defaults to smtp.domain, but can be
--   changed by mainCf "relayhost".
--   
--   The smarthost may refuse to relay mail on to other domains, without
--   further configuration/keys. But this should be enough to get cron job
--   mail flowing to a place where it will be seen.
satellite :: Property DebianLike

-- | Sets up a file by running a property (which the filename is passed
--   to). If the setup property makes a change, postmap will be run on the
--   file, and postfix will be reloaded.
mappedFile :: Combines (Property x) (Property UnixLike) => FilePath -> (FilePath -> Property x) -> CombinedType (Property x) (Property UnixLike)

-- | Run newaliases command, which should be done after changing
--   etcaliases.
newaliases :: Property UnixLike

-- | The main config file for postfix.
mainCfFile :: FilePath

-- | Sets a main.cf name=value pair. Does not reload postfix
--   immediately.
mainCf :: (String, String) -> Property UnixLike

-- | Gets a main.cf setting.
getMainCf :: String -> IO (Maybe String)

-- | Checks if a main.cf field is set. A field that is set to the empty
--   string is considered not set.
mainCfIsSet :: String -> IO Bool

-- | Parses main.cf, and removes any initial configuration lines that are
--   overridden to other values later in the file.
--   
--   For example, to add some settings, removing any old settings:
--   
--   
--   mainCf `File.containsLines`
--   [ "# I like bars."
--   , "foo = bar"
--   ] `onChange` dedupMainCf
--   
--   
--   Note that multiline configurations that continue onto the next line
--   are not currently supported.
dedupMainCf :: Property UnixLike
dedupCf :: [String] -> [String]

-- | The master config file for postfix.
masterCfFile :: FilePath

-- | A service that can be present in the master config file.
data Service
Service :: ServiceType -> String -> ServiceOpts -> Service
[serviceType] :: Service -> ServiceType
[serviceCommand] :: Service -> String
[serviceOpts] :: Service -> ServiceOpts
data ServiceType
InetService :: (Maybe HostName) -> ServicePort -> ServiceType
UnixService :: FilePath -> PrivateService -> ServiceType
FifoService :: FilePath -> PrivateService -> ServiceType
PassService :: FilePath -> PrivateService -> ServiceType
type ServicePort = String
type PrivateService = Bool

-- | Options for a service.
data ServiceOpts
ServiceOpts :: Maybe Bool -> Maybe Bool -> Maybe Int -> Maybe Int -> ServiceOpts
[serviceUnprivileged] :: ServiceOpts -> Maybe Bool
[serviceChroot] :: ServiceOpts -> Maybe Bool
[serviceWakeupTime] :: ServiceOpts -> Maybe Int
[serviceProcessLimit] :: ServiceOpts -> Maybe Int
defServiceOpts :: ServiceOpts
formatServiceLine :: Service -> Line

-- | Note that this does not handle multi-line service entries, in which
--   subsequent lines are indented. serviceLine does not generate
--   such entries.
parseServiceLine :: Line -> Maybe Service

-- | Enables a Service in postfix's masterCfFile.
service :: Service -> RevertableProperty DebianLike DebianLike

-- | Installs saslauthd and configures it for postfix, authenticating
--   against PAM.
--   
--   Does not configure postfix to use it; eg smtpd_sasl_auth_enable =
--   yes needs to be set to enable use. See
--   https://wiki.debian.org/PostfixAndSASL.
--   
--   Password brute force attacks are possible when SASL auth is enabled.
--   It would be wise to enable fail2ban, for example:
--   
--   
--   Fail2Ban.jailEnabled "postfix-sasl"
--   
saslAuthdInstalled :: Property DebianLike

-- | Uses saslpasswd2 to set the password for a user in the
--   sasldb2 file.
--   
--   The password is taken from the privdata.
saslPasswdSet :: Domain -> User -> Property (HasInfo + UnixLike)
instance GHC.Classes.Eq Propellor.Property.Postfix.Service
instance GHC.Show.Show Propellor.Property.Postfix.Service
instance GHC.Classes.Eq Propellor.Property.Postfix.ServiceOpts
instance GHC.Show.Show Propellor.Property.Postfix.ServiceOpts
instance GHC.Classes.Eq Propellor.Property.Postfix.ServiceType
instance GHC.Show.Show Propellor.Property.Postfix.ServiceType

module Propellor.Property.SiteSpecific.GitHome

-- | Clones Joey Hess's git home directory, and runs its fixups script.
installedFor :: User -> Property DebianLike
url :: String
hasGitDir :: User -> IO Bool

module Propellor.Property.Ssh
installed :: Property UnixLike
restarted :: Property DebianLike

-- | The text of a ssh public key, for example, "ssh-ed25519
--   AAAAC3NzaC1lZDI1NTE5AAAAIB3BJ2GqZiTR2LEoDXyYFgh/BduWefjdKXAsAtzS9zeI"
type PubKeyText = String
data SshKeyType
SshRsa :: SshKeyType
SshDsa :: SshKeyType
SshEcdsa :: SshKeyType
SshEd25519 :: SshKeyType
sshdConfig :: FilePath
type ConfigKeyword = String
setSshdConfigBool :: ConfigKeyword -> Bool -> Property DebianLike
setSshdConfig :: ConfigKeyword -> String -> Property DebianLike
data RootLogin

-- | allow or prevent root login
RootLogin :: Bool -> RootLogin

-- | disable password authentication for root, while allowing other
--   authentication methods
WithoutPassword :: RootLogin

-- | allow root login with public-key authentication, but only if a forced
--   command has been specified for the public key
ForcedCommandsOnly :: RootLogin
permitRootLogin :: RootLogin -> Property DebianLike
passwordAuthentication :: Bool -> Property DebianLike

-- | Configure ssh to not allow password logins.
--   
--   To prevent lock-out, this is done only once root's authorized_keys is
--   in place.
noPasswords :: Property DebianLike

-- | Makes the ssh server listen on a given port, in addition to any other
--   ports it is configured to listen on.
--   
--   Revert to prevent it listening on a particular port.
listenPort :: Port -> RevertableProperty DebianLike DebianLike

-- | Blows away existing host keys and make new ones. Useful for systems
--   installed from an image that might reuse host keys. A flag file is
--   used to only ever do this once.
randomHostKeys :: Property DebianLike

-- | Installs the specified list of ssh host keys.
--   
--   The corresponding private keys come from the privdata.
--   
--   Any host keys that are not in the list are removed from the host.
hostKeys :: IsContext c => c -> [(SshKeyType, PubKeyText)] -> Property (HasInfo + DebianLike)

-- | Installs a single ssh host key of a particular type.
--   
--   The public key is provided to this function; the private key comes
--   from the privdata;
hostKey :: IsContext c => c -> SshKeyType -> PubKeyText -> Property (HasInfo + DebianLike)

-- | Indicates the host key that is used by a Host, but does not actually
--   configure the host to use it. Normally this does not need to be used;
--   use hostKey instead.
hostPubKey :: SshKeyType -> PubKeyText -> Property (HasInfo + UnixLike)
getHostPubKey :: Propellor (Map SshKeyType PubKeyText)

-- | Sets up a user with the specified public keys, and the corresponding
--   private keys from the privdata.
--   
--   The public keys are added to the Info, so other properties like
--   authorizedKeysFrom can use them.
userKeys :: IsContext c => User -> c -> [(SshKeyType, PubKeyText)] -> Property (HasInfo + UnixLike)

-- | Sets up a user with the specified pubic key, and a private key from
--   the privdata.
--   
--   A file can be specified to write the key to somewhere other than the
--   default locations. Allows a user to have multiple keys for different
--   roles.
userKeyAt :: IsContext c => Maybe FilePath -> User -> c -> (SshKeyType, PubKeyText) -> Property (HasInfo + UnixLike)

-- | Puts some host's ssh public key(s), as set using hostPubKey or
--   hostKey into the known_hosts file for a user.
knownHost :: [Host] -> HostName -> User -> Property UnixLike

-- | Reverts knownHost
unknownHost :: [Host] -> HostName -> User -> Property UnixLike

-- | Ensures that a local user's authorized_keys contains lines allowing
--   logins from a remote user on the specified Host.
--   
--   The ssh keys of the remote user can be set using userKeys
--   
--   Any other lines in the authorized_keys file are preserved as-is.
authorizedKeysFrom :: User -> (User, Host) -> Property UnixLike

-- | Reverts authorizedKeysFrom
unauthorizedKeysFrom :: User -> (User, Host) -> Property UnixLike

-- | Makes a user have authorized_keys from the PrivData
--   
--   This removes any other lines from the file.
authorizedKeys :: IsContext c => User -> c -> Property (HasInfo + UnixLike)

-- | Ensures that a user's authorized_keys contains a line. Any other lines
--   in the file are preserved as-is.
authorizedKey :: User -> String -> RevertableProperty UnixLike UnixLike
hasAuthorizedKeys :: User -> IO Bool
getUserPubKeys :: User -> Propellor [(SshKeyType, PubKeyText)]
instance GHC.Show.Show Propellor.Property.Ssh.UserKeyInfo
instance GHC.Classes.Ord Propellor.Property.Ssh.UserKeyInfo
instance GHC.Classes.Eq Propellor.Property.Ssh.UserKeyInfo
instance GHC.Show.Show Propellor.Property.Ssh.HostKeyInfo
instance GHC.Classes.Ord Propellor.Property.Ssh.HostKeyInfo
instance GHC.Classes.Eq Propellor.Property.Ssh.HostKeyInfo
instance Propellor.Types.Info.IsInfo Propellor.Property.Ssh.HostKeyInfo
instance GHC.Base.Monoid Propellor.Property.Ssh.HostKeyInfo
instance Propellor.Types.Info.IsInfo Propellor.Property.Ssh.UserKeyInfo
instance GHC.Base.Monoid Propellor.Property.Ssh.UserKeyInfo

module Propellor.Property.Dns

-- | Primary dns server for a domain, using bind.
--   
--   Currently, this only configures bind to serve forward DNS, not reverse
--   DNS.
--   
--   Most of the content of the zone file is configured by setting
--   properties of hosts. For example,
--   
--   
--   host "foo.example.com"
--     & ipv4 "192.168.1.1"
--     & alias "mail.exmaple.com"
--   
--   
--   Will cause that hostmame and its alias to appear in the zone file,
--   with the configured IP address.
--   
--   Also, if a host has a ssh public key configured, a SSHFP record will
--   be automatically generated for it.
--   
--   The [(BindDomain, Record)] list can be used for additional records
--   that cannot be configured elsewhere. This often includes NS records,
--   TXT records and perhaps CNAMEs pointing at hosts that propellor does
--   not control.
--   
--   The primary server is configured to only allow zone transfers to
--   secondary dns servers. These are determined in two ways:
--   
--   
--   
- By looking at the properties of other hosts, to find hosts that
--   are configured as the secondary dns server.
--   
- By looking for NS Records in the passed list of records.
--   
--   
--   In either case, the secondary dns server Host should have an ipv4
--   and/or ipv6 property defined.
primary :: [Host] -> Domain -> SOA -> [(BindDomain, Record)] -> RevertableProperty (HasInfo + DebianLike) DebianLike

-- | Primary dns server for a domain, secured with DNSSEC.
--   
--   This is like primary, except the resulting zone file is signed.
--   The Zone Signing Key (ZSK) and Key Signing Key (KSK) used in signing
--   it are taken from the PrivData.
--   
--   As a side effect of signing the zone, a
--   /var/cache/bind/dsset-domain. file will be created. This file
--   contains the DS records which need to be communicated to your domain
--   registrar to make DNSSEC be used for your domain. Doing so is outside
--   the scope of propellor (currently). See for example the tutorial
--   https://www.digitalocean.com/community/tutorials/how-to-setup-dnssec-on-an-authoritative-bind-dns-server--2
--   
--   The Recurrance controls how frequently the signature should be
--   regenerated, using a new random salt, to prevent zone walking attacks.
--   `Weekly Nothing` is a reasonable choice.
--   
--   To transition from primary to signedPrimary, you can
--   revert the primary property, and add this property.
--   
--   Note that DNSSEC zone files use a serial number based on the unix
--   epoch. This is different from the serial number used by
--   primary, so if you want to later disable DNSSEC you will need
--   to adjust the serial number passed to mkSOA to ensure it is larger.
signedPrimary :: Recurrance -> [Host] -> Domain -> SOA -> [(BindDomain, Record)] -> RevertableProperty (HasInfo + DebianLike) DebianLike

-- | Secondary dns server for a domain.
--   
--   The primary server is determined by looking at the properties of other
--   hosts to find which one is configured as the primary.
--   
--   Note that if a host is declared to be a primary and a secondary dns
--   server for the same domain, the primary server config always wins.
secondary :: [Host] -> Domain -> RevertableProperty (HasInfo + DebianLike) DebianLike

-- | This variant is useful if the primary server does not have its DNS
--   configured via propellor.
secondaryFor :: [HostName] -> [Host] -> Domain -> RevertableProperty (HasInfo + DebianLike) DebianLike

-- | Generates a SOA with some fairly sane numbers in it.
--   
--   The Domain is the domain to use in the SOA record. Typically something
--   like ns1.example.com. So, not the domain that this is the SOA record
--   for.
--   
--   The SerialNumber can be whatever serial number was used by the domain
--   before propellor started managing it. Or 0 if the domain has only ever
--   been managed by propellor.
--   
--   You do not need to increment the SerialNumber when making changes!
--   Propellor will automatically add the number of commits in the git
--   repository to the SerialNumber.
mkSOA :: Domain -> SerialNumber -> SOA

-- | Write a Zone out to a to a file.
--   
--   The serial number in the Zone automatically has the serialNumberOffset
--   added to it. Also, just in case, the old serial number used in the
--   zone file is checked, and if it is somehow larger, its succ is used.
writeZoneFile :: Zone -> FilePath -> IO ()

-- | Adjusts the serial number of the zone to always be larger than the
--   serial number in the Zone record, and always be larger than the passed
--   SerialNumber.
nextSerialNumber :: Zone -> SerialNumber -> Zone
adjustSerialNumber :: Zone -> (SerialNumber -> SerialNumber) -> Zone

-- | Count the number of git commits made to the current branch.
serialNumberOffset :: IO SerialNumber
type WarningMessage = String

-- | Generates a Zone for a particular Domain from the DNS properies of all
--   hosts that propellor knows about that are in that Domain.
--   
--   Does not include SSHFP records.
genZone :: [Host] -> Map HostName Host -> Domain -> SOA -> (Zone, [WarningMessage])

module Propellor.Property.OS

-- | Replaces whatever OS was installed before with a clean installation of
--   the OS that the Host is configured to have.
--   
--   This is experimental; use with caution!
--   
--   This can replace one Linux distribution with different one. But, it
--   can also fail and leave the system in an unbootable state.
--   
--   To avoid this property being accidentially used, you have to provide a
--   Confirmation containing the name of the host that you intend to apply
--   the property to.
--   
--   This property only runs once. The cleanly installed system will have a
--   file /etc/propellor-cleaninstall, which indicates it was
--   cleanly installed.
--   
--   The files from the old os will be left in /old-os
--   
--   After the OS is installed, and if all properties of the host have been
--   successfully satisfied, the host will be rebooted to properly load the
--   new OS.
--   
--   You will typically want to run some more properties after the clean
--   install succeeds, to bootstrap from the cleanly installed system to a
--   fully working system. For example:
--   
--   
--   & osDebian Unstable X86_64
--   & cleanInstallOnce (Confirmed "foo.example.com")
--      `onChange` propertyList "fixing up after clean install"
--          [ preserveNetwork
--          , preserveResolvConf
--          , preserveRootSshAuthorized
--          , Apt.update
--          -- , Grub.boots "/dev/sda"
--          --   `requires` Grub.installed Grub.PC
--          -- , oldOsRemoved (Confirmed "foo.example.com")
--          ]
--   & Hostname.sane
--   & Apt.installed ["linux-image-amd64"]
--   & Apt.installed ["ssh"]
--   & User.hasSomePassword "root"
--   & User.accountFor "joey"
--   & User.hasSomePassword "joey"
--   -- rest of system properties here
--   
cleanInstallOnce :: Confirmation -> Property DebianLike
data Confirmation
Confirmed :: HostName -> Confirmation

-- | /etc/network/interfaces is configured to bring up the network
--   interface that currently has a default route configured, using the
--   same (static) IP address.
preserveNetwork :: Property DebianLike

-- | /etc/resolv.conf is copied from the old OS
preserveResolvConf :: Property Linux

-- | /root/.ssh/authorized_keys has added to it any ssh keys that
--   were authorized in the old OS. Any other contents of the file are
--   retained.
preserveRootSshAuthorized :: Property UnixLike
oldOSRemoved :: Confirmation -> Property UnixLike

module Propellor.Property.Sudo

-- | Allows a user to sudo. If the user has a password, sudo is configured
--   to require it. If not, NOPASSWORD is enabled for the user.
enabledFor :: User -> RevertableProperty DebianLike DebianLike

module Propellor.Property.SiteSpecific.Branchable
server :: [Host] -> Property (HasInfo + DebianLike)

module Propellor.Property.Uwsgi
type ConfigFile = [String]
type AppName = String
appEnabled :: AppName -> ConfigFile -> RevertableProperty DebianLike DebianLike
appAvailable :: AppName -> ConfigFile -> Property DebianLike
appCfg :: AppName -> FilePath
appVal :: AppName -> FilePath
appValRelativeCfg :: AppName -> LinkTarget
installed :: Property DebianLike
restarted :: Property DebianLike
reloaded :: Property DebianLike

module Propellor.Property.XFCE
installed :: Property DebianLike

-- | Minimal install of XFCE, with a terminal emulator and panel, and X and
--   network-manager, but not any of the extra apps.
installedMin :: Property DebianLike

-- | Installs network-manager-gnome, which is the way to get
--   network-manager to manage networking in XFCE too.
networkManager :: Property DebianLike

-- | Normally at first login, XFCE asks what kind of panel the user wants.
--   This enables the default configuration noninteractively.
defaultPanelFor :: User -> Overwrite -> Property DebianLike

-- | Functions running zfs processes.
module Propellor.Property.ZFS.Process

-- | Gets the properties of a ZFS volume.
zfsGetProperties :: ZFS -> IO ZFSProperties
zfsExists :: ZFS -> IO Bool

-- | Runs the zfs command with the arguments.
--   
--   Runs the command with -H which will skip the header line and separate
--   all fields with tabs.
--   
--   Replaces Nothing in the argument list with the ZFS pool/dataset.
runZfs :: String -> [Maybe String] -> ZFS -> IO [String]

-- | Return the ZFS command line suitable for readProcess or cmdProperty.
zfsCommand :: String -> [Maybe String] -> ZFS -> (String, [String])

-- | Functions defining zfs Properties.
module Propellor.Property.ZFS.Properties

-- | OS's that support ZFS
type ZFSOS = Linux + FreeBSD

-- | Will ensure that a ZFS volume exists with the specified mount point.
--   This requires the pool to exist as well, but we don't create pools
--   yet.
zfsExists :: ZFS -> Property ZFSOS

-- | Sets the given properties. Returns True if all were successfully
--   changed, False if not.
zfsSetProperties :: ZFS -> ZFSProperties -> Property ZFSOS

-- | ZFS properties
module Propellor.Property.ZFS

-- | FreeBSD Poudriere properties
module Propellor.Property.FreeBSD.Poudriere
poudriereConfigPath :: FilePath
newtype PoudriereConfigured
PoudriereConfigured :: String -> PoudriereConfigured
poudriereConfigured :: PoudriereConfigured -> Bool
setConfigured :: Property (HasInfo + FreeBSD)
poudriere :: Poudriere -> Property (HasInfo + FreeBSD)
poudriereCommand :: String -> [String] -> (String, [String])
runPoudriere :: String -> [String] -> IO [String]
listJails :: IO [String]
jailExists :: Jail -> IO Bool
jail :: Jail -> Property FreeBSD
data JailInfo
JailInfo :: String -> JailInfo
data Poudriere
Poudriere :: String -> String -> String -> Bool -> FilePath -> String -> Maybe PoudriereZFS -> Poudriere
[_resolvConf] :: Poudriere -> String
[_freebsdHost] :: Poudriere -> String
[_baseFs] :: Poudriere -> String
[_usePortLint] :: Poudriere -> Bool
[_distFilesCache] :: Poudriere -> FilePath
[_svnHost] :: Poudriere -> String
[_zfs] :: Poudriere -> Maybe PoudriereZFS
defaultConfig :: Poudriere
data PoudriereZFS
PoudriereZFS :: ZFS -> ZFSProperties -> PoudriereZFS
data Jail
Jail :: String -> FBSDVersion -> PoudriereArch -> Jail
data PoudriereArch
I386 :: PoudriereArch
AMD64 :: PoudriereArch
fromArchitecture :: Architecture -> PoudriereArch
yesNoProp :: Bool -> String
type ConfigLine = String
type ConfigFile = [ConfigLine]
class ToShellConfigLines a where toLines c = map (\ (k, v) -> intercalate "=" [k, v]) (toAssoc c)
toAssoc :: ToShellConfigLines a => a -> [(String, String)]
toLines :: ToShellConfigLines a => a -> [ConfigLine]
confFile :: FilePath
instance GHC.Classes.Eq Propellor.Property.FreeBSD.Poudriere.PoudriereArch
instance GHC.Show.Show Propellor.Property.FreeBSD.Poudriere.PoudriereConfigured
instance GHC.Base.Monoid Propellor.Property.FreeBSD.Poudriere.PoudriereConfigured
instance Propellor.Types.Info.IsInfo Propellor.Property.FreeBSD.Poudriere.PoudriereConfigured
instance Propellor.Types.ConfigurableValue.ConfigurableValue Propellor.Property.FreeBSD.Poudriere.PoudriereArch
instance Propellor.Property.FreeBSD.Poudriere.ToShellConfigLines Propellor.Property.FreeBSD.Poudriere.Poudriere
instance Propellor.Property.FreeBSD.Poudriere.ToShellConfigLines Propellor.Property.FreeBSD.Poudriere.PoudriereZFS

-- | FreeBSD Properties
--   
--   This module is designed to be imported unqualified.
module Propellor.Property.FreeBSD

module Propellor.Property.Chroot

-- | Defines a Chroot at the given location, built with debootstrap.
--   
--   Properties can be added to configure the Chroot. At a minimum, add a
--   property such as osDebian to specify the operating system to
--   bootstrap.
--   
--   
--   debootstrapped Debootstrap.BuildD "/srv/chroot/ghc-dev" $ props
--   & osDebian Unstable X86_64
--   & Apt.installed ["ghc", "haskell-platform"]
--   & ...
--   
debootstrapped :: DebootstrapConfig -> FilePath -> Props metatypes -> Chroot

-- | Defines a Chroot at the given location, bootstrapped with the
--   specified ChrootBootstrapper.
bootstrapped :: ChrootBootstrapper b => b -> FilePath -> Props metatypes -> Chroot

-- | Ensures that the chroot exists and is provisioned according to its
--   properties.
--   
--   Reverting this property removes the chroot. Anything mounted inside it
--   is first unmounted. Note that it does not ensure that any processes
--   that might be running inside the chroot are stopped.
provisioned :: Chroot -> RevertableProperty (HasInfo + Linux) Linux

-- | Generates a Chroot that has all the properties of a Host.
--   
--   Note that it's possible to create loops using this, where a host
--   contains a Chroot containing itself etc. Such loops will be detected
--   at runtime.
hostChroot :: ChrootBootstrapper bootstrapper => Host -> bootstrapper -> FilePath -> Chroot

-- | Specification of a chroot. Normally you'll use debootstrapped
--   or bootstrapped or hostChroot to construct a Chroot
--   value.
data Chroot
[Chroot] :: ChrootBootstrapper b => FilePath -> b -> InfoPropagator -> Host -> Chroot

-- | Class of things that can do initial bootstrapping of an operating
--   System in a chroot.
class ChrootBootstrapper b

-- | Do initial bootstrapping of an operating system in a chroot. If the
--   operating System is not supported, return Left error message.
buildchroot :: ChrootBootstrapper b => b -> Maybe System -> FilePath -> Either String (Property Linux)

-- | Use this to bootstrap a chroot with debootstrap.
data Debootstrapped
Debootstrapped :: DebootstrapConfig -> Debootstrapped

-- | Use this to bootstrap a chroot by extracting a tarball.
--   
--   The tarball is expected to contain a root directory (no top-level
--   directory, also known as a "tarbomb"). It may be optionally compressed
--   with any format tar knows how to detect automatically.
data ChrootTarball
ChrootTarball :: FilePath -> ChrootTarball

-- | Check if propellor is currently running within a chroot.
--   
--   This allows properties to check and avoid performing actions that
--   should not be done in a chroot.
inChroot :: Propellor Bool

-- | Runs an action with the true localdir exposed, not the one
--   bind-mounted into a chroot. The action is passed the path containing
--   the contents of the localdir outside the chroot.
--   
--   In a chroot, this is accomplished by temporily bind mounting the
--   localdir to a temp directory, to preserve access to the original bind
--   mount. Then we unmount the localdir to expose the true localdir.
--   Finally, to cleanup, the temp directory is bind mounted back to the
--   localdir.
exposeTrueLocaldir :: (FilePath -> Propellor a) -> Propellor a
provisioned' :: Chroot -> Bool -> RevertableProperty (HasInfo + Linux) Linux
propagateChrootInfo :: InfoPropagator

-- | Propellor is run inside the chroot to provision it.
propellChroot :: Chroot -> ([String] -> IO (CreateProcess, IO ())) -> Bool -> Property UnixLike
chain :: [Host] -> CmdLine -> IO ()
chrootSystem :: Chroot -> Maybe System
instance GHC.Show.Show Propellor.Property.Chroot.InChroot
instance Propellor.Container.IsContainer Propellor.Property.Chroot.Chroot
instance GHC.Show.Show Propellor.Property.Chroot.Chroot
instance Propellor.Property.Chroot.ChrootBootstrapper Propellor.Property.Chroot.ChrootTarball
instance Propellor.Property.Chroot.ChrootBootstrapper Propellor.Property.Chroot.Debootstrapped

-- | This module contains properties that configure how Propellor
--   bootstraps to run itself on a Host.
module Propellor.Property.Bootstrap

-- | Different ways that Propellor's dependencies can be installed, and
--   propellor can be built. The default is `Robustly Cabal`
--   
--   `Robustly Cabal` and `Robustly Stack` use the OS's native packages as
--   much as possible to install Cabal, Stack, and propellor's build
--   dependencies. When necessary, dependencies are built from source using
--   Cabal or Stack rather than using the OS's native packages.
--   
--   OSOnly uses the OS's native packages of Cabal and all of
--   propellor's build dependencies. It may not work on all systems.
data Bootstrapper
Robustly :: Builder -> Bootstrapper
OSOnly :: Bootstrapper
data Builder
Cabal :: Builder
Stack :: Builder

-- | This property can be used to configure the Bootstrapper that is
--   used to bootstrap propellor on a Host. For example, if you want to use
--   stack:
--   
--   
--   host "example.com" $ props
--   	& bootstrapWith (Robustly Stack)
--   
--   
--   When bootstrappedFrom is used in a Chroot or other
--   Container, this property can also be added to the chroot to
--   configure it.
bootstrapWith :: Bootstrapper -> Property (HasInfo + UnixLike)

-- | Where a propellor repository should be bootstrapped from.
data RepoSource
GitRepoUrl :: String -> RepoSource

-- | When used in a chroot, this copies the git repository from outside the
--   chroot, including its configuration.
GitRepoOutsideChroot :: RepoSource

-- | Bootstraps a propellor installation into
--   usrlocalpropellor
--   
--   Normally, propellor is bootstrapped by eg, using propellor --spin, and
--   so this property is not generally needed.
--   
--   This property only does anything when used inside a Chroot or other
--   Container. This is particularly useful inside a chroot used to build a
--   disk image, to make the disk image have propellor installed.
--   
--   The git repository is cloned (or pulled to update if it already
--   exists).
--   
--   All build dependencies are installed, using distribution packages or
--   falling back to using cabal or stack.
bootstrappedFrom :: RepoSource -> Property Linux

-- | Clones the propellor repository into usrlocalpropellor
--   
--   If the propellor repo has already been cloned, pulls to get it
--   up-to-date.
clonedFrom :: RepoSource -> Property Linux

module Propellor.Property.Grub

-- | Eg, "hd0,0" or "xen/xvda1"
type GrubDevice = String

-- | Eg, "/dev/sda"
type OSDevice = String

-- | Platforms that grub can boot.
data GrubTarget
PC :: GrubTarget
EFI64 :: GrubTarget
EFI32 :: GrubTarget
Coreboot :: GrubTarget
Xen :: GrubTarget

-- | Installs the grub package. This does not make grub be used as the
--   bootloader.
--   
--   This includes running update-grub, unless it's run in a chroot.
installed :: GrubTarget -> Property (HasInfo + DebianLike)

-- | Run update-grub, to generate the grub boot menu. It will be
--   automatically updated when kernel packages are installed.
mkConfig :: Property DebianLike

-- | Installs grub; does not run update-grub.
installed' :: GrubTarget -> Property (HasInfo + DebianLike)

-- | Sets a simple confguration value, using grub-mkconfig to update the
--   grub boot menu accordingly. On Debian, these are written to
--   /etc/default/grub
--   
--   Example:
--   
--   
--   & Grub.configured "GRUB_TIMEOUT" "10"
--   & Grub.configured "GRUB_TERMINAL_INPUT" "console serial"
--   
configured :: String -> String -> Property DebianLike

-- | Adds a word to the default linux command line. Any other words in the
--   command line will be left unchanged.
--   
--   Example:
--   
--   
--   & Grub.cmdline_Linux_default "i915.enable_psr=1"
--   ! Grub.cmdline_Linux_default "quiet"
--   
cmdline_Linux_default :: String -> RevertableProperty DebianLike DebianLike

-- | Installs grub onto a device's boot loader, so the system can boot from
--   that device.
--   
--   You may want to install grub to multiple devices; eg for a system that
--   uses software RAID.
--   
--   Note that this property does not check if grub is already installed on
--   the device; it always does the work to reinstall it. It's a good idea
--   to arrange for this property to only run once, by eg making it be run
--   onChange after OS.cleanInstallOnce.
boots :: OSDevice -> Property Linux

-- | This is a version of boots that makes grub boot the system
--   mounted at a particular directory. The OSDevice should be the
--   underlying disk device that grub will be installed to (generally a
--   whole disk, not a partition).
bootsMounted :: FilePath -> OSDevice -> GrubTarget -> Property Linux
type TimeoutSecs = Int

-- | Use PV-grub chaining to boot
--   
--   Useful when the VPS's pv-grub is too old to boot a modern kernel
--   image.
--   
--   http://notes.pault.ag/linode-pv-grub-chainning/
--   
--   The rootdev should be in the form "hd0", while the bootdev is in the
--   form "xen/xvda".
chainPVGrub :: GrubDevice -> GrubDevice -> TimeoutSecs -> Property (HasInfo + DebianLike)

-- | Disk image generation.
--   
--   This module is designed to be imported unqualified.
module Propellor.Property.DiskImage

-- | Type class of disk image formats.
class DiskImage d

-- | Get the location where the raw disk image should be stored.
rawDiskImage :: DiskImage d => d -> RawDiskImage

-- | Describe the disk image (for display to the user)
describeDiskImage :: DiskImage d => d -> String

-- | Convert the raw disk image file in the rawDiskImage location
--   into the desired disk image format. For best efficiency, the raw disk
--   imasge file should be left unchanged on disk.
buildDiskImage :: DiskImage d => d -> RevertableProperty DebianLike Linux

-- | A raw disk image, that can be written directly out to a disk.
newtype RawDiskImage
RawDiskImage :: FilePath -> RawDiskImage

-- | A virtualbox .vmdk file, which contains a pointer to the raw disk
--   image. This can be built very quickly.
newtype VirtualBoxPointer
VirtualBoxPointer :: FilePath -> VirtualBoxPointer

-- | Creates a bootable disk image.
--   
--   First the specified Chroot is set up, and its properties are
--   satisfied.
--   
--   Then, the disk image is set up, and the chroot is copied into the
--   appropriate partition(s) of it.
--   
--   The partitions default to being sized just large enough to fit the
--   files from the chroot. You can use addFreeSpace to make them a
--   bit larger than that, or setSize to use a fixed size.
--   
--   Note that the disk image file is reused if it already exists, to avoid
--   expensive IO to generate a new one. And, it's updated in-place, so its
--   contents are undefined during the build process.
--   
--   Note that the noServices property is automatically added to the
--   chroot while the disk image is being built, which should prevent any
--   daemons that are included from being started on the system that is
--   building the disk image.
--   
--   Example use:
--   
--   
--   import Propellor.Property.DiskImage
--   import Propellor.Property.Chroot
--   
--   foo = host "foo.example.com" $ props
--   	& imageBuilt (RawDiskImage "/srv/diskimages/disk.img") mychroot
--   	MSDOS
--   	[ partition EXT2 `mountedAt` "/boot"
--   		`setFlag` BootFlag
--   	, partition EXT4 `mountedAt` "/"
--   		`addFreeSpace` MegaBytes 100
--   		`mountOpt` errorReadonly
--   	, swapPartition (MegaBytes 256)
--   	]
--    where
--   mychroot d = debootstrapped mempty d $ props
--   	& osDebian Unstable X86_64
--   	& Apt.installed ["linux-image-amd64"]
--   	& Grub.installed PC
--   	& User.hasPassword (User "root")
--   	& User.accountFor (User "demo")
--   		& User.hasPassword (User "demo")
--   	& User.hasDesktopGroups (User "demo")
--   		& ...
--   
imageBuilt :: DiskImage d => d -> (FilePath -> Chroot) -> TableType -> [PartSpec ()] -> RevertableProperty (HasInfo + DebianLike) Linux

-- | Like imageBuilt, 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 d => d -> (FilePath -> Chroot) -> TableType -> [PartSpec ()] -> RevertableProperty (HasInfo + DebianLike) Linux

-- | Create a bootable disk image for a Host.
--   
--   This works just like imageBuilt, but partition table is
--   determined by looking at the Host's hasPartitionTableType,
--   hasPartition, and adjustPartition properties.
--   
--   For example:
--   
--   
--   foo :: Host
--   foo = host "foo.example.com" $ props
--   & imageBuiltFor bar
--   	(RawDiskImage "/srv/diskimages/bar-disk.img")
--   	(Debootstrapped mempty)
--   
--   bar :: Host
--   bar = host "bar.example.com" $ props
--   & hasPartiton
--   	( partition EXT2
--   	`mountedAt` "/boot"
--   	`partLocation` Beginning
--   	`addFreeSpace` MegaBytes 150
--   	)
--   & hasPartiton
--   	( partition EXT4
--   	`mountedAt` "/"
--   	`addFreeSpace` MegaBytes 500
--   	)
--   & osDebian Unstable X86_64
--   & Apt.installed ["linux-image-amd64"]
--   & Grub.installed PC
--   & hasPassword (User "root")
--   
imageBuiltFor :: (DiskImage d, ChrootBootstrapper bootstrapper) => Host -> d -> bootstrapper -> RevertableProperty (HasInfo + DebianLike) Linux

-- | Like imageBuiltFor, but the chroot is deleted and rebuilt from
--   scratch each time.
imageRebuiltFor :: (DiskImage d, ChrootBootstrapper bootstrapper) => Host -> d -> bootstrapper -> RevertableProperty (HasInfo + DebianLike) Linux

-- | Builds a disk image from the contents of a chroot.
imageBuiltFrom :: DiskImage d => d -> FilePath -> TableType -> Finalization -> [PartSpec ()] -> RevertableProperty (HasInfo + DebianLike) Linux

-- | Ensures that a disk image file of the specified size exists.
--   
--   If the file doesn't exist, or is too small, creates a new one, full of
--   0's.
--   
--   If the file is too large, truncates it down to the specified size.
imageExists :: RawDiskImage -> ByteSize -> Property Linux

-- | Platforms that grub can boot.
data GrubTarget
PC :: GrubTarget
EFI64 :: GrubTarget
EFI32 :: GrubTarget
Coreboot :: GrubTarget
Xen :: GrubTarget
instance Propellor.Property.DiskImage.DiskImage Propellor.Property.DiskImage.RawDiskImage
instance Propellor.Property.DiskImage.DiskImage Propellor.Property.DiskImage.VirtualBoxPointer

-- | Properties for use on https://www.exoscale.ch/
module Propellor.Property.HostingProvider.Exoscale

-- | 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

module Propellor.Property.HostingProvider.Linode

-- | 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)

-- | 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 :: TimeoutSecs -> Property (HasInfo + DebianLike)

-- | Linode disables mlocate's cron job's execute permissions, presumably
--   to avoid disk IO. This ensures it's executable.
mlocateEnabled :: Property DebianLike

module Propellor.Property.Hostname

-- | Ensures that the hostname is set using best practices, to whatever
--   name the Host has.
--   
--   Configures both /etc/hostname and the current hostname.
--   (However, when used inside a chroot, avoids setting the current
--   hostname as that would impact the system outside the chroot.)
--   
--   Configures /etc/mailname with the domain part of the hostname.
--   
--   /etc/hosts is also configured, with an entry for 127.0.1.1,
--   which is standard at least on Debian to set the FDQN.
--   
--   Also, the /etc/hosts 127.0.0.1 line is set to localhost.
--   Putting any other hostnames there is not best practices and can lead
--   to annoying messages from eg, apache.
sane :: Property UnixLike
sane' :: ExtractDomain -> Property UnixLike
setTo :: HostName -> Property UnixLike
setTo' :: ExtractDomain -> HostName -> Property UnixLike

-- | Makes /etc/resolv.conf contain search and domain lines for the
--   domain that the hostname is in.
searchDomain :: Property UnixLike
searchDomain' :: ExtractDomain -> Property UnixLike

-- | Function to extract the domain name from a HostName.
type ExtractDomain = HostName -> String

-- | hostname of foo.example.com has a domain of example.com. But, when the
--   hostname is example.com, the domain is example.com too.
--   
--   This doesn't work for eg, foo.co.uk, or when foo.sci.uni.edu is in a
--   sci.uni.edu subdomain. If you are in such a network, provide your own
--   ExtractDomain function to the properties above.
extractDomain :: ExtractDomain

module Propellor.Property.HostingProvider.CloudAtCost
decruft :: Property DebianLike

-- | Build and maintain schroots for use with sbuild.
--   
--   For convenience we set up several enhancements, such as ccache and
--   eatmydata. This means we have to make several assumptions:
--   
--   
--   
- you want to build for a Debian release strictly newer than
--   squeeze, or for a Buntish release newer than or equal to trusty
--   
- if you want to build for Debian stretch or newer, you have sbuild
--   0.70.0 or newer
--   
--   
--   The latter is due to the migration from GnuPG v1 to GnuPG v2.1 in
--   Debian stretch, which older sbuild can't handle.
--   
--   Suggested usage in config.hs:
--   
--   
--   mybox = host "mybox.example.com" $ props
--   	& osDebian (Stable "stretch") X86_64
--   	& Apt.useLocalCacher
--   	& sidSchrootBuilt
--   	& Sbuild.usableBy (User "spwhitton")
--   	& Schroot.overlaysInTmpfs
--     where
--   	sidSchrootBuilt = Sbuild.built Sbuild.UseCcache $ props
--   		& osDebian Unstable X86_32
--   		& Sbuild.update `period` Weekly (Just 1)
--   		& Sbuild.useHostProxy mybox
--   
--   
--   If you are using sbuild older than 0.70.0, you also need:
--   
--   
--   & Sbuild.keypairGenerated
--   
--   
--   To take advantage of the piuparts and autopkgtest support, add to your
--   ~/.sbuildrc (assumes sbuild 0.71.0 or newer):
--   
--   
--   $piuparts_opts = [
--       '--no-eatmydata',
--       '--schroot',
--       '%r-%a-sbuild',
--       '--fail-if-inadequate',
--       ];
--   
--   $autopkgtest_root_args = "";
--   $autopkgtest_opts = ["--", "schroot", "%r-%a-sbuild"];
--   
--   
--   On Debian jessie hosts, you should ensure that sbuild and autopkgtest
--   come from the same suite. This is because the autopkgtest binary
--   changed its name between jessie and stretch. If you have not installed
--   backports of sbuild or autopkgtest, you don't need to do anything. But
--   if you have installed either package from jessie-backports (with
--   Propellor or otherwise), you should install the other from
--   jessie-backports, too.
module Propellor.Property.Sbuild

-- | Whether an sbuild schroot should use ccache during builds
--   
--   ccache is generally useful but it breaks building some packages. This
--   data types allows you to toggle it on and off for particular schroots.
data UseCcache
UseCcache :: UseCcache
NoCcache :: UseCcache

-- | Build and configure a schroot for use with sbuild
--   
--   The second parameter should specify, at a minimum, the operating
--   system for the schroot. This is usually done using a property like
--   osDebian
built :: UseCcache -> Props metatypes -> RevertableProperty (HasInfo + DebianLike) Linux

-- | Ensure that an sbuild schroot's packages and apt indexes are updated
--   
--   This replaces use of sbuild-update(1).
update :: Property DebianLike

-- | Ensure that an sbuild schroot uses the host's Apt proxy.
--   
--   This property is standardly used when the host has
--   useLocalCacher.
useHostProxy :: Host -> Property DebianLike

-- | Generate the apt keys needed by sbuild
--   
--   You only need this if you are using sbuild older than 0.70.0.
keypairGenerated :: Property DebianLike

-- | Generate the apt keys needed by sbuild using a low-quality source of
--   randomness
--   
--   Note that any running rngd will be killed; if you are using rngd, you
--   should arrange for it to be restarted after this property has been
--   ensured. E.g.
--   
--   
--   & Sbuild.keypairInsecurelyGenerated
--   	`onChange` Systemd.started "my-rngd-service"
--   
--   
--   Useful on throwaway build VMs.
--   
--   You only need this if you are using sbuild older than 0.70.0.
keypairInsecurelyGenerated :: Property DebianLike

-- | Add an user to the sbuild group in order to use sbuild
usableBy :: User -> Property DebianLike

-- | Maintain recommended ~/.sbuildrc for a user, and adds them to the
--   sbuild group
--   
--   You probably want a custom ~/.sbuildrc on your workstation, but this
--   property is handy for quickly setting up build boxes.
--   
--   On Debian jessie hosts, you should ensure that sbuild and autopkgtest
--   come from the same suite. This is because the autopkgtest binary
--   changed its name between jessie and stretch. If you have not installed
--   backports of sbuild or autopkgtest, you don't need to do anything. But
--   if you have installed either package from jessie-backports (with
--   Propellor or otherwise), you should install the other from
--   jessie-backports, too.
userConfig :: User -> Property DebianLike

module Propellor.Property.Systemd
type ServiceName = String

-- | Starts a systemd service.
--   
--   Note that this does not configure systemd to start the service on
--   boot, it only ensures that the service is currently running.
started :: ServiceName -> Property Linux

-- | Stops a systemd service.
stopped :: ServiceName -> Property Linux

-- | Enables a systemd service.
--   
--   This does not ensure the service is started, it only configures
--   systemd to start it on boot.
enabled :: ServiceName -> Property Linux

-- | Disables a systemd service.
disabled :: ServiceName -> Property Linux

-- | Masks a systemd service.
masked :: ServiceName -> RevertableProperty Linux Linux

-- | Ensures that a service is both enabled and started
running :: ServiceName -> Property Linux

-- | Restarts a systemd service.
restarted :: ServiceName -> Property Linux

-- | The systemd-networkd service.
networkd :: ServiceName

-- | The systemd-journald service.
journald :: ServiceName

-- | The systemd-logind service.
logind :: ServiceName
installed :: Property DebianLike
type Option = String

-- | Ensures that an option is configured in one of systemd's config files.
--   Does not ensure that the relevant daemon notices the change
--   immediately.
--   
--   This assumes that there is only one [Header] per file, which is
--   currently the case for files like journald.conf and system.conf. And
--   it assumes the file already exists with the right [Header], so new
--   lines can just be appended to the end.
configured :: FilePath -> Option -> String -> Property Linux

-- | Causes systemd to reload its configuration files.
daemonReloaded :: Property Linux

-- | Enables persistent storage of the journal.
persistentJournal :: Property DebianLike

-- | Configures journald, restarting it so the changes take effect.
journaldConfigured :: Option -> String -> Property Linux

-- | Configures logind, restarting it so the changes take effect.
logindConfigured :: Option -> String -> Property Linux

-- | Configures whether leftover processes started from the user's login
--   session are killed after the user logs out.
--   
--   The default configuration varies depending on the version of systemd.
--   
--   Revert the property to ensure that screen sessions etc keep running:
--   
--   
--   ! killUserProcesses
--   
killUserProcesses :: RevertableProperty Linux Linux

-- | Ensures machined and machinectl are installed
machined :: Property Linux
type MachineName = String
data Container

-- | Defines a container with a given machine name, and how to create its
--   chroot if not already present.
--   
--   Properties can be added to configure the Container. At a minimum, add
--   a property such as osDebian to specify the operating system to
--   bootstrap.
--   
--   
--   container "webserver" $ \d -> Chroot.debootstrapped mempty d $ props
--   & osDebian Unstable X86_64
--      & Apt.installedRunning "apache2"
--      & ...
--   
container :: MachineName -> (FilePath -> Chroot) -> Container

-- | Defines a container with a given machine name, with the chroot created
--   using debootstrap.
--   
--   Properties can be added to configure the Container. At a minimum, add
--   a property such as osDebian to specify the operating system to
--   bootstrap.
--   
--   
--   debContainer "webserver" $ props
--   & osDebian Unstable X86_64
--      & Apt.installedRunning "apache2"
--      & ...
--   
debContainer :: MachineName -> Props metatypes -> Container

-- | Runs a container using systemd-nspawn.
--   
--   A systemd unit is set up for the container, so it will automatically
--   be started on boot.
--   
--   Systemd is automatically installed inside the container, and will
--   communicate with the host's systemd. This allows systemctl to be used
--   to examine the status of services running inside the container.
--   
--   When the host system has persistentJournal enabled, journactl can be
--   used to examine logs forwarded from the container.
--   
--   Reverting this property stops the container, removes the systemd unit,
--   and deletes the chroot and all its contents.
nspawned :: Container -> RevertableProperty (HasInfo + Linux) Linux

-- | This configures how systemd-nspawn(1) starts the container, by
--   specifying a parameter, such as "--private-network", or
--   "--link-journal=guest"
--   
--   When there is no leading dash, "--" is prepended to the parameter.
--   
--   Reverting the property will remove a parameter, if it's present.
containerCfg :: String -> RevertableProperty (HasInfo + Linux) (HasInfo + Linux)

-- | Bind mounts /etc/resolv.conf from the host into the container.
--   
--   This property is enabled by default. Revert it to disable it.
resolvConfed :: RevertableProperty (HasInfo + Linux) (HasInfo + Linux)

-- | Link the container's journal to the host's if possible. (Only works if
--   the host has persistent journal enabled.)
--   
--   This property is enabled by default. Revert it to disable it.
linkJournal :: RevertableProperty (HasInfo + Linux) (HasInfo + Linux)

-- | Disconnect networking of the container from the host.
privateNetwork :: RevertableProperty (HasInfo + Linux) (HasInfo + Linux)
data Proto
TCP :: Proto
UDP :: Proto
class Publishable a

-- | Publish a port from the container to the host.
--   
--   This feature was first added in systemd version 220.
--   
--   This property is only needed (and will only work) if the container is
--   configured to use private networking. Also, networkd should be enabled
--   both inside the container, and on the host. For example:
--   
--   
--   foo :: Host
--   foo = host "foo.example.com"
--   & Systemd.nspawned webserver
--   		`requires` Systemd.running Systemd.networkd
--   
--   webserver :: Systemd.container
--   webserver = Systemd.container "webserver" (Chroot.debootstrapped mempty)
--   & os (System (Debian Testing) X86_64)
--   & Systemd.privateNetwork
--   & Systemd.running Systemd.networkd
--   & Systemd.publish (Port 80 ->- Port 8080)
--   & Apt.installedRunning "apache2"
--   
publish :: Publishable p => p -> RevertableProperty (HasInfo + Linux) (HasInfo + Linux)
class Bindable a

-- | Bind mount a file or directory from the host into the container.
bind :: Bindable p => p -> RevertableProperty (HasInfo + Linux) (HasInfo + Linux)

-- | Read-only mind mount.
bindRo :: Bindable p => p -> RevertableProperty (HasInfo + Linux) (HasInfo + Linux)
instance GHC.Show.Show Propellor.Property.Systemd.Container
instance Propellor.Container.IsContainer Propellor.Property.Systemd.Container
instance Propellor.Property.Systemd.Publishable Propellor.Types.OS.Port
instance Propellor.Property.Systemd.Publishable (Propellor.Types.Container.Bound Propellor.Types.OS.Port)
instance Propellor.Property.Systemd.Publishable (Propellor.Property.Systemd.Proto, Propellor.Types.Container.Bound Propellor.Types.OS.Port)
instance Propellor.Property.Systemd.Bindable GHC.IO.FilePath
instance Propellor.Property.Systemd.Bindable (Propellor.Types.Container.Bound GHC.IO.FilePath)

module Propellor.Property.Journald

-- | Configures journald, restarting it so the changes take effect.
configured :: Option -> String -> Property Linux
type DataSize = String
configuredSize :: Option -> DataSize -> Property Linux
systemMaxUse :: DataSize -> Property Linux
runtimeMaxUse :: DataSize -> Property Linux
systemKeepFree :: DataSize -> Property Linux
runtimeKeepFree :: DataSize -> Property Linux
systemMaxFileSize :: DataSize -> Property Linux
runtimeMaxFileSize :: DataSize -> Property Linux
systemdSizeUnits :: Integer -> String

module Propellor.Property.Laptop

-- | Makes powertop auto-tune the system for optimal power consumption on
--   boot.
powertopAutoTuneOnBoot :: RevertableProperty DebianLike DebianLike

module Propellor.Property.SiteSpecific.GitAnnexBuilder
builduser :: UserName
homedir :: FilePath
gitbuilderdir :: FilePath
builddir :: FilePath
type TimeOut = String
type ArchString = String
autobuilder :: ArchString -> Times -> TimeOut -> Property (HasInfo + DebianLike)
tree :: ArchString -> Flavor -> Property DebianLike
buildDepsApt :: Property DebianLike
buildDepsNoHaskellLibs :: Property DebianLike
haskellPkgsInstalled :: String -> Property DebianLike
cabalDeps :: Property UnixLike
autoBuilderContainer :: (DebianSuite -> Architecture -> Flavor -> Property (HasInfo + Debian)) -> DebianSuite -> Architecture -> Flavor -> Times -> TimeOut -> Container
type Flavor = Maybe String
standardAutoBuilder :: DebianSuite -> Architecture -> Flavor -> Property (HasInfo + Debian)
stackAutoBuilder :: DebianSuite -> Architecture -> Flavor -> Property (HasInfo + Debian)
stackInstalled :: Property Linux
armAutoBuilder :: DebianSuite -> Architecture -> Flavor -> Property (HasInfo + Debian)
androidAutoBuilderContainer :: Times -> TimeOut -> Container
androidAutoBuilderContainer' :: MachineName -> Property DebianLike -> FilePath -> Times -> TimeOut -> Container

-- | Specific configuration for Joey Hess's sites. Probably not useful to
--   others except as an example.
module Propellor.Property.SiteSpecific.JoeySites
scrollBox :: Property (HasInfo + DebianLike)
oldUseNetServer :: [Host] -> Property (HasInfo + DebianLike)
oldUseNetShellBox :: Property DebianLike
oldUseNetInstalled :: Package -> Property DebianLike
kgbServer :: Property (HasInfo + Debian)
gitServer :: [Host] -> Property (HasInfo + DebianLike)
type AnnexUUID = String

-- | A website, with files coming from a git-annex repository.
annexWebSite :: RepoUrl -> HostName -> AnnexUUID -> [(String, RepoUrl)] -> Property (HasInfo + DebianLike)
letos :: AgreeTOS
apacheSite :: HostName -> ConfigFile -> RevertableProperty DebianLike DebianLike
apachecfg :: HostName -> ConfigFile -> ConfigFile
gitAnnexDistributor :: Property (HasInfo + DebianLike)
downloads :: [Host] -> Property (HasInfo + DebianLike)
tmp :: Property (HasInfo + DebianLike)
pumpRss :: Property DebianLike
ircBouncer :: Property (HasInfo + DebianLike)
kiteShellBox :: Property DebianLike
githubBackup :: Property (HasInfo + DebianLike)
githubKeys :: Property (HasInfo + UnixLike)
rsyncNetBackup :: [Host] -> Property DebianLike
backupsBackedupFrom :: [Host] -> HostName -> FilePath -> Property DebianLike
podcatcher :: Property DebianLike
kiteMailServer :: Property (HasInfo + DebianLike)
dkimMilter :: Property (HasInfo + DebianLike)
dkimInstalled :: Property (HasInfo + DebianLike)
domainKey :: (BindDomain, Record)
postfixSaslPasswordClient :: Property (HasInfo + DebianLike)
hasPostfixCert :: Context -> Property (HasInfo + UnixLike)
legacyWebSites :: Property (HasInfo + DebianLike)
userDirHtml :: Property DebianLike
alarmClock :: String -> User -> String -> Property Linux
homePowerMonitor :: IsContext c => User -> [Host] -> c -> (SshKeyType, PubKeyText) -> Property (HasInfo + DebianLike)
homeRouter :: Property (HasInfo + DebianLike)

-- | Enable IP masqerading, on whatever other interfaces come up than the
--   provided intif.
ipmasq :: String -> Property DebianLike
laptopSoftware :: Property DebianLike
baseSoftware :: Property DebianLike
devSoftware :: Property DebianLike
cubieTruckOneWire :: Property DebianLike

module Propellor.Property.Uboot

-- | Name of a board.
type BoardName = String

-- | Installs u-boot for Allwinner/sunxi platforms.
--   
--   This includes writing it to the boot sector.
sunxi :: BoardName -> Property (HasInfo + DebianLike)

-- | Machine-specific properties.
--   
--   Many embedded computers have their own special configuration needed to
--   use them. Rather than needing to hunt down documentation about the
--   kernel, bootloader, etc for a given machine, if there's a property in
--   here for your machine, you can simply use it.
--   
--   Not all machine properties have been tested yet. If one flagged as
--   untested and you find it works, please let us know.
--   
--   You will need to configure the Host with the right
--   Architecture for the machine. These properties do test at
--   runtime that a supported Architecture was selected.
--   
--   Sometimes non-free firmware is needed to use a board. If the board
--   won't be functional at all without it, its property will include the
--   non-free firmware, but if the non-free firmware is only needed for
--   non-critical functionality, it won't be included.
--   
--   Example: Building a disk image for a Marvell SheevaPlug
--   
--   This defines a Host "sheeva" that is a Marvell SheevaPlug. A bootable
--   disk image for "sheeva" is built on another machine "darkstar", which
--   can be eg an Intel laptop running Debian.
--   
--   
--   import Propellor.Property.Machine
--   import Propellor.Property.DiskImage
--   
--   sheeva :: Host
--   sheeva = host "sheeva.example.com" $ props
--   	& osDebian Unstable ARMEL
--   	& marvell_SheevaPlug Marvell_SheevaPlug_SDCard
--   & hasPartition
--   	( partition EXT4
--   		`mountedAt` "/"
--   	`addFreeSpace` MegaBytes 2048
--   	)
--   
--   darkstar :: Host
--   darkstar = host "darkstar.example.com" $ props
--   & imageBuiltFor sheeva
--   	(RawDiskImage "/srv/sheeva-disk.img")
--   	(Debootstrapped mempty)
--   
module Propellor.Property.Machine
data Marvell_SheevaPlug_BootDevice
Marvell_SheevaPlug_SDCard :: Marvell_SheevaPlug_BootDevice
Marvell_SheevaPlug_ESATA :: Marvell_SheevaPlug_BootDevice

-- | Marvell SheevaPlug
--   
--   This includes a small EXT2 formatted /boot partition.
--   
--   Note that u-boot may need to be upgraded manually, and will need to be
--   configured to boot from the SD card or eSATA. See
--   https://www.cyrius.com/debian/kirkwood/sheevaplug/install/
marvell_SheevaPlug :: Marvell_SheevaPlug_BootDevice -> Property (HasInfo + DebianLike)

-- | Cubietech Cubietruck
--   
--   Wifi needs non-free firmware-brcm80211, which is not installed by this
--   property. Also, see https://bugs.debian.org/844056
cubietech_Cubietruck :: Property (HasInfo + DebianLike)

-- | Olimex A10-OLinuXino-LIME
olimex_A10_OLinuXino_LIME :: Property (HasInfo + DebianLike)

-- | Cubietech Cubieboard (untested)
cubietech_Cubieboard :: Property (HasInfo + DebianLike)

-- | Cubietech Cubieboard2 (untested)
cubietech_Cubieboard2 :: Property (HasInfo + DebianLike)

-- | LeMaker Banana Pi
lemaker_Banana_Pi :: Property (HasInfo + DebianLike)

-- | LeMaker Banana Pro (untested)
lemaker_Banana_Pro :: Property (HasInfo + DebianLike)

-- | Olimex A10s-Olinuxino Micro (untested)
olimex_A10s_OLinuXino_Micro :: Property (HasInfo + DebianLike)

-- | Olimex A20-OlinuXino-LIME (untested)
olimex_A20_OLinuXino_LIME :: Property (HasInfo + DebianLike)

-- | Olimex A20-OlinuXino-LIME2 (untested)
olimex_A20_OLinuXino_LIME2 :: Property (HasInfo + DebianLike)

-- | Olimex A20-Olinuxino Micro (untested)
olimex_A20_OLinuXino_Micro :: Property (HasInfo + DebianLike)

-- | Olimex A20-SOM-EVB (untested)
olimex_A20_SOM_EVB :: Property (HasInfo + DebianLike)

-- | LinkSprite pcDuino Nano (untested)
--   
--   Needs non-free firmware, see
--   https://wiki.debian.org/InstallingDebianOn/Allwinner
linkSprite_pcDuino3_Nano :: Property (HasInfo + DebianLike)

-- | Docker support for propellor
--   
--   The existance of a docker container is just another Property of a
--   system, which propellor can set up. See config.hs for an example.
module Propellor.Property.Docker
installed :: Property (DebianLike + ArchLinux)

-- | Configures docker with an authentication file, so that images can be
--   pushed to index.docker.io. Optional.
configured :: Property (HasInfo + DebianLike)

-- | Defines a Container with a given name, image, and properties. Add
--   properties to configure the Container.
--   
--   
--   container "web-server" (latestImage "debian") $ props
--      & publish "80:80"
--      & Apt.installed {"apache2"]
--      & ...
--   
container :: ContainerName -> Image -> Props metatypes -> Container

-- | Ensures that a docker container is set up and running.
--   
--   The container has its own Properties which are handled by running
--   propellor inside the container.
--   
--   When the container's Properties include DNS info, such as a CNAME,
--   that is propagated to the Info of the Host it's docked in.
--   
--   Reverting this property ensures that the container is stopped and
--   removed.
docked :: Container -> RevertableProperty (HasInfo + Linux) (HasInfo + Linux)

-- | Build the image from a directory containing a Dockerfile.
imageBuilt :: HasImage c => FilePath -> c -> Property Linux

-- | Pull the image from the standard Docker Hub registry.
imagePulled :: HasImage c => c -> Property Linux

-- | Configures the kernel to respect docker memory limits.
--   
--   This assumes the system boots using grub 2. And that you don't need
--   any other GRUB_CMDLINE_LINUX_DEFAULT settings.
--   
--   Only takes effect after reboot. (Not automated.)
memoryLimited :: Property DebianLike

-- | Causes *any* docker images that are not in use by running containers
--   to be deleted. And deletes any containers that propellor has set up
--   before that are not currently running. Does not delete any containers
--   that were not set up using propellor.
--   
--   Generally, should come after the properties for the desired
--   containers.
garbageCollected :: Property Linux

-- | Tweaks a container to work well with docker.
--   
--   Currently, this consists of making pam_loginuid lines optional in the
--   pam config, to work around
--   https://github.com/docker/docker/issues/5663 which affects
--   docker 1.2.0.
tweaked :: Property Linux

-- | A docker image, that can be used to run a container. The user has to
--   specify a name and can provide an optional tag. See Docker Image
--   Documention for more information.
data Image
Image :: String -> Maybe String -> Image
[repository] :: Image -> String
[tag] :: Image -> Maybe String

-- | Defines a Docker image without any tag. This is considered by Docker
--   as the latest image of the provided repository.
latestImage :: String -> Image

-- | A short descriptive name for a container. Should not contain
--   whitespace or other unusual characters, only [a-zA-Z0-9_-] are allowed
type ContainerName = String

-- | A docker container.
data Container
Container :: Image -> Host -> Container
class HasImage a
getImageName :: HasImage a => a -> Image

-- | Set custom dns server for container.
dns :: String -> Property (HasInfo + Linux)

-- | Set container host name.
hostname :: String -> Property (HasInfo + Linux)
class Publishable p

-- | Publish a container's port to the host
publish :: Publishable p => p -> Property (HasInfo + Linux)

-- | Expose a container's port without publishing it.
expose :: String -> Property (HasInfo + Linux)

-- | Username or UID for container.
user :: String -> Property (HasInfo + Linux)
class Mountable p

-- | Mount a volume
volume :: Mountable v => v -> Property (HasInfo + Linux)

-- | Mount a volume from the specified container into the current
--   container.
volumes_from :: ContainerName -> Property (HasInfo + Linux)

-- | Work dir inside the container.
workdir :: String -> Property (HasInfo + Linux)

-- | Memory limit for container. Format: numberunit, where
--   unit = b, k, m or g
--   
--   Note: Only takes effect when the host has the memoryLimited property
--   enabled.
memory :: String -> Property (HasInfo + Linux)

-- | CPU shares (relative weight).
--   
--   By default, all containers run at the same priority, but you can tell
--   the kernel to give more CPU time to a container using this property.
cpuShares :: Int -> Property (HasInfo + Linux)

-- | Link with another container on the same host.
link :: ContainerName -> ContainerAlias -> Property (HasInfo + Linux)

-- | Set environment variable with a tuple composed by the environment
--   variable name and its value.
environment :: (String, String) -> Property (HasInfo + Linux)

-- | A short alias for a linked container. Each container has its own alias
--   namespace.
type ContainerAlias = String

-- | This property is enabled by default for docker containers configured
--   by propellor; as well as keeping badly behaved containers running, it
--   ensures that containers get started back up after reboot or after
--   docker is upgraded.
restartAlways :: Property (HasInfo + Linux)

-- | Docker will restart the container if it exits nonzero. If a number is
--   provided, it will be restarted only up to that many times.
restartOnFailure :: Maybe Int -> Property (HasInfo + Linux)

-- | Makes docker not restart a container when it exits Note that this
--   includes not restarting it on boot!
restartNever :: Property (HasInfo + Linux)

-- | Called when propellor is running inside a docker container. The string
--   should be the container's ContainerId.
--   
--   This process is effectively init inside the container. It even needs
--   to wait on zombie processes!
--   
--   In the foreground, run an interactive bash (or sh) shell, so that the
--   user can interact with it when attached to the container.
--   
--   When the system reboots, docker restarts the container, and this is
--   run again. So, to make the necessary services get started on boot,
--   this needs to provision the container then. However, if the container
--   is already being provisioned by the calling propellor, it would be
--   redundant and problimatic to also provisoon it here, when not booting
--   up.
--   
--   The solution is a flag file. If the flag file exists, then the
--   container was already provisioned. So, it must be a reboot, and time
--   to provision again. If the flag file doesn't exist, don't provision
--   here.
init :: String -> IO ()
chain :: [Host] -> HostName -> String -> IO ()
instance GHC.Classes.Eq Propellor.Property.Docker.ContainerFilter
instance GHC.Classes.Eq Propellor.Property.Docker.ContainerIdent
instance GHC.Show.Show Propellor.Property.Docker.ContainerIdent
instance GHC.Read.Read Propellor.Property.Docker.ContainerIdent
instance GHC.Show.Show Propellor.Property.Docker.ContainerId
instance GHC.Read.Read Propellor.Property.Docker.ContainerId
instance GHC.Classes.Eq Propellor.Property.Docker.ContainerId
instance GHC.Show.Show Propellor.Property.Docker.Image
instance GHC.Read.Read Propellor.Property.Docker.Image
instance GHC.Classes.Eq Propellor.Property.Docker.Image
instance Propellor.Container.IsContainer Propellor.Property.Docker.Container
instance Propellor.Property.Docker.HasImage Propellor.Property.Docker.Image
instance Propellor.Property.Docker.HasImage Propellor.Property.Docker.Container
instance Propellor.Property.Docker.ImageIdentifier Propellor.Property.Docker.ImageID
instance Propellor.Property.Docker.ImageIdentifier Propellor.Property.Docker.Image
instance Propellor.Property.Docker.ImageIdentifier Propellor.Property.Docker.ImageUID
instance Propellor.Property.Docker.Publishable (Propellor.Types.Container.Bound Propellor.Types.OS.Port)
instance Propellor.Property.Docker.Publishable GHC.Base.String
instance Propellor.Property.Docker.Mountable (Propellor.Types.Container.Bound GHC.IO.FilePath)
instance Propellor.Property.Docker.Mountable GHC.Base.String

module Propellor.CmdLine

-- | Runs propellor on hosts, as controlled by command-line options.
defaultMain :: [Host] -> IO ()
processCmdLine :: IO CmdLine

-- | This module adds conductors to propellor. A conductor is a Host that
--   is responsible for running propellor on other hosts
--   
--   This eliminates the need to manually run propellor --spin to update
--   the conducted hosts, and can be used to orchestrate updates to hosts.
--   
--   The conductor needs to be able to ssh to the hosts it conducts, and
--   run propellor, as root. To this end, the knownHost property is
--   automatically added to the conductor, so it knows the host keys of the
--   relevant hosts. Also, each conducted host is configured to let its
--   conductor ssh in as root, by automatically adding the
--   authorizedKeysFrom property.
--   
--   It's left up to you to use userKeys to configure the ssh keys
--   for the root user on conductor hosts, and to use hostKeys to
--   configure the host keys for the conducted hosts.
--   
--   For example, if you have some webservers and a dnsserver, and want the
--   master host to conduct all of them:
--   
--   
--   import Propellor
--   import Propellor.Property.Conductor
--   import qualified Propellor.Property.Ssh as Ssh
--   import qualified Propellor.Property.Cron as Cron
--   
--   main = defaultMain (orchestrate hosts)
--   
--   hosts =
--   	[ master
--   , dnsserver
--   ] ++ webservers
--   
--   dnsserver = host "dns.example.com"
--   & Ssh.hostKeys hostContext [(SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB3BJ2GqZiTR2LEoDXyYFgh/BduWefjdKXAsAtzS9zeI")]
--   & ...
--   
--   webservers =
--      [ host "www1.example.com"
--   	& Ssh.hostKeys hostContext [(SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICfFntnesZcYz2B2T41ay45igfckXRSh5uVffkuCQkLv")]
--   	& ...
--   , ...
--   ]
--   
--   master = host "master.example.com"
--   & Ssh.userKeys (User "root") [(SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFWD0Hau5FDLeNrDHKilNMKm9c68R3WD+NJOp2jPWvJV")]
--   & conducts webservers
--   	`before` conducts dnsserver
--   & Cron.runPropellor
--   
--   
--   Notice that, in the above example, the the webservers are conducted
--   first. Only once the webservers have successfully been set up is the
--   dnsserver updated. This way, when adding a new web server, the dns
--   won't list it until it's ready.
--   
--   There can be multiple conductors, and conductors can conduct other
--   conductors if you need such a hierarchy. (Loops in the hierarchy, such
--   as a host conducting itself, are detected and automatically broken.)
--   
--   While it's allowed for a single host to be conducted by multiple
--   conductors, the results can be discordent. Since only one propellor
--   process can be run on a host at a time, one of the conductors will
--   fail to communicate with it.
--   
--   Note that a conductor can see all PrivData of the hosts it conducts.
module Propellor.Property.Conductor

-- | Pass this a list of all your hosts; it will finish setting up
--   orchestration as configured by the conducts properties you add
--   to hosts.
--   
--   
--   main = defaultMain $ orchestrate hosts
--   
orchestrate :: [Host] -> [Host]

-- | Class of things that can be conducted.
--   
--   There are instances for single hosts, and for lists of hosts. With a
--   list, each listed host will be conducted in turn. Failure to conduct
--   one host does not prevent conducting subsequent hosts in the list, but
--   will be propagated as an overall failure of the property.
class Conductable c
conducts :: Conductable c => c -> RevertableProperty (HasInfo + UnixLike) (HasInfo + UnixLike)
instance GHC.Show.Show Propellor.Property.Conductor.Orchestrated
instance GHC.Base.Monoid Propellor.Property.Conductor.Orchestrated
instance GHC.Base.Monoid Propellor.Property.Conductor.NotConductorFor
instance GHC.Base.Monoid Propellor.Property.Conductor.ConductorFor
instance Propellor.Property.Conductor.Conductable Propellor.Types.Core.Host
instance Propellor.Property.Conductor.Conductable [Propellor.Types.Core.Host]
instance GHC.Show.Show Propellor.Property.Conductor.Orchestra
instance GHC.Show.Show Propellor.Property.Conductor.ConductorFor
instance GHC.Show.Show Propellor.Property.Conductor.NotConductorFor
instance Propellor.Types.Info.IsInfo Propellor.Property.Conductor.ConductorFor
instance Propellor.Types.Info.IsInfo Propellor.Property.Conductor.NotConductorFor
instance Propellor.Types.Info.IsInfo Propellor.Property.Conductor.Orchestrated

-- | When propellor runs on a Host, it ensures that its Properties are
--   satisfied, taking action as necessary when a Property is not currently
--   satisfied.
--   
--   A simple propellor program example:
--   
--   
--   import Propellor
--   import qualified Propellor.Property.File as File
--   import qualified Propellor.Property.Apt as Apt
--   
--   main :: IO ()
--   main = defaultMain hosts
--   
--   hosts :: [Host]
--   hosts = [example]
--   
--   example :: Host
--   example = host "example.com" $ props
--       & Apt.installed ["mydaemon"]
--       & "/etc/mydaemon.conf" `File.containsLine` "secure=1"
--         `onChange` cmdProperty "service" ["mydaemon", "restart"]
--       ! Apt.installed ["unwantedpackage"]
--   
--   
--   See config.hs for a more complete example, and clone Propellor's git
--   repository for a deployable system using Propellor: git clone
--   git://git.joeyh.name/propellor
module Propellor

-- | Everything Propellor knows about a system: Its hostname, properties
--   and their collected info.
data Host
Host :: HostName -> [ChildProperty] -> Info -> Host
[hostName] :: Host -> HostName
[hostProperties] :: Host -> [ChildProperty]
[hostInfo] :: Host -> Info

-- | The core data type of Propellor, this represents a property that the
--   system should have, with a descrition, and an action to ensure it has
--   the property.
--   
--   There are different types of properties that target different OS's,
--   and so have different metatypes. For example: "Property DebianLike"
--   and "Property FreeBSD".
--   
--   Also, some properties have associated Info, which is indicated
--   in their type: "Property (HasInfo + DebianLike)"
--   
--   There are many associated type families, which are mostly used
--   internally, so you needn't worry about them.
data Property metatypes
Property :: metatypes -> Desc -> (Maybe (Propellor Result)) -> Info -> [ChildProperty] -> Property metatypes

-- | A property that can be reverted. The first Property is run normally
--   and the second is run when it's reverted.
--   
--   See Versioned for a way to use RevertableProperty to define
--   different versions of a host.
data RevertableProperty setupmetatypes undometatypes
RevertableProperty :: Property setupmetatypes -> Property undometatypes -> RevertableProperty setupmetatypes undometatypes
[setupRevertableProperty] :: RevertableProperty setupmetatypes undometatypes -> Property setupmetatypes
[undoRevertableProperty] :: RevertableProperty setupmetatypes undometatypes -> Property undometatypes

-- | Runs propellor on hosts, as controlled by command-line options.
defaultMain :: [Host] -> IO ()

-- | Defines a host and its properties.
--   
--   
--   host "example.com" $ props
--   	& someproperty
--   	! oldproperty
--   	& otherproperty
--   
host :: HostName -> Props metatypes -> Host

-- | Adds a property to a Props.
--   
--   Can add Properties and RevertableProperties
(&) :: (IsProp p, MetaTypes y ~ GetMetaTypes p, CheckCombinable x y ~ CanCombine) => Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
infixl 1 &

-- | Adds a property in reverted form.
(!) :: (CheckCombinable x z ~ CanCombine) => Props (MetaTypes x) -> RevertableProperty (MetaTypes y) (MetaTypes z) -> Props (MetaTypes (Combine x z))
infixl 1 !

-- | Indicates that the first property depends on the second, so before the
--   first is ensured, the second must be ensured.
--   
--   The combined property uses the description of the first property.
requires :: Combines x y => x -> y -> CombinedType x y

-- | Combines together two properties, resulting in one property that
--   ensures the first, and if the first succeeds, ensures the second.
--   
--   The combined property uses the description of the first property.
before :: Combines x y => x -> y -> CombinedType x y

-- | Whenever a change has to be made for a Property, causes a hook
--   Property to also be run, but not otherwise.
onChange :: (Combines x y) => x -> y -> CombinedType x y

-- | Changes the description of a property.
describe :: IsProp p => p -> Desc -> p

-- | Support for LVM logical volumes.
module Propellor.Property.Lvm

-- | Create or resize a logical volume, and make sure it is formatted. When
--   reverted, remove the logical volume.
--   
--   Example use:
--   
--   
--   import qualified Propellor.Property.Lvm as Lvm
--   import qualified Propellor.Property.Partition as Partition
--   Lvm.lvFormatted Lvm.YesReallyFormatLogicalVolume
--           (Lvm.LogicalVolume "test" (Lvm.VolumeGroup "vg0")) "16m"
--           Partition.EXT4
--   
--   
--   If size and filesystem match, nothing is done.
--   
--   Volume group must have been created already.
lvFormatted :: Eep -> LogicalVolume -> DataSize -> Fs -> RevertableProperty DebianLike UnixLike

-- | Make sure needed tools are installed.
installed :: RevertableProperty DebianLike DebianLike
data Eep
YesReallyFormatLogicalVolume :: Eep
newtype VolumeGroup
VolumeGroup :: String -> VolumeGroup
data LogicalVolume
LogicalVolume :: String -> VolumeGroup -> LogicalVolume

-- | Versioned properties and hosts.
--   
--   When importing and using this module, you will need to enable some
--   language extensions:
--   
--   
--   {-# LANGUAGE RankNTypes, FlexibleContexts, TypeFamilies #-}
--   
--   
--   This module takes advantage of RevertableProperty to let
--   propellor switch cleanly between versions. The way it works is all
--   revertable properties for other versions than the current version are
--   first reverted, and then propellor ensures the property for the
--   current version. This method should work for any combination of
--   revertable properties.
--   
--   For example:
--   
--   
--   demo :: Versioned Int (RevertableProperty DebianLike DebianLike)
--   demo ver =
--   	ver (   (== 1) --> Apache.modEnabled "foo"
--   	`requires` Apache.modEnabled "foosupport"
--       <|> (== 2) --> Apache.modEnabled "bar"
--   	    <|> (> 2)  --> Apache.modEnabled "baz"
--   	    )
--   
--   foo :: Host
--   foo = host "foo.example.com" $ props
--   	& demo `version` (2 :: Int)
--   
--   
--   Similarly, a whole Host can be versioned. For example:
--   
--   
--   bar :: Versioned Int Host
--   bar ver = host "bar.example.com" $ props
--   & osDebian Unstable X86_64
--   	& ver (   (== 1) --> Apache.modEnabled "foo"
--   	      <|> (== 2) --> Apache.modEnabled "bar"
--   	      )
--   	& ver ( (>= 2) --> Apt.unattendedUpgrades )
--   
--   
--   Note that some versioning of revertable properties may cause propellor
--   to do a lot of unnecessary work each time it's run. Here's an example
--   of such a problem:
--   
--   
--   slow :: Versioned Int -> RevertableProperty DebianLike DebianLike
--   slow ver =
--   	ver (   (== 1) --> (Apt.installed "foo" <!> Apt.removed "foo")
--       <|> (== 2) --> (Apt.installed "bar" <!> Apt.removed "bar")
--          )
--   
--   
--   Suppose that package bar depends on package foo. Then at version 2,
--   propellor will remove package foo in order to revert version 1, only
--   to re-install it since version 2 also needs it installed.
module Propellor.Property.Versioned

-- | Something that has multiple versions of type v.
type Versioned v t = VersionedBy v -> t

-- | Access a particular version of a Versioned value.
version :: (Versioned v t) -> v -> t

-- | Specify a function that checks the version, and what
--   RevertableProperty to use if the version matches.
(-->) :: (v -> Bool) -> RevertableProperty metatypes metatypes -> VerSpec v metatypes
infixl 8 -->

-- | Add an alternate version.
(<|>) :: VerSpec v metatypes -> VerSpec v metatypes -> VerSpec v metatypes
infixl 2 <|>

-- | Installation to a target disk.
--   
--   Note that the RevertableProperties in this module are not really
--   revertable; the target disk can't be put back how it was. The
--   RevertableProperty type is used only to let them be used in a
--   Versioned Host as shown below.
--   
--   Here's an example of a noninteractive installer image using these
--   properties.
--   
--   There are two versions of Hosts, the installer and the target system.
--   
--   
--   data Variety = Installer | Target
--   	deriving (Eq)
--   
--   
--   The seed of both the installer and the target. They have some
--   properties in common, and some different properties. The
--   targetInstalled property knows how to convert the installer
--   it's running on into a target system.
--   
--   
--   seed :: Versioned Variety Host
--   seed ver = host "debian.local" $ props
--   	& osDebian Unstable X86_64
--   	& Hostname.sane
--   	& Apt.stdSourcesList
--   	& Apt.installed ["linux-image-amd64"]
--   	& Grub.installed PC
--   	& "en_US.UTF-8" `Locale.selectedFor` ["LANG"]
--   	& ver ( (== Installer) --> targetInstalled seed Target (userInput ver) parts)
--   	& ver ( (== Target)    --> fstabLists (userInput ver) parts)
--   	& ver ( (== Installer) --> targetBootable (userInput ver))
--     where
--   	parts = TargetPartTable MSDOS
--   		[ partition EXT4 `mountedAt` "/"
--   			`useDiskSpace` RemainingSpace
--   		, swapPartition (MegaBytes 1024)
--   		]
--   
--   
--   The installer disk image can then be built from the seed as follows:
--   
--   
--   installerBuilt :: RevertableProperty (HasInfo + DebianLike) Linux
--   installerBuilt = imageBuilt (VirtualBoxPointer "/srv/installer.vmdk")
--   (hostChroot (seed `version` installer) (Debootstrapped mempty))
--   MSDOS
--   	 [ partition EXT4 `mountedAt` "/"
--   	`setFlag` BootFlag
--   	`reservedSpacePercentage` 0
--   		`addFreeSpace` MegaBytes 256
--   	]
--   
--   
--   When the installer is booted up, and propellor is run, it installs to
--   the target disk. Since this example is a noninteractive installer, the
--   details of what it installs to are configured before it's built.
--   
--   
--   data HardCodedUserInput = HardCodedUserInput (Maybe TargetDiskDevice) (Maybe DiskEraseConfirmed)
--   
--   instance UserInput HardCodedUserInput where 
--   	targetDiskDevice (HardCodedUserInput t _) = Just t
--   	diskEraseConfirmed (HardCodedUserInput _ c) = Just c
--   
--   userInput :: Version -> HardCodedUserInput
--   userInput Installer =  HardCodedUserInput Nothing Nothing
--   userInput Target = HardCodedUserInput (Just (TargetDiskDevice "/dev/sda")) (Just DiskEraseConfirmed)
--   
--   
--   For an example of how to use this to make an interactive installer,
--   see https://git.joeyh.name/index.cgi/secret-project.git/
module Propellor.Property.Installer.Target

-- | Partition table for the target disk.
data TargetPartTable
TargetPartTable :: TableType -> [PartSpec DiskPart] -> TargetPartTable

-- | Property that installs the target system to the TargetDiskDevice
--   specified in the UserInput. That device will be re-partitioned and
--   formatted and all files erased.
--   
--   The installation is done efficiently by rsyncing the installer's files
--   to the target, which forms the basis for a chroot that is provisioned
--   with the specified version of the Host. Thanks to
--   Propellor.Property.Versioned, any unwanted properties of the installer
--   will be automatically reverted in the chroot.
--   
--   When there is no TargetDiskDevice or the user has not confirmed the
--   installation, nothing is done except for installing dependencies. So,
--   this can also be used as a property of the installer image.
targetInstalled :: UserInput i => Versioned v Host -> v -> i -> TargetPartTable -> RevertableProperty (HasInfo + DebianLike) (HasInfo + DebianLike)

-- | Property for use in the target Host to set up its fstab. Should be
--   passed the same TargetPartTable as targetInstalled.
fstabLists :: UserInput i => i -> TargetPartTable -> RevertableProperty Linux Linux

-- | Gets the target mounted.
mountTarget :: UserInput i => i -> [PartSpec DiskPart] -> RevertableProperty Linux Linux

-- | Make the target bootable using whatever bootloader is installed on it.
targetBootable :: UserInput i => i -> RevertableProperty Linux Linux

-- | Partitions the target disk.
partitionTargetDisk :: UserInput i => i -> TableType -> [PartSpec DiskPart] -> RevertableProperty DebianLike DebianLike

-- | Where the target disk is mounted while it's being installed.
targetDir :: FilePath

-- | This can be used to find a likely disk device to use as the target for
--   an installation.
--   
--   This is a bit of a hack; of course the user could be prompted but to
--   avoid prompting, some heuristics... * It should not already be
--   mounted. * Prefer disks big enough to comfortably hold a Linux
--   installation, so at least 8 gb. (But, if the system only has a smaller
--   disk, it should be used.) * A medium size internal disk is better than
--   a large removable disk, because removable or added drives are often
--   used for data storage on systems with smaller internal disk for the
--   OS. (But, if the internal disk is too small, prefer removable disk;
--   some systems have an unusably small internal disk.) * Prefer the first
--   disk in BIOS order, all other things being equal, because the main OS
--   disk typically comes first. This can be approximated by preferring
--   devsda to devsdb.
probeDisk :: IO TargetDiskDevice

-- | Find disk devices, such as devsda (not partitions)
findDiskDevices :: IO [FilePath]

-- | How much of the target disks are used, compared with the size of the
--   installer's root device. Since the main part of an installation is
--   targetInstalled rsyncing the latter to the former, this allows
--   roughly estimating the percent done while an install is running, and
--   can be used in some sort of progress display.
data TargetFilled
data TargetFilledHandle

-- | Prepare for getting TargetFilled.
prepTargetFilled :: IO TargetFilledHandle

-- | Get the current TargetFilled value. This is fast enough to be
--   run multiple times per second without using much CPU.
checkTargetFilled :: TargetFilledHandle -> IO TargetFilled
newtype TargetFilledPercent
TargetFilledPercent :: Int -> TargetFilledPercent
targetFilledPercent :: TargetFilled -> TargetFilledPercent
instance GHC.Classes.Eq Propellor.Property.Installer.Target.TargetFilledPercent
instance GHC.Show.Show Propellor.Property.Installer.Target.TargetFilledPercent
instance GHC.Classes.Eq Propellor.Property.Installer.Target.TargetFilled
instance GHC.Show.Show Propellor.Property.Installer.Target.TargetFilled
instance GHC.Show.Show Propellor.Property.Installer.Target.MinorNumber
instance GHC.Classes.Eq Propellor.Property.Installer.Target.MinorNumber
instance GHC.Classes.Ord Propellor.Property.Installer.Target.Candidate
instance GHC.Classes.Eq Propellor.Property.Installer.Target.Candidate
instance Propellor.Property.Chroot.ChrootBootstrapper Propellor.Property.Installer.Target.RsyncBootstrapper
instance GHC.Base.Monoid Propellor.Property.Installer.Target.TargetFilled

-- | Installer disk image generation
--   
--   These modules contain properties that can be used to create a disk
--   image, suitable for booting from removable media, that can perform an
--   interactive or non-interactive installation of a Host's internal disk.
--   
--   The disk image is created using propellor. When booted, it runs
--   propellor to install to the desired disk.
--   
--   There is no user interface included here. For an example of using this
--   to build a full, interactive installer, see
--   https://git.joeyh.name/index.cgi/secret-project.git/
module Propellor.Property.Installer
