-- This is the main configuration file for Propellor, and is used to -- the propellor program. import Propellor import qualified Propellor.Property.Apt as Apt import qualified Propellor.Property.Cmd as Cmd import qualified Propellor.Property.Cron as Cron import qualified Propellor.Property.File as File import qualified Propellor.Property.Sudo as Sudo import qualified Propellor.Property.User as User import qualified Propellor.Property.Ssh as Ssh import qualified Propellor.Property.Hostname as Hostname import qualified Propellor.Property.Locale as Locale import Control.Applicative import Propellor.Utilities import Data.Maybe import Data.List main :: IO () main = defaultMain hosts -- The hosts propellor knows about. hosts :: [Host] hosts = [ -- cavia, coypu, marmot, woodmouse, wolverine ] -- Cavia is a T430s laptop - my main terminal -- Stable -- cavia :: Host -- cavia = host "cavia.rodere.systems" $ props -- & standardGraphicalSystem (Stable "stretch") X86_64 ["Welcome to Cavia"] -- Coypu is a HTPC low-power i3 server -- Testing coypu :: Host coypu = host "coypu.rodere.systems" $ props & standardSystem (Stable "stretch") X86_64 ["Welcome to Coypu"] -- Wolverine is a powerful desktop server that usually stays powered off -- Good for everything -- Testing wolverine :: Host wolverine = host "wolverine.rodere.systems" $ props & standardSystem (Testing) X86_64 ["Welcome to Wolverine"] -- Marmot is a well-rounded server for development and builds. -- Semi-stable marmot :: Host marmot = host "marmot.rodere.systems" $ props & standardSystem (Stable "stretch") X86_64 ["Welcome to Marmot"] & Apt.installed ["cgit", "nginx", "fcgiwrap"] -- Woodmouse is a minimal workbench server -- Stable woodmouse :: Host woodmouse = host "woodmouse.rodere.systems" $ props & standardSystem (Stable "stretch") X86_64 ["Welcome to Woodmouse"] & Apt.backportInstalled["znc"] & customZNCBacklogPkgInstalled -- This is my standard system setup. type Motd = [String] -- This is my standard system setup. standardSystem :: DebianSuite -> Architecture -> Motd -> Property (HasInfo + Debian) standardSystem suite arch motd = standardSystemUnhardened suite arch motd `before` Ssh.noPasswords standardSystemUnhardened :: DebianSuite -> Architecture -> Motd -> Property (HasInfo + Debian) standardSystemUnhardened suite arch motd = propertyList "standard system" $ props & osDebian suite arch & Hostname.sane & Hostname.searchDomain & Locale.available "en_US.UTF-8" & File.hasContent "/etc/motd" ("":motd++[""]) & Apt.stdSourcesList `onChange` Apt.upgrade & Apt.cacheCleaned & Apt.update & Apt.installed ["etckeeper","sudo"] & Apt.installed ["ssh","mosh","git","wget","curl"] & Apt.installed ["vim","screen","less","emacs-nox"] & User.accountFor (User "root") & User.hasSomePassword (User "root") & User.accountFor (User "gnusosa") & User.hasSomePassword (User "gnusosa") & Sudo.enabledFor (User "gnusosa") & User.accountFor (User "git") & Cron.runPropellor (Cron.Times "20 * * * *") -- I don't care for Exim & Apt.removed ["exim4", "exim4-daemon-light", "exim4-config", "exim4-base"] `onChange` Apt.autoRemove customZNCBacklogPkgInstalled :: Property UnixLike customZNCBacklogPkgInstalled = check (not <$> Apt.isInstalled "znc-backlog") (getAndInstallZNCBacklogPkg) getWebFile :: [String] -> String -> UncheckedProperty UnixLike getWebFile params url = cmdProperty "wget" (params++[url]) doesWebFileExist :: String -> IO Bool doesWebFileExist url = (== [True]) <$> (mapMaybe parse . lines) <$> go where parse l | "HTTP/1.1 200 OK" `isInfixOf` l = Just True | "HTTP/1.1 400 Not Found" `isInfixOf` l = Just False | otherwise = Nothing go = do readProcess "curl" (["--head","-L"]++[url]) runForcedDpkg :: Apt.Package -> [String] -> Property UnixLike runForcedDpkg ps fs = check (Apt.isInstalled ps) (cmdProperty "dpkg" (["-i", "--force-all"]++fs)) getZNCBacklogPkg :: Property UnixLike getZNCBacklogPkg = check (doesWebFileExist url) (getWebFile ["-Pznc"] url) where url = "http://www.gnusosa.net/misc/pkgs/debian/znc-backlog.deb" installZNCBacklogPkg :: Property UnixLike installZNCBacklogPkg = check (doesFileExist path) (runForcedDpkg "znc-backlog" [path]) where path = "/usr/local/propellor/znc/znc-backlog.deb" getAndInstallZNCBacklogPkg :: Property UnixLike getAndInstallZNCBacklogPkg = propertyList "get-install custom znc-backlog package" $ props & getZNCBacklogPkg & installZNCBacklogPkg