From 6075fc636dfd9d8c946ed11a58ffa7059dd560d0 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 12 Apr 2014 21:34:25 -0400 Subject: propellor spin --- propellor.cabal | 1 + 1 file changed, 1 insertion(+) (limited to 'propellor.cabal') diff --git a/propellor.cabal b/propellor.cabal index 5497cc6b..b28a26d0 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -76,6 +76,7 @@ Library Propellor.Property.Docker Propellor.Property.File Propellor.Property.Git + Propellor.Property.Gpg Propellor.Property.Network Propellor.Property.OpenId Propellor.Property.Reboot -- cgit v1.3-2-g0d8e From c7830f4e669735bf46945592b315e7e367129888 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 12 Apr 2014 22:36:36 -0400 Subject: propellor spin --- Propellor/Property/Cron.hs | 9 +- Propellor/Property/Obnam.hs | 77 +++++++++++++++ config-joey.hs | 10 +- debian/changelog | 2 + privdata/diatom.kitenet.net.gpg | 211 ++++++++++++++++++++-------------------- propellor.cabal | 1 + 6 files changed, 202 insertions(+), 108 deletions(-) create mode 100644 Propellor/Property/Obnam.hs (limited to 'propellor.cabal') diff --git a/Propellor/Property/Cron.hs b/Propellor/Property/Cron.hs index fa6019ea..2fa9c87e 100644 --- a/Propellor/Property/Cron.hs +++ b/Propellor/Property/Cron.hs @@ -4,13 +4,15 @@ import Propellor import qualified Propellor.Property.File as File import qualified Propellor.Property.Apt as Apt +import Data.Char + type CronTimes = String -- | Installs a cron job, run as a specificed user, in a particular --directory. Note that the Desc must be unique, as it is used for the --cron.d/ filename. job :: Desc -> CronTimes -> UserName -> FilePath -> String -> Property -job desc times user cddir command = ("/etc/cron.d/" ++ desc) `File.hasContent` +job desc times user cddir command = cronjobfile `File.hasContent` [ "# Generated by propellor" , "" , "SHELL=/bin/sh" @@ -20,6 +22,11 @@ job desc times user cddir command = ("/etc/cron.d/" ++ desc) `File.hasContent` ] `requires` Apt.serviceInstalledRunning "cron" `describe` ("cronned " ++ desc) + where + cronjobfile = "/etc/cron.d/" ++ map sanitize desc + sanitize c + | isAlphaNum c = c + | otherwise = '_' -- | Installs a cron job, and runs it niced and ioniced. niceJob :: Desc -> CronTimes -> UserName -> FilePath -> String -> Property diff --git a/Propellor/Property/Obnam.hs b/Propellor/Property/Obnam.hs new file mode 100644 index 00000000..ebdcb9dd --- /dev/null +++ b/Propellor/Property/Obnam.hs @@ -0,0 +1,77 @@ +module Propellor.Property.Obnam where + +import Propellor +import qualified Propellor.Property.Apt as Apt +import qualified Propellor.Property.Cron as Cron +import Utility.SafeCommand + +installed :: Property +installed = Apt.installed ["obnam"] + +type ObnamParam = String + +-- | 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. +-- And since Obnam encrypts, just make this property depend on a gpg +-- key, and tell obnam to use the key, and your data will be backed +-- up securely. For example: +-- +-- > & Obnam.backup "/srv/git" "33 3 * * *" +-- > [ "--repository=2318@usw-s002.rsync.net:mygitrepos.obnam" +-- > , "--encrypt-with=1B169BE1" +-- > ] +-- > `requires` Gpg.keyImported "1B169BE1" "root" +-- > `requires` Ssh.keyImported SshRsa "root" +-- +-- How awesome is that? +backup :: FilePath -> Cron.CronTimes -> [ObnamParam] -> Property +backup dir crontimes params = cronjob `describe` desc + `requires` restored dir params + `requires` installed + where + desc = dir ++ " backed up by obnam" + cronjob = Cron.niceJob ("obnam_backup" ++ dir) crontimes "root" "/" $ + unwords $ + [ "obnam" + , "backup" + , shellEscape dir + ] ++ map shellEscape params + +-- | 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 +restored dir params = Property (dir ++ " restored by obnam") go + `requires` installed + where + go = ifM (liftIO needsRestore) + ( liftIO restore + , noChange + ) + + needsRestore = null <$> catchDefaultIO [] (dirContents dir) + + restore = withTmpDirIn (takeDirectory dir) "obnam-restore" $ \tmpdir -> do + ok <- boolSystem "obnam" $ + [ Param "restore" + , Param "--to" + , Param tmpdir + ] ++ map Param params + let restoreddir = tmpdir ++ "/" ++ dir + ifM (pure ok <&&> doesDirectoryExist restoreddir) + ( do + void $ tryIO $ removeDirectory dir + renameDirectory restoreddir dir + return MadeChange + , return FailedChange + ) diff --git a/config-joey.hs b/config-joey.hs index 7403f873..a983e87b 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -18,6 +18,7 @@ import qualified Propellor.Property.OpenId as OpenId import qualified Propellor.Property.Docker as Docker import qualified Propellor.Property.Git as Git import qualified Propellor.Property.Gpg as Gpg +import qualified Propellor.Property.Obnam as Obnam import qualified Propellor.Property.SiteSpecific.GitHome as GitHome import qualified Propellor.Property.SiteSpecific.GitAnnexBuilder as GitAnnexBuilder import qualified Propellor.Property.SiteSpecific.JoeySites as JoeySites @@ -72,8 +73,13 @@ hosts = & Apt.buildDep ["git-annex"] `period` Daily & Git.daemonRunning "/srv/git" & File.ownerGroup "/srv/git" "joey" "joey" - & Gpg.keyImported "git.kitenet.net obnam backup key" "root" - & Ssh.keyImported SshRsa "root" + & Obnam.backup "/srv/git" "33 3 * * *" + [ "--repository=2318@usw-s002.rsync.net:git.kitenet.net" + , "--encrypt-with=1B169BE1" + ] + `requires` Gpg.keyImported "1B169BE1" "root" + `requires` Ssh.keyImported SshRsa "root" + -- git repos restore (how?) (also make backups!) -- family annex needs family members to have accounts, -- ssh host key etc.. finesse? diff --git a/debian/changelog b/debian/changelog index 29f1787e..6593c95d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,8 @@ propellor (0.3.1) UNRELEASED; urgency=medium * Merge scheduler bug fix from git-annex. + * Support for provisioning hosts with ssh and gpg keys. + * Obnam support. -- Joey Hess Fri, 11 Apr 2014 15:00:11 -0400 diff --git a/privdata/diatom.kitenet.net.gpg b/privdata/diatom.kitenet.net.gpg index 34d986c2..da97a08d 100644 --- a/privdata/diatom.kitenet.net.gpg +++ b/privdata/diatom.kitenet.net.gpg @@ -1,109 +1,110 @@ -----BEGIN PGP MESSAGE----- Version: GnuPG v1 -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 -UUFGrYcSqu0P -=w6i8 +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 +/kCJ1kYezrPgaFt3p6JHzQ== +=5opC -----END PGP MESSAGE----- diff --git a/propellor.cabal b/propellor.cabal index b28a26d0..cc616c17 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -78,6 +78,7 @@ Library Propellor.Property.Git Propellor.Property.Gpg Propellor.Property.Network + Propellor.Property.Obnam Propellor.Property.OpenId Propellor.Property.Reboot Propellor.Property.Scheduled -- cgit v1.3-2-g0d8e From 1495db6cd103bf5f9f4635dbbfe807c7c1f39b2e Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 13 Apr 2014 14:01:30 -0400 Subject: propellor spin --- Propellor/Property/Apache.hs | 28 +++++++++ Propellor/Property/File.hs | 9 ++- Propellor/Property/SiteSpecific/JoeySites.hs | 92 ++++++++++++++++++++++++++++ config-joey.hs | 38 +++--------- debian/changelog | 1 + propellor.cabal | 1 + 6 files changed, 136 insertions(+), 33 deletions(-) create mode 100644 Propellor/Property/Apache.hs (limited to 'propellor.cabal') diff --git a/Propellor/Property/Apache.hs b/Propellor/Property/Apache.hs new file mode 100644 index 00000000..5e32b0da --- /dev/null +++ b/Propellor/Property/Apache.hs @@ -0,0 +1,28 @@ +module Propellor.Property.Apache where + +import Propellor +import qualified Propellor.Property.File as File +import qualified Propellor.Property.Apt as Apt + +type ConfigFile = [String] + +siteEnabled :: HostName -> ConfigFile -> RevertableProperty +siteEnabled hn cf = RevertableProperty enable disable + where + enable = siteAvailable hn cf + `onChange` cmdProperty "a2ensite" ["--quiet", hn] + `requires` Apt.installed ["apache2"] + disable = File.notPresent (siteCfg hn) + `onChange` cmdProperty "a2dissite" ["--quiet", hn] + +siteAvailable :: HostName -> ConfigFile -> Property +siteAvailable hn cf = siteCfg hn `File.hasContent` (comment:cf) + `describe` ("apache site available " ++ hn) + where + comment = "# deployed with propellor, do not modify" + +siteCfg :: HostName -> FilePath +siteCfg hn = "/etc/apache2/sites-available/" ++ hn ++ ".conf" + +restart :: Property +restart = cmdProperty "service" ["apache2", "restart"] diff --git a/Propellor/Property/File.hs b/Propellor/Property/File.hs index bd33c9b8..8f23dab7 100644 --- a/Propellor/Property/File.hs +++ b/Propellor/Property/File.hs @@ -31,11 +31,14 @@ hasPrivContentExposed f = hasPrivContent f `onChange` -- | Ensures that a line is present in a file, adding it to the end if not. containsLine :: FilePath -> Line -> Property -f `containsLine` l = fileProperty (f ++ " contains:" ++ l) go f +f `containsLine` l = f `containsLines` [l] + +containsLines :: FilePath -> [Line] -> Property +f `containsLines` l = fileProperty (f ++ " contains:" ++ show l) go f where go ls - | l `elem` ls = ls - | otherwise = ls++[l] + | all (`elem` ls) l = ls + | otherwise = ls++l -- | 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 diff --git a/Propellor/Property/SiteSpecific/JoeySites.hs b/Propellor/Property/SiteSpecific/JoeySites.hs index 46373170..81557b32 100644 --- a/Propellor/Property/SiteSpecific/JoeySites.hs +++ b/Propellor/Property/SiteSpecific/JoeySites.hs @@ -5,6 +5,14 @@ module Propellor.Property.SiteSpecific.JoeySites where import Propellor import qualified Propellor.Property.Apt as Apt +import qualified Propellor.Property.File as File +import qualified Propellor.Property.Gpg as Gpg +import qualified Propellor.Property.Ssh as Ssh +import qualified Propellor.Property.Git as Git +import qualified Propellor.Property.Service as Service +import qualified Propellor.Property.User as User +import qualified Propellor.Property.Obnam as Obnam +import qualified Propellor.Property.Apache as Apache oldUseNetShellBox :: Property oldUseNetShellBox = check (not <$> Apt.isInstalled "oldusenet") $ @@ -21,3 +29,87 @@ oldUseNetShellBox = check (not <$> Apt.isInstalled "oldusenet") $ , "rm -rf /root/tmp/oldusenet" ] `describe` "olduse.net built" ] + +-- git.kitenet.net and git.joeyh.name +gitServer :: [Host] -> Property +gitServer hosts = propertyList "git.kitenet.net setup" + [ Obnam.backup "/srv/git" "33 3 * * *" + [ "--repository=sftp://2318@usw-s002.rsync.net/~/git.kitenet.net" + , "--encrypt-with=1B169BE1" + , "--client-name=wren" + ] Obnam.OnlyClient + `requires` Gpg.keyImported "1B169BE1" "root" + `requires` Ssh.keyImported SshRsa "root" + `requires` Ssh.knownHost hosts "usw-s002.rsync.net" "root" + `requires` Ssh.authorizedKeys "family" + `requires` User.accountFor "family" + , Apt.installed ["git", "git-annex", "rsync", "kgb-client-git", "gitweb"] + , File.hasPrivContentExposed "/etc/kgb-bot/kgb-client.conf" + , toProp $ Git.daemonRunning "/srv/git" + , "/etc/gitweb.conf" `File.containsLines` + [ "$projectroot = 'srv/git';" + , "@git_base_url_list = ('git://git.kitenet.net', 'http://git.kitenet.net/git', 'ssh://git.kitenet.net/srv/git');" + , "# disable snapshot download; overloads server" + , "$feature{'snapshot'}{'default'} = [];" + ] + `describe` "gitweb configured" + , website "git.kitenet.net" + , website "git.joeyh.name" + -- ssh keys for branchable and github repo hooks + -- TODO: upgrade to newer git-annex-shell for notification + -- gitweb + ] + where + website hn = toProp $ Apache.siteEnabled hn (gitapacheconf hn) + +gitapacheconf :: HostName -> Apache.ConfigFile +gitapacheconf hn = + [ "" + , " ServerAdmin joey@kitenet.net" + , "" + , " ServerName " ++ hn ++ ":80" + , "" + , " DocumentRoot /srv/web/git.kitenet.net/" + , " " + , " Options Indexes ExecCGI FollowSymlinks" + , " AllowOverride None" + , " DirectoryIndex index.cgi" + , " " + , "" + , " ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/" + , " " + , " SetHandler cgi-script" + , " Options ExecCGI" + , " " + , "" + , " ErrorLog /var/log/apache2/error.log" + , " LogLevel warn" + , " CustomLog /var/log/apache2/access.log combined" + , "" + , " # Possible values include: debug, info, notice, warn, error, crit," + , " # alert, emerg." + , " LogLevel warn" + , "" + , " CustomLog /var/log/apache2/access.log combined" + , " ServerSignature On" + , " " + , " " + , " Options Indexes MultiViews" + , " AllowOverride None" + , " Order allow,deny" + , " Allow from all" + , " " + , "" + ] + +-- Note: needs debian unstable for new kgb +kgbServer :: Property +kgbServer = propertyList "kgb.kitenet.net setup" + [ Apt.serviceInstalledRunning "kgb-bot" + , File.hasPrivContent "/etc/kgb-bot/kgb.conf" + `onChange` Service.restarted "kgb-bot" + , "/etc/default/kgb-bot" `File.containsLine` "BOT_ENABLED=1" + `describe` "kgb bot enabled" + `onChange` Service.running "kgb-bot" + ] + diff --git a/config-joey.hs b/config-joey.hs index 9976592e..aba648dc 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -5,7 +5,6 @@ import Propellor.CmdLine import Propellor.Property.Scheduled import qualified Propellor.Property.File as File import qualified Propellor.Property.Apt as Apt -import qualified Propellor.Property.Service as Service import qualified Propellor.Property.Network as Network import qualified Propellor.Property.Ssh as Ssh import qualified Propellor.Property.Cron as Cron @@ -18,8 +17,6 @@ import qualified Propellor.Property.Dns as Dns import qualified Propellor.Property.OpenId as OpenId import qualified Propellor.Property.Docker as Docker import qualified Propellor.Property.Git as Git -import qualified Propellor.Property.Gpg as Gpg -import qualified Propellor.Property.Obnam as Obnam import qualified Propellor.Property.SiteSpecific.GitHome as GitHome import qualified Propellor.Property.SiteSpecific.GitAnnexBuilder as GitAnnexBuilder import qualified Propellor.Property.SiteSpecific.JoeySites as JoeySites @@ -48,15 +45,10 @@ hosts = & cname "ancient.kitenet.net" & Docker.docked hosts "ancient-kitenet" - -- I'd rather this were on diatom, but I use features - -- not available in stable. + -- I'd rather this were on diatom, but it needs unstable. & cname "kgb.kitenet.net" - & Apt.serviceInstalledRunning "kgb-bot" - & File.hasPrivContent "/etc/kgb-bot/kgb.conf" - `onChange` Service.restarted "kgb-bot" - & "/etc/default/kgb-bot" `File.containsLine` "BOT_ENABLED=1" - `describe` "kgb bot enabled" - `onChange` Service.running "kgb-bot" + & JoeySites.kgbServer + & Docker.garbageCollected `period` Daily & Apt.installed ["git-annex", "mtr", "screen"] @@ -75,31 +67,17 @@ hosts = -- Important stuff that needs not too much memory or CPU. , standardSystem "diatom.kitenet.net" Stable & Hostname.sane + & Ssh.hostKey SshDsa + & Ssh.hostKey SshRsa + & Ssh.hostKey SshEcdsa & Apt.unattendedUpgrades & Apt.serviceInstalledRunning "ntp" & Dns.zones myDnsSecondary & Apt.serviceInstalledRunning "apache2" & cname "git.kitenet.net" - & Ssh.hostKey SshDsa - & Ssh.hostKey SshRsa - & Ssh.hostKey SshEcdsa - & Obnam.backup "/srv/git" "33 3 * * *" - [ "--repository=sftp://2318@usw-s002.rsync.net/~/git.kitenet.net" - , "--encrypt-with=1B169BE1" - , "--client-name=wren" - ] Obnam.OnlyClient - `requires` Gpg.keyImported "1B169BE1" "root" - `requires` Ssh.keyImported SshRsa "root" - `requires` Ssh.knownHost hosts "usw-s002.rsync.net" "root" - `requires` Ssh.authorizedKeys "family" - `requires` User.accountFor "family" - & Apt.installed ["git", "git-annex", "rsync", "kgb-client-git"] - & File.hasPrivContentExposed "/etc/kgb-bot/kgb-client.conf" - & Git.daemonRunning "/srv/git" - -- ssh keys for branchable and github repo hooks - -- TODO: upgrade to newer git-annex-shell for notification - -- gitweb + & cname "git.joeyh.name" + & JoeySites.gitServer hosts & cname "downloads.kitenet.net" & Apt.buildDep ["git-annex"] `period` Daily diff --git a/debian/changelog b/debian/changelog index 6593c95d..b3cc554a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,7 @@ propellor (0.3.1) UNRELEASED; urgency=medium * Merge scheduler bug fix from git-annex. * Support for provisioning hosts with ssh and gpg keys. * Obnam support. + * Apache support. -- Joey Hess Fri, 11 Apr 2014 15:00:11 -0400 diff --git a/propellor.cabal b/propellor.cabal index cc616c17..a7b7fbca 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -68,6 +68,7 @@ Library Exposed-Modules: Propellor Propellor.Property + Propellor.Property.Apache Propellor.Property.Apt Propellor.Property.Cmd Propellor.Property.Hostname -- cgit v1.3-2-g0d8e From 95ac5163da904780ae166c2bf3a0addcb8d8870e Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 13 Apr 2014 15:34:01 -0400 Subject: Properties can now be satisfied differently on different operating systems. --- Propellor/Attr.hs | 7 +++++++ Propellor/Message.hs | 4 ++-- Propellor/Property.hs | 8 ++++++++ Propellor/Types.hs | 28 ++-------------------------- Propellor/Types/Attr.hs | 7 ++++++- Propellor/Types/OS.hs | 19 +++++++++++++++++++ config-joey.hs | 12 +++++++----- debian/changelog | 2 ++ propellor.cabal | 1 + 9 files changed, 54 insertions(+), 34 deletions(-) create mode 100644 Propellor/Types/OS.hs (limited to 'propellor.cabal') diff --git a/Propellor/Attr.hs b/Propellor/Attr.hs index 67ea8b8c..9a9d8446 100644 --- a/Propellor/Attr.hs +++ b/Propellor/Attr.hs @@ -21,6 +21,13 @@ hostname name = pureAttrProperty ("hostname " ++ name) $ getHostName :: Propellor HostName getHostName = asks _hostname +os :: System -> AttrProperty +os system = pureAttrProperty ("OS " ++ show system) $ + \d -> d { _os = Just system } + +getOS :: Propellor (Maybe System) +getOS = asks _os + cname :: Domain -> AttrProperty cname domain = pureAttrProperty ("cname " ++ domain) (addCName domain) diff --git a/Propellor/Message.hs b/Propellor/Message.hs index 2e63061e..780471c3 100644 --- a/Propellor/Message.hs +++ b/Propellor/Message.hs @@ -29,7 +29,7 @@ actionMessage desc a = do return r warningMessage :: MonadIO m => String -> m () -warningMessage s = liftIO $ colorLine Vivid Red $ "** warning: " ++ s +warningMessage s = liftIO $ colorLine Vivid Magenta $ "** warning: " ++ s colorLine :: ColorIntensity -> Color -> String -> IO () colorLine intensity color msg = do @@ -43,7 +43,7 @@ colorLine intensity color msg = do errorMessage :: String -> IO a errorMessage s = do - warningMessage s + liftIO $ colorLine Vivid Red $ "** error: " ++ s error "Cannot continue!" -- | Causes a debug message to be displayed when PROPELLOR_DEBUG=1 diff --git a/Propellor/Property.hs b/Propellor/Property.hs index 3e41fbcb..95d17c05 100644 --- a/Propellor/Property.hs +++ b/Propellor/Property.hs @@ -10,6 +10,7 @@ import "mtl" Control.Monad.Reader import Propellor.Types import Propellor.Types.Attr +import Propellor.Attr import Propellor.Engine import Utility.Monad import System.FilePath @@ -91,6 +92,13 @@ check c property = Property (propertyDesc property) $ ifM (liftIO c) , return NoChange ) +-- | Makes a property that is satisfied differently depending on the host's +-- operating system. +-- +-- Note that the operating system may not be declared for some hosts. +withOS :: Desc -> (Maybe System -> Propellor Result) -> Property +withOS desc a = Property desc $ a =<< getOS + boolProperty :: Desc -> IO Bool -> Property boolProperty desc a = Property desc $ ifM (liftIO a) ( return MadeChange diff --git a/Propellor/Types.hs b/Propellor/Types.hs index b8f8f167..5f575daf 100644 --- a/Propellor/Types.hs +++ b/Propellor/Types.hs @@ -6,8 +6,6 @@ module Propellor.Types ( Host(..) , Attr , HostName - , UserName - , GroupName , Propellor(..) , Property(..) , RevertableProperty(..) @@ -19,16 +17,12 @@ module Propellor.Types , requires , Desc , Result(..) - , System(..) - , Distribution(..) - , DebianSuite(..) - , Release - , Architecture , ActionResult(..) , CmdLine(..) , PrivDataField(..) , GpgKeyId , SshKeyType(..) + , module Propellor.Types.OS ) where import Data.Monoid @@ -38,12 +32,10 @@ import "mtl" Control.Monad.Reader import "MonadCatchIO-transformers" Control.Monad.CatchIO import Propellor.Types.Attr +import Propellor.Types.OS data Host = Host [Property] (Attr -> Attr) -type UserName = String -type GroupName = String - -- | Propellor's monad provides read-only access to attributes of the -- system. newtype Propellor p = Propellor { runWithAttr :: ReaderT Attr IO p } @@ -119,22 +111,6 @@ instance Monoid Result where mappend _ MadeChange = MadeChange mappend NoChange NoChange = NoChange --- | High level descritption of a operating system. -data System = System Distribution Architecture - deriving (Show) - -data Distribution - = Debian DebianSuite - | Ubuntu Release - deriving (Show) - -data DebianSuite = Experimental | Unstable | Testing | Stable | DebianRelease Release - deriving (Show, Eq) - -type Release = String - -type Architecture = String - -- | Results of actions, with color. class ActionResult a where getActionResult :: a -> (String, ColorIntensity, Color) diff --git a/Propellor/Types/Attr.hs b/Propellor/Types/Attr.hs index cdbe9ca3..1ff58148 100644 --- a/Propellor/Types/Attr.hs +++ b/Propellor/Types/Attr.hs @@ -1,11 +1,14 @@ module Propellor.Types.Attr where +import Propellor.Types.OS + import qualified Data.Set as S -- | The attributes of a host. For example, its hostname. data Attr = Attr { _hostname :: HostName , _cnames :: S.Set Domain + , _os :: Maybe System , _sshPubKey :: Maybe String , _dockerImage :: Maybe String @@ -16,6 +19,7 @@ instance Eq Attr where x == y = and [ _hostname x == _hostname y , _cnames x == _cnames y + , _os x == _os y , _sshPubKey x == _sshPubKey y , _dockerImage x == _dockerImage y @@ -27,13 +31,14 @@ instance Show Attr where show a = unlines [ "hostname " ++ _hostname a , "cnames " ++ show (_cnames a) + , "OS " ++ show (_os a) , "sshPubKey " ++ show (_sshPubKey a) , "docker image " ++ show (_dockerImage a) , "docker run params " ++ show (map (\mk -> mk "") (_dockerRunParams a)) ] newAttr :: HostName -> Attr -newAttr hn = Attr hn S.empty Nothing Nothing [] +newAttr hn = Attr hn S.empty Nothing Nothing Nothing [] type HostName = String type Domain = String diff --git a/Propellor/Types/OS.hs b/Propellor/Types/OS.hs new file mode 100644 index 00000000..5b0e376d --- /dev/null +++ b/Propellor/Types/OS.hs @@ -0,0 +1,19 @@ +module Propellor.Types.OS where + +type UserName = String +type GroupName = String + +-- | High level descritption of a operating system. +data System = System Distribution Architecture + deriving (Show, Eq) + +data Distribution + = Debian DebianSuite + | Ubuntu Release + deriving (Show, Eq) + +data DebianSuite = Experimental | Unstable | Testing | Stable | DebianRelease Release + deriving (Show, Eq) + +type Release = String +type Architecture = String diff --git a/config-joey.hs b/config-joey.hs index aba648dc..ed214e82 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -29,7 +29,7 @@ hosts = & Apt.buildDep ["git-annex"] `period` Daily -- Nothing super-important lives here. - , standardSystem "clam.kitenet.net" Unstable + , standardSystem "clam.kitenet.net" Unstable "amd64" & cleanCloudAtCost & Apt.unattendedUpgrades & Network.ipv6to4 @@ -53,7 +53,7 @@ hosts = & Apt.installed ["git-annex", "mtr", "screen"] -- Orca is the main git-annex build box. - , standardSystem "orca.kitenet.net" Unstable + , standardSystem "orca.kitenet.net" Unstable "amd64" & Hostname.sane & Apt.unattendedUpgrades & Docker.configured @@ -65,7 +65,7 @@ hosts = & Apt.buildDep ["git-annex"] `period` Daily -- Important stuff that needs not too much memory or CPU. - , standardSystem "diatom.kitenet.net" Stable + , standardSystem "diatom.kitenet.net" Stable "amd64" & Hostname.sane & Ssh.hostKey SshDsa & Ssh.hostKey SshRsa @@ -142,8 +142,9 @@ gitAnnexBuilder arch buildminute = Docker.container (arch ++ "-git-annex-builder & Apt.unattendedUpgrades -- This is my standard system setup. -standardSystem :: HostName -> DebianSuite -> Host -standardSystem hn suite = host hn +standardSystem :: HostName -> DebianSuite -> Architecture -> Host +standardSystem hn suite arch = host hn + & os (System (Debian suite) arch) & Apt.stdSourcesList suite `onChange` Apt.upgrade & Apt.installed ["etckeeper"] & Apt.installed ["ssh"] @@ -166,6 +167,7 @@ standardSystem hn suite = host hn -- This is my standard container setup, featuring automatic upgrades. standardContainer :: Docker.ContainerName -> DebianSuite -> Architecture -> Host standardContainer name suite arch = Docker.container name (image system) + & os (System (Debian suite) arch) & Apt.stdSourcesList suite & Apt.unattendedUpgrades where diff --git a/debian/changelog b/debian/changelog index b3cc554a..4c18df20 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,8 @@ propellor (0.3.1) UNRELEASED; urgency=medium * Support for provisioning hosts with ssh and gpg keys. * Obnam support. * Apache support. + * Properties can now be satisfied differently on different operating + systems. -- Joey Hess Fri, 11 Apr 2014 15:00:11 -0400 diff --git a/propellor.cabal b/propellor.cabal index a7b7fbca..1d625381 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -97,6 +97,7 @@ Library Propellor.Engine Propellor.Exception Propellor.Types + Propellor.Types.OS Other-Modules: Propellor.Types.Attr Propellor.CmdLine -- cgit v1.3-2-g0d8e