From 934910052c5a03785fb3a5c99f04a3919921e06c Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 6 Jun 2014 21:40:31 -0400 Subject: propellor spin --- config-joey.hs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/config-joey.hs b/config-joey.hs index 2dcbf9b4..31ca807b 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -179,7 +179,6 @@ hosts = -- (o) ` & Apt.installed ["git-annex"] & Docker.configured - ! Docker.docked hosts "voltagex" & Docker.garbageCollected `period` (Weekly (Just 1)) --' __|II| ,. @@ -231,15 +230,6 @@ hosts = -- (o) ` & Docker.volume ("/home/joey/src/git-annex:" ++ gitannexdir) -- temp for an acquantance - , standardContainer "voltagex" Stable "amd64" - & Docker.publish "22022:22" - & Docker.memory "500m" - & Docker.cpuShares 1 - & Apt.serviceInstalledRunning "ssh" - & Ssh.permitRootLogin True - & Ssh.passwordAuthentication True - & User.hasSomePassword "root" - ] ++ monsters -- This is my standard system setup. -- cgit v1.2.3 -- cgit v1.2.3 From d832ef93d68e3b15d71ea4cf990d94f741ca3141 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 6 Jun 2014 21:51:00 -0400 Subject: propellor spin --- config-joey.hs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config-joey.hs b/config-joey.hs index 31ca807b..d9e23bc0 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -170,6 +170,10 @@ hosts = -- (o) ` & Hostname.sane & Postfix.satellite & Apt.unattendedUpgrades + & Ssh.hostKey SshDsa + & Ssh.hostKey SshRsa + & Ssh.hostKey SshEcdsa + & Ssh.keyImported SshRsa "joey" & alias "eubackup.kitenet.net" & Apt.installed ["obnam", "sshfs", "rsync"] -- cgit v1.2.3 From c538426b56e7915cc0a1f00388baa31c9e88dd36 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 6 Jun 2014 22:08:52 -0400 Subject: propellor spin --- config-joey.hs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/config-joey.hs b/config-joey.hs index d9e23bc0..236af544 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -175,6 +175,22 @@ hosts = -- (o) ` & Ssh.hostKey SshEcdsa & Ssh.keyImported SshRsa "joey" + -- PV-grub chaining + -- http://notes.pault.ag/linode-pv-grub-chainning/ + & "/boot/grub/menu.lst" `File.hasContent` + [ "default 1" + , "timeout 30" + , "" + , "title grub-xen shim" + , "root (hd0,0)" + , "kernel /boot/xen-shim" + , "boot" + ] + & "/boot/load.cf" `File.hasContent` + [ "configfile (xen/xvda)/boot/grub/grub.cfg" ] + & Apt.installed ["grub-xen"] + & flagFile (scriptProperty ["grub-mkimage --prefix '(xen/xvda)/boot/grub' -c /boot/load.cf -O x86_64-xen /usr/lib/grub/x86_64-xen/*.mod > /boot/xen-shim"]) "/boot/xen-shim" + & alias "eubackup.kitenet.net" & Apt.installed ["obnam", "sshfs", "rsync"] & JoeySites.githubBackup -- cgit v1.2.3 From 0840c70d8b384aa326a129c9e65d31fe0ebca2eb Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 6 Jun 2014 22:23:36 -0400 Subject: propellor spin --- config-joey.hs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/config-joey.hs b/config-joey.hs index 236af544..c08eadaf 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -177,6 +177,7 @@ hosts = -- (o) ` -- PV-grub chaining -- http://notes.pault.ag/linode-pv-grub-chainning/ + -- (Adapted to use xvda1/hd0,0 instead of xvda/hd0) & "/boot/grub/menu.lst" `File.hasContent` [ "default 1" , "timeout 30" @@ -187,9 +188,9 @@ hosts = -- (o) ` , "boot" ] & "/boot/load.cf" `File.hasContent` - [ "configfile (xen/xvda)/boot/grub/grub.cfg" ] + [ "configfile (xen/xvda1)/boot/grub/grub.cfg" ] & Apt.installed ["grub-xen"] - & flagFile (scriptProperty ["grub-mkimage --prefix '(xen/xvda)/boot/grub' -c /boot/load.cf -O x86_64-xen /usr/lib/grub/x86_64-xen/*.mod > /boot/xen-shim"]) "/boot/xen-shim" + & flagFile (scriptProperty ["update-grub; grub-mkimage --prefix '(xen/xvda1)/boot/grub' -c /boot/load.cf -O x86_64-xen /usr/lib/grub/x86_64-xen/*.mod > /boot/xen-shim"]) "/boot/xen-shim" & alias "eubackup.kitenet.net" & Apt.installed ["obnam", "sshfs", "rsync"] -- cgit v1.2.3 From ec56e5452dbd05e26fba87407b3e20c9dc024693 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 6 Jun 2014 22:31:22 -0400 Subject: propellor spin --- privdata/elephant.kitenet.net.gpg | 125 ++++++++++++++++++++++++++++++++------ 1 file changed, 107 insertions(+), 18 deletions(-) diff --git a/privdata/elephant.kitenet.net.gpg b/privdata/elephant.kitenet.net.gpg index 315fea00..41eda0d5 100644 --- a/privdata/elephant.kitenet.net.gpg +++ b/privdata/elephant.kitenet.net.gpg @@ -1,22 +1,111 @@ -----BEGIN PGP MESSAGE----- Version: GnuPG v1 -hQIMA7ODiaEXBlRZAQ//SW/xJB2ymi3hEqTbJRCtmU2cbMW/mk/Mb/ZW3P0DaARv -beC10xd1fgFUCNt40JrQ5HGeq5ckG/GWEjT2J1IP3oDTPPoK40qqLYZfHYLyAFok -N59z2rh2FDwsnd7ordI6SAfuyd5Z5v+SF800tIjOuy5Byjw8n3QkrpnLdXhBZU7k -8EP94+/z1vWOkumVqiFRarqbgBwoAbVv0dnp5/CHqGPl83P/JSGrjMMxbcaZ/gfA -ACbX/jq7nHwhYRRkDAsHKZ2IqD48r14ddtoLdXhATUDJBFUEEGoAVOvbCigLzjQE -yXeQ7H3kZ7yVy6iWhaRyKtsCy3rfApzbjleYTisT9cLlVUC0z+kitgcIpcWKF286 -ezWaM8qcyuXXsDmr0e0QLAN2gbJMNrM2D2mgULMKnYT2h72/raQOiUOxgWJgyo1U -ybzEVRmF9YWQXrzZI66FEK7e94IPK68JMNEFVc3brrhNi6zNfpTck5Ut5R9pa41L -u8oIqOZ11GTFhZ2COhlAV+Ud5ihXoGKa4HtqsJFrOsonNz9i1J2kw+2vhsZ2lG7X -ILVeFmDnWNfOv1ONe/eO4ZfRO7BdA3EovYCr8CF5zN9WI5y09DWnHg+3Qm90rHMo -ytZoevIpNpkHN+g0u+rNs2qIm4F2E2oI9IwjrI2oo/0tZbwfclICu4ed6e5oqu3S -wFcBmuO0P9zst5bmgozQaMUKgTKidKDtg8G33AqICRttwDr++JR0mCTKB8fW7KBu -R07VTpxd5RcXww8OFZYjf7UBNO1z98prBiJC+gUP4jccZD8zeahxqZ908CHMx5sf -Pb2VGT7X/wZExy6Ek9GRSpA0gGGCWDc9ITmRVHvXWvbxP0F/zzuYhggxJFGoSgw/ -7fWq05dfI8pKaOeBlzF/XsrtrLJO3yZVEw17eodxa/KEkAbP+Ze3Qfmurg0UMbut -2y0GsYzpSpzWGoBtYigXtVYDveeohzPu8jL01NbfmkNDp6FSjkm31E4sV7ipe5M7 -cvzDXh7in4RBO1znFwzGccDeNT2d8t9Pf+up9wxs7+EvsKwA2hRBLfg= -=AdUG +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 +=oXYz -----END PGP MESSAGE----- -- cgit v1.2.3 From fc9fdfe1351dc5273185190af62989caba55ffa8 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 6 Jun 2014 22:35:23 -0400 Subject: propellor spin --- privdata/diatom.kitenet.net.gpg | 736 ++++++++++++++++++++-------------------- 1 file changed, 368 insertions(+), 368 deletions(-) diff --git a/privdata/diatom.kitenet.net.gpg b/privdata/diatom.kitenet.net.gpg index d1e76014..9643cf94 100644 --- a/privdata/diatom.kitenet.net.gpg +++ b/privdata/diatom.kitenet.net.gpg @@ -1,372 +1,372 @@ -----BEGIN PGP MESSAGE----- Version: GnuPG v1 -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 -uHj0ZyJrX3IzUToU+/qSYA53iBg6mX7EsHM= -=IsJI +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 +7/HW/0mHEZlf846FaPssiNT+Ieyj9Q== +=lxmO -----END PGP MESSAGE----- -- cgit v1.2.3 From 6fc6d54f8a8b6cff9da2f51dc50d29efbada3d5a Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 6 Jun 2014 22:46:31 -0400 Subject: propellor spin --- config-joey.hs | 1 + src/Propellor/Property/SiteSpecific/JoeySites.hs | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/config-joey.hs b/config-joey.hs index c08eadaf..74ad9e9a 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -195,6 +195,7 @@ hosts = -- (o) ` & alias "eubackup.kitenet.net" & Apt.installed ["obnam", "sshfs", "rsync"] & JoeySites.githubBackup + & JoeySites.obnamRepos ["wren", "pell"] & alias "podcatcher.kitenet.net" & Apt.installed ["git-annex"] diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs index b44401ea..c66c167d 100644 --- a/src/Propellor/Property/SiteSpecific/JoeySites.hs +++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs @@ -338,3 +338,14 @@ githubBackup = propertyList "github-backup box" in File.hasPrivContent f `onChange` File.ownerGroup f "joey" "joey" ] + +obnamRepos :: [String] -> Property +obnamRepos rs = propertyList ("obnam repos for " ++ unwords rs) + (mkbase : map mkrepo rs) + where + mkbase = mkdir "/home/joey/lib" + `before` mkdir "/home/joey/backup" + mkrepo r = mkdir ("/home/joey/lib/nackup/" ++ r ++ ".obnam") + mkdir d = File.dirExists d + `before` File.ownerGroup "joey" "joey" d + -- cgit v1.2.3 From c3add08491ba90e7efc7856f200baa60531ec7d6 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 6 Jun 2014 22:47:42 -0400 Subject: propellor spin --- src/Propellor/Property/SiteSpecific/JoeySites.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs index c66c167d..1055dbfb 100644 --- a/src/Propellor/Property/SiteSpecific/JoeySites.hs +++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs @@ -345,7 +345,7 @@ obnamRepos rs = propertyList ("obnam repos for " ++ unwords rs) where mkbase = mkdir "/home/joey/lib" `before` mkdir "/home/joey/backup" - mkrepo r = mkdir ("/home/joey/lib/nackup/" ++ r ++ ".obnam") + mkrepo r = mkdir ("/home/joey/lib/backup/" ++ r ++ ".obnam") mkdir d = File.dirExists d - `before` File.ownerGroup "joey" "joey" d + `before` File.ownerGroup d "joey" "joey" -- cgit v1.2.3 From a0aac3924479a643abadea1ca85a0e3968eabf4d Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 6 Jun 2014 22:49:55 -0400 Subject: propellor spin --- src/Propellor/Property/SiteSpecific/JoeySites.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs index 1055dbfb..120ea611 100644 --- a/src/Propellor/Property/SiteSpecific/JoeySites.hs +++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs @@ -343,8 +343,8 @@ obnamRepos :: [String] -> Property obnamRepos rs = propertyList ("obnam repos for " ++ unwords rs) (mkbase : map mkrepo rs) where - mkbase = mkdir "/home/joey/lib" - `before` mkdir "/home/joey/backup" + mkbase = mkdir "/home/joey/lib/backup" + `requires` mkdir "/home/joey/lib" mkrepo r = mkdir ("/home/joey/lib/backup/" ++ r ++ ".obnam") mkdir d = File.dirExists d `before` File.ownerGroup d "joey" "joey" -- cgit v1.2.3 From 9ed258633a19f5b3aa1169c621281973f607c231 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 6 Jun 2014 23:07:05 -0400 Subject: propellor spin --- src/Propellor/Property/Obnam.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Propellor/Property/Obnam.hs b/src/Propellor/Property/Obnam.hs index e5ef7365..3d13e61e 100644 --- a/src/Propellor/Property/Obnam.hs +++ b/src/Propellor/Property/Obnam.hs @@ -110,7 +110,7 @@ latestVersion = withOS "obnam latest version" $ \o -> case o of _ -> noChange where sources suite = - [ "deb http://code.liw.fi/debian " ++ Apt.showSuite suite ++ " main" + [ "deb http://code.liw.fi/debian " ++ Apt.showSuite stableRelease ++ " main" ] -- gpg key used by the code.liw.fi repository. key = Apt.AptKey "obnam" $ unlines -- cgit v1.2.3 From b5812c7564076c08f1ff7a2d7460a51074dad397 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 6 Jun 2014 23:07:46 -0400 Subject: propellor spin --- src/Propellor/Property/Obnam.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Propellor/Property/Obnam.hs b/src/Propellor/Property/Obnam.hs index 3d13e61e..15a8494c 100644 --- a/src/Propellor/Property/Obnam.hs +++ b/src/Propellor/Property/Obnam.hs @@ -105,11 +105,11 @@ installed = Apt.installed ["obnam"] latestVersion :: Property latestVersion = withOS "obnam latest version" $ \o -> case o of (Just (System (Debian suite) _)) | isStable suite -> ensureProperty $ - Apt.setSourcesListD (sources suite) "obnam" + Apt.setSourcesListD stablesources "obnam" `requires` toProp (Apt.trustsKey key) _ -> noChange where - sources suite = + stablesources = [ "deb http://code.liw.fi/debian " ++ Apt.showSuite stableRelease ++ " main" ] -- gpg key used by the code.liw.fi repository. -- cgit v1.2.3 -- cgit v1.2.3 From 969db1ed56157aa202359c0f47fff783baba6eac Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 7 Jun 2014 00:07:08 -0400 Subject: when ssh key data is missing, allow both error messages to be printed --- config-joey.hs | 1 + src/Propellor/Property.hs | 9 +++++++++ src/Propellor/Property/Ssh.hs | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/config-joey.hs b/config-joey.hs index 74ad9e9a..63768eeb 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -196,6 +196,7 @@ hosts = -- (o) ` & Apt.installed ["obnam", "sshfs", "rsync"] & JoeySites.githubBackup & JoeySites.obnamRepos ["wren", "pell"] + & Ssh.knownHost hosts "usw-s002.rsync.net" "joey" & alias "podcatcher.kitenet.net" & Apt.installed ["git-annex"] diff --git a/src/Propellor/Property.hs b/src/Propellor/Property.hs index e3d46eae..c7a03765 100644 --- a/src/Propellor/Property.hs +++ b/src/Propellor/Property.hs @@ -37,6 +37,15 @@ combineProperties desc ps = Property desc (go ps NoChange) (combineAttrs ps) FailedChange -> return FailedChange _ -> go ls (r <> rs) +-- | Does not stop on failure (but does propigate failure at the end). +combineProperties' :: Desc -> [Property] -> Property +combineProperties' desc ps = Property desc (go ps NoChange) (combineAttrs ps) + where + go [] rs = return rs + go (l:ls) rs = do + r <- ensureProperty l + go ls (r <> rs) + -- | Combines together two properties, resulting in one property -- that ensures the first, and if the first succeeds, ensures the second. -- The property uses the description of the first property. diff --git a/src/Propellor/Property/Ssh.hs b/src/Propellor/Property/Ssh.hs index 061f440c..ba0311cc 100644 --- a/src/Propellor/Property/Ssh.hs +++ b/src/Propellor/Property/Ssh.hs @@ -97,7 +97,7 @@ hostKey keytype = combineProperties desc -- | Sets up a user with a ssh private key and public key pair -- from the site's PrivData. keyImported :: SshKeyType -> UserName -> Property -keyImported keytype user = combineProperties desc +keyImported keytype user = combineProperties' desc [ property desc (install writeFile (SshPubKey keytype user) ".pub") , property desc (install writeFileProtected (SshPrivKey keytype user) "") ] -- cgit v1.2.3 From 582be8ebe00838509d978091d3c97ebeb1bf99de Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 7 Jun 2014 00:14:05 -0400 Subject: combineProperties no longer stops when a property fails; now it continues trying to satisfy all properties on the list before propigating the failure. Audited all of my calls to combineProperties and they should be fine with this behavior.. which suggests it's the right behavior. --- debian/changelog | 8 ++++++++ propellor.cabal | 2 +- src/Propellor/Property.hs | 12 ++---------- src/Propellor/Property/Ssh.hs | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/debian/changelog b/debian/changelog index 046cf607..5b6cdcbc 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +propellor (0.7.0) UNRELEASED; urgency=medium + + * combineProperties no longer stops when a property fails; now it continues + trying to satisfy all properties on the list before propigating the + failure. + + -- Joey Hess Sat, 07 Jun 2014 00:12:44 -0400 + propellor (0.6.0) unstable; urgency=medium * Docker containers now propagate DNS attributes out to the host they're diff --git a/propellor.cabal b/propellor.cabal index 350215fd..41486dd8 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -1,5 +1,5 @@ Name: propellor -Version: 0.6.0 +Version: 0.7.0 Cabal-Version: >= 1.6 License: BSD3 Maintainer: Joey Hess diff --git a/src/Propellor/Property.hs b/src/Propellor/Property.hs index c7a03765..8e419a6b 100644 --- a/src/Propellor/Property.hs +++ b/src/Propellor/Property.hs @@ -26,7 +26,8 @@ propertyList :: Desc -> [Property] -> Property propertyList desc ps = Property desc (ensureProperties ps) (combineAttrs ps) -- | Combines a list of properties, resulting in one property that --- ensures each in turn, stopping on failure. +-- ensures each in turn. Does not stop on failure; does propigate +-- overall success/failure. combineProperties :: Desc -> [Property] -> Property combineProperties desc ps = Property desc (go ps NoChange) (combineAttrs ps) where @@ -37,15 +38,6 @@ combineProperties desc ps = Property desc (go ps NoChange) (combineAttrs ps) FailedChange -> return FailedChange _ -> go ls (r <> rs) --- | Does not stop on failure (but does propigate failure at the end). -combineProperties' :: Desc -> [Property] -> Property -combineProperties' desc ps = Property desc (go ps NoChange) (combineAttrs ps) - where - go [] rs = return rs - go (l:ls) rs = do - r <- ensureProperty l - go ls (r <> rs) - -- | Combines together two properties, resulting in one property -- that ensures the first, and if the first succeeds, ensures the second. -- The property uses the description of the first property. diff --git a/src/Propellor/Property/Ssh.hs b/src/Propellor/Property/Ssh.hs index ba0311cc..061f440c 100644 --- a/src/Propellor/Property/Ssh.hs +++ b/src/Propellor/Property/Ssh.hs @@ -97,7 +97,7 @@ hostKey keytype = combineProperties desc -- | Sets up a user with a ssh private key and public key pair -- from the site's PrivData. keyImported :: SshKeyType -> UserName -> Property -keyImported keytype user = combineProperties' desc +keyImported keytype user = combineProperties desc [ property desc (install writeFile (SshPubKey keytype user) ".pub") , property desc (install writeFileProtected (SshPrivKey keytype user) "") ] -- cgit v1.2.3 From fc49d75e4fb9e8d2c7ce9d60647a26ecc030d253 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 9 Jun 2014 01:45:58 -0400 Subject: Attr is renamed to Info. --- debian/changelog | 1 + doc/todo/metapackage.mdwn | 2 +- doc/todo/ssh_hostkey_Attr.mdwn | 7 ---- doc/todo/ssh_hostkey_Info.mdwn | 7 ++++ propellor.cabal | 4 +- src/Propellor.hs | 4 +- src/Propellor/Attr.hs | 83 -------------------------------------- src/Propellor/Engine.hs | 2 +- src/Propellor/Info.hs | 83 ++++++++++++++++++++++++++++++++++++++ src/Propellor/Property.hs | 20 ++++----- src/Propellor/Property/Dns.hs | 26 ++++++------ src/Propellor/Property/Docker.hs | 32 +++++++-------- src/Propellor/Property/Hostname.hs | 2 +- src/Propellor/Types.hs | 30 +++++++------- src/Propellor/Types/Attr.hs | 65 ----------------------------- src/Propellor/Types/Info.hs | 65 +++++++++++++++++++++++++++++ 16 files changed, 217 insertions(+), 216 deletions(-) delete mode 100644 doc/todo/ssh_hostkey_Attr.mdwn create mode 100644 doc/todo/ssh_hostkey_Info.mdwn delete mode 100644 src/Propellor/Attr.hs create mode 100644 src/Propellor/Info.hs delete mode 100644 src/Propellor/Types/Attr.hs create mode 100644 src/Propellor/Types/Info.hs diff --git a/debian/changelog b/debian/changelog index 5b6cdcbc..b8db1680 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,7 @@ propellor (0.7.0) UNRELEASED; urgency=medium * combineProperties no longer stops when a property fails; now it continues trying to satisfy all properties on the list before propigating the failure. + * Attr is renamed to Info. -- Joey Hess Sat, 07 Jun 2014 00:12:44 -0400 diff --git a/doc/todo/metapackage.mdwn b/doc/todo/metapackage.mdwn index cd7bc1fd..bd14f858 100644 --- a/doc/todo/metapackage.mdwn +++ b/doc/todo/metapackage.mdwn @@ -1,5 +1,5 @@ * Should be possible to generate a metapackage of all packages that properties direct apt to install. Then any other packages can be auto-removed. This would just be a matter of storing the apt-installed - packages in an Attr. Although not removing essential and base packages + packages in to Info or somewhere. Although not removing essential and base packages could be problimatic. diff --git a/doc/todo/ssh_hostkey_Attr.mdwn b/doc/todo/ssh_hostkey_Attr.mdwn deleted file mode 100644 index 3f352543..00000000 --- a/doc/todo/ssh_hostkey_Attr.mdwn +++ /dev/null @@ -1,7 +0,0 @@ -* Either `Ssh.hostKey` should set the sshPubKey attr - (which seems hard, as attrs need to be able to be calculated without - running any IO code, and here IO is needed along with decrypting the - PrivData..), or the public key should not be stored in - the PrivData, and instead configured using the attr. - Getting the ssh host key into the attr will allow automatically - exporting it via DNS (SSHFP record) diff --git a/doc/todo/ssh_hostkey_Info.mdwn b/doc/todo/ssh_hostkey_Info.mdwn new file mode 100644 index 00000000..a7f8a66a --- /dev/null +++ b/doc/todo/ssh_hostkey_Info.mdwn @@ -0,0 +1,7 @@ +* Either `Ssh.hostKey` should set the sshPubKey info + (which seems hard, as info needs to be able to be calculated without + running any IO code, and here IO is needed along with decrypting the + PrivData..), or the public key should not be stored in + the PrivData, and instead configured using the info. + Getting the ssh host key into the info will allow automatically + exporting it via DNS (SSHFP record) diff --git a/propellor.cabal b/propellor.cabal index 41486dd8..ff361da8 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -97,7 +97,7 @@ Library Propellor.Property.SiteSpecific.GitHome Propellor.Property.SiteSpecific.JoeySites Propellor.Property.SiteSpecific.GitAnnexBuilder - Propellor.Attr + Propellor.Info Propellor.Message Propellor.PrivData Propellor.Engine @@ -106,7 +106,7 @@ Library Propellor.Types.OS Propellor.Types.Dns Other-Modules: - Propellor.Types.Attr + Propellor.Types.Info Propellor.CmdLine Propellor.SimpleSh Propellor.Property.Docker.Shim diff --git a/src/Propellor.hs b/src/Propellor.hs index e6312248..c0ef14f4 100644 --- a/src/Propellor.hs +++ b/src/Propellor.hs @@ -33,7 +33,7 @@ module Propellor ( module Propellor.Types , module Propellor.Property , module Propellor.Property.Cmd - , module Propellor.Attr + , module Propellor.Info , module Propellor.PrivData , module Propellor.Engine , module Propellor.Exception @@ -50,7 +50,7 @@ import Propellor.Property.Cmd import Propellor.PrivData import Propellor.Message import Propellor.Exception -import Propellor.Attr +import Propellor.Info import Utility.PartialPrelude as X import Utility.Process as X diff --git a/src/Propellor/Attr.hs b/src/Propellor/Attr.hs deleted file mode 100644 index 7d371d40..00000000 --- a/src/Propellor/Attr.hs +++ /dev/null @@ -1,83 +0,0 @@ -{-# LANGUAGE PackageImports #-} - -module Propellor.Attr where - -import Propellor.Types -import Propellor.Types.Attr - -import "mtl" Control.Monad.Reader -import qualified Data.Set as S -import qualified Data.Map as M -import Data.Maybe -import Data.Monoid -import Control.Applicative - -pureAttrProperty :: Desc -> Attr -> Property -pureAttrProperty desc = Property ("has " ++ desc) (return NoChange) - -askAttr :: (Attr -> Val a) -> Propellor (Maybe a) -askAttr f = asks (fromVal . f . hostAttr) - -os :: System -> Property -os system = pureAttrProperty ("Operating " ++ show system) $ - mempty { _os = Val system } - -getOS :: Propellor (Maybe System) -getOS = askAttr _os - --- | Indidate that a host has an A record in the DNS. --- --- TODO check at run time if the host really has this address. --- (Can't change the host's address, but as a sanity check.) -ipv4 :: String -> Property -ipv4 = addDNS . Address . IPv4 - --- | Indidate that a host has an AAAA record in the DNS. -ipv6 :: String -> Property -ipv6 = addDNS . Address . IPv6 - --- | 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 -alias = addDNS . CNAME . AbsDomain - -addDNS :: Record -> Property -addDNS r = pureAttrProperty (rdesc r) $ - mempty { _dns = S.singleton r } - where - rdesc (CNAME d) = unwords ["alias", ddesc d] - rdesc (Address (IPv4 addr)) = unwords ["ipv4", addr] - rdesc (Address (IPv6 addr)) = unwords ["ipv6", addr] - rdesc (MX n d) = unwords ["MX", show n, ddesc d] - rdesc (NS d) = unwords ["NS", ddesc d] - rdesc (TXT s) = unwords ["TXT", s] - rdesc (SRV x y z d) = unwords ["SRV", show x, show y, show z, ddesc d] - - ddesc (AbsDomain domain) = domain - ddesc (RelDomain domain) = domain - ddesc RootDomain = "@" - -sshPubKey :: String -> Property -sshPubKey k = pureAttrProperty ("ssh pubkey known") $ - mempty { _sshPubKey = Val k } - -getSshPubKey :: Propellor (Maybe String) -getSshPubKey = askAttr _sshPubKey - -hostMap :: [Host] -> M.Map HostName Host -hostMap l = M.fromList $ zip (map hostName l) l - -findHost :: [Host] -> HostName -> Maybe Host -findHost l hn = M.lookup hn (hostMap l) - -getAddresses :: Attr -> [IPAddr] -getAddresses = mapMaybe getIPAddr . S.toList . _dns - -hostAddresses :: HostName -> [Host] -> [IPAddr] -hostAddresses hn hosts = case hostAttr <$> findHost hosts hn of - Nothing -> [] - Just attr -> mapMaybe getIPAddr $ S.toList $ _dns attr diff --git a/src/Propellor/Engine.hs b/src/Propellor/Engine.hs index ca0f7265..a3fc0f30 100644 --- a/src/Propellor/Engine.hs +++ b/src/Propellor/Engine.hs @@ -12,7 +12,7 @@ import "mtl" Control.Monad.Reader import Propellor.Types import Propellor.Message import Propellor.Exception -import Propellor.Attr +import Propellor.Info runPropellor :: Host -> Propellor a -> IO a runPropellor host a = runReaderT (runWithHost a) host diff --git a/src/Propellor/Info.hs b/src/Propellor/Info.hs new file mode 100644 index 00000000..00f1b0e9 --- /dev/null +++ b/src/Propellor/Info.hs @@ -0,0 +1,83 @@ +{-# LANGUAGE PackageImports #-} + +module Propellor.Info where + +import Propellor.Types +import Propellor.Types.Info + +import "mtl" Control.Monad.Reader +import qualified Data.Set as S +import qualified Data.Map as M +import Data.Maybe +import Data.Monoid +import Control.Applicative + +pureInfoProperty :: Desc -> Info -> Property +pureInfoProperty desc = Property ("has " ++ desc) (return NoChange) + +askInfo :: (Info -> Val a) -> Propellor (Maybe a) +askInfo f = asks (fromVal . f . hostInfo) + +os :: System -> Property +os system = pureInfoProperty ("Operating " ++ show system) $ + mempty { _os = Val system } + +getOS :: Propellor (Maybe System) +getOS = askInfo _os + +-- | Indidate that a host has an A record in the DNS. +-- +-- TODO check at run time if the host really has this address. +-- (Can't change the host's address, but as a sanity check.) +ipv4 :: String -> Property +ipv4 = addDNS . Address . IPv4 + +-- | Indidate that a host has an AAAA record in the DNS. +ipv6 :: String -> Property +ipv6 = addDNS . Address . IPv6 + +-- | 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 +alias = addDNS . CNAME . AbsDomain + +addDNS :: Record -> Property +addDNS r = pureInfoProperty (rdesc r) $ + mempty { _dns = S.singleton r } + where + rdesc (CNAME d) = unwords ["alias", ddesc d] + rdesc (Address (IPv4 addr)) = unwords ["ipv4", addr] + rdesc (Address (IPv6 addr)) = unwords ["ipv6", addr] + rdesc (MX n d) = unwords ["MX", show n, ddesc d] + rdesc (NS d) = unwords ["NS", ddesc d] + rdesc (TXT s) = unwords ["TXT", s] + rdesc (SRV x y z d) = unwords ["SRV", show x, show y, show z, ddesc d] + + ddesc (AbsDomain domain) = domain + ddesc (RelDomain domain) = domain + ddesc RootDomain = "@" + +sshPubKey :: String -> Property +sshPubKey k = pureInfoProperty ("ssh pubkey known") $ + mempty { _sshPubKey = Val k } + +getSshPubKey :: Propellor (Maybe String) +getSshPubKey = askInfo _sshPubKey + +hostMap :: [Host] -> M.Map HostName Host +hostMap l = M.fromList $ zip (map hostName l) l + +findHost :: [Host] -> HostName -> Maybe Host +findHost l hn = M.lookup hn (hostMap l) + +getAddresses :: Info -> [IPAddr] +getAddresses = mapMaybe getIPAddr . S.toList . _dns + +hostAddresses :: HostName -> [Host] -> [IPAddr] +hostAddresses hn hosts = case hostInfo <$> findHost hosts hn of + Nothing -> [] + Just info -> mapMaybe getIPAddr $ S.toList $ _dns info diff --git a/src/Propellor/Property.hs b/src/Propellor/Property.hs index 8e419a6b..68b6f6a9 100644 --- a/src/Propellor/Property.hs +++ b/src/Propellor/Property.hs @@ -9,7 +9,7 @@ import Control.Monad.IfElse import "mtl" Control.Monad.Reader import Propellor.Types -import Propellor.Attr +import Propellor.Info import Propellor.Engine import Utility.Monad import System.FilePath @@ -23,13 +23,13 @@ property d s = Property d s mempty -- and print out the description of each as it's run. Does not stop -- on failure; does propigate overall success/failure. propertyList :: Desc -> [Property] -> Property -propertyList desc ps = Property desc (ensureProperties ps) (combineAttrs ps) +propertyList desc ps = Property desc (ensureProperties ps) (combineInfos ps) -- | Combines a list of properties, resulting in one property that -- ensures each in turn. Does not stop on failure; does propigate -- overall success/failure. combineProperties :: Desc -> [Property] -> Property -combineProperties desc ps = Property desc (go ps NoChange) (combineAttrs ps) +combineProperties desc ps = Property desc (go ps NoChange) (combineInfos ps) where go [] rs = return rs go (l:ls) rs = do @@ -68,7 +68,7 @@ flagFile' p getflagfile = adjustProperty p $ \satisfy -> do --- | Whenever a change has to be made for a Property, causes a hook -- Property to also be run, but not otherwise. onChange :: Property -> Property -> Property -p `onChange` hook = Property (propertyDesc p) satisfy (combineAttr p hook) +p `onChange` hook = Property (propertyDesc p) satisfy (combineInfo p hook) where satisfy = do r <- ensureProperty p @@ -135,7 +135,7 @@ host hn = Host hn [] mempty -- -- Can add Properties and RevertableProperties (&) :: IsProp p => Host -> p -> Host -(Host hn ps as) & p = Host hn (ps ++ [toProp p]) (as <> getAttr p) +(Host hn ps as) & p = Host hn (ps ++ [toProp p]) (as <> getInfo p) infixl 1 & @@ -149,12 +149,12 @@ infixl 1 ! adjustProperty :: Property -> (Propellor Result -> Propellor Result) -> Property adjustProperty p f = p { propertySatisfy = f (propertySatisfy p) } --- Combines the Attr of two properties. -combineAttr :: (IsProp p, IsProp q) => p -> q -> Attr -combineAttr p q = getAttr p <> getAttr q +-- Combines the Info of two properties. +combineInfo :: (IsProp p, IsProp q) => p -> q -> Info +combineInfo p q = getInfo p <> getInfo q -combineAttrs :: IsProp p => [p] -> Attr -combineAttrs = mconcat . map getAttr +combineInfos :: IsProp p => [p] -> Info +combineInfos = mconcat . map getInfo makeChange :: IO () -> Propellor Result makeChange a = liftIO a >> return MadeChange diff --git a/src/Propellor/Property/Dns.hs b/src/Propellor/Property/Dns.hs index 50ce649e..ddfcf8e6 100644 --- a/src/Propellor/Property/Dns.hs +++ b/src/Propellor/Property/Dns.hs @@ -15,7 +15,7 @@ module Propellor.Property.Dns ( import Propellor import Propellor.Types.Dns import Propellor.Property.File -import Propellor.Types.Attr +import Propellor.Types.Info import qualified Propellor.Property.Apt as Apt import qualified Propellor.Property.Service as Service import Utility.Applicative @@ -113,7 +113,7 @@ secondary hosts domain = secondaryFor (otherServers Master hosts domain) hosts d secondaryFor :: [HostName] -> [Host] -> Domain -> RevertableProperty secondaryFor masters hosts domain = RevertableProperty setup cleanup where - setup = pureAttrProperty desc (addNamedConf conf) + setup = pureInfoProperty desc (addNamedConf conf) `requires` servingZones cleanup = namedConfWritten @@ -131,7 +131,7 @@ otherServers :: DnsServerType -> [Host] -> Domain -> [HostName] otherServers wantedtype hosts domain = M.keys $ M.filter wanted $ hostMap hosts where - wanted h = case M.lookup domain (fromNamedConfMap $ _namedconf $ hostAttr h) of + wanted h = case M.lookup domain (fromNamedConfMap $ _namedconf $ hostInfo h) of Nothing -> False Just conf -> confDnsServerType conf == wantedtype && confDomain conf == domain @@ -346,7 +346,7 @@ genZone hosts zdomain soa = inzdomain = M.elems $ M.filterWithKey (\hn _ -> inDomain zdomain $ AbsDomain $ hn) m -- Each host with a hostname located in the zdomain - -- should have 1 or more IPAddrs in its Attr. + -- should have 1 or more IPAddrs in its Info. -- -- If a host lacks any IPAddr, it's probably a misconfiguration, -- so warn. @@ -355,9 +355,9 @@ genZone hosts zdomain soa = | null l = [Left $ "no IP address defined for host " ++ hostName h] | otherwise = map Right l where - attr = hostAttr h + info = hostInfo h l = zip (repeat $ AbsDomain $ hostName h) - (map Address $ getAddresses attr) + (map Address $ getAddresses info) -- Any host, whether its hostname is in the zdomain or not, -- may have cnames which are in the zdomain. The cname may even be @@ -373,10 +373,10 @@ genZone hosts zdomain soa = -- So we can just use the IPAddrs. addcnames :: Host -> [Either WarningMessage (BindDomain, Record)] addcnames h = concatMap gen $ filter (inDomain zdomain) $ - mapMaybe getCNAME $ S.toList (_dns attr) + mapMaybe getCNAME $ S.toList (_dns info) where - attr = hostAttr h - gen c = case getAddresses attr of + info = hostInfo h + gen c = case getAddresses info of [] -> [ret (CNAME c)] l -> map (ret . Address) l where @@ -386,9 +386,9 @@ genZone hosts zdomain soa = hostrecords :: Host -> [Either WarningMessage (BindDomain, Record)] hostrecords h = map Right l where - attr = hostAttr h + info = hostInfo h l = zip (repeat $ AbsDomain $ hostName h) - (S.toList $ S.filter (\r -> isNothing (getIPAddr r) && isNothing (getCNAME r)) (_dns attr)) + (S.toList $ S.filter (\r -> isNothing (getIPAddr r) && isNothing (getCNAME r)) (_dns info)) -- Simplifies the list of hosts. Remove duplicate entries. -- Also, filter out any CHAMES where the same domain has an @@ -417,10 +417,10 @@ domainHost base (AbsDomain d) where dotbase = '.':base -addNamedConf :: NamedConf -> Attr +addNamedConf :: NamedConf -> Info addNamedConf conf = mempty { _namedconf = NamedConfMap (M.singleton domain conf) } where domain = confDomain conf getNamedConf :: Propellor (M.Map Domain NamedConf) -getNamedConf = asks $ fromNamedConfMap . _namedconf . hostAttr +getNamedConf = asks $ fromNamedConfMap . _namedconf . hostInfo diff --git a/src/Propellor/Property/Docker.hs b/src/Propellor/Property/Docker.hs index fa3e2344..1521eb65 100644 --- a/src/Propellor/Property/Docker.hs +++ b/src/Propellor/Property/Docker.hs @@ -35,7 +35,7 @@ module Propellor.Property.Docker ( import Propellor import Propellor.SimpleSh -import Propellor.Types.Attr +import Propellor.Types.Info import qualified Propellor.Property.File as File import qualified Propellor.Property.Apt as Apt import qualified Propellor.Property.Docker.Shim as Shim @@ -72,9 +72,9 @@ type ContainerName = String -- > & Apt.installed {"apache2"] -- > & ... container :: ContainerName -> Image -> Host -container cn image = Host hn [] attr +container cn image = Host hn [] info where - attr = dockerAttr $ mempty { _dockerImage = Val image } + info = dockerInfo $ mempty { _dockerImage = Val image } hn = cn2hn cn cn2hn :: ContainerName -> HostName @@ -86,8 +86,8 @@ cn2hn cn = cn ++ ".docker" -- The container has its own Properties which are handled by running -- propellor inside the container. -- --- Additionally, the container can have DNS attributes, such as a CNAME. --- These become attributes of the host(s) it's docked in. +-- Additionally, the container can have DNS info, such as a CNAME. +-- These become info of the host(s) it's docked in. -- -- Reverting this property ensures that the container is stopped and -- removed. @@ -96,7 +96,7 @@ docked -> ContainerName -> RevertableProperty docked hosts cn = RevertableProperty - ((maybe id exposeDnsAttrs mhost) (go "docked" setup)) + ((maybe id exposeDnsInfos mhost) (go "docked" setup)) (go "undocked" teardown) where go desc a = property (desc ++ " " ++ cn) $ do @@ -123,9 +123,9 @@ docked hosts cn = RevertableProperty ] ] -exposeDnsAttrs :: Host -> Property -> Property -exposeDnsAttrs (Host _ _ containerattr) p = combineProperties (propertyDesc p) $ - p : map addDNS (S.toList $ _dns containerattr) +exposeDnsInfos :: Host -> Property -> Property +exposeDnsInfos (Host _ _ containerinfo) p = combineProperties (propertyDesc p) $ + p : map addDNS (S.toList $ _dns containerinfo) findContainer :: Maybe Host @@ -144,10 +144,10 @@ findContainer mhost cid cn mk = case mhost of mkContainer :: ContainerId -> Host -> Maybe Container mkContainer cid@(ContainerId hn _cn) h = Container - <$> fromVal (_dockerImage attr) - <*> pure (map (\a -> a hn) (_dockerRunParams attr)) + <$> fromVal (_dockerImage info) + <*> pure (map (\a -> a hn) (_dockerRunParams info)) where - attr = _dockerattr $ hostAttr h' + info = _dockerinfo $ hostInfo h' h' = h -- expose propellor directory inside the container & volume (localdir++":"++localdir) @@ -469,17 +469,17 @@ listImages :: IO [Image] listImages = lines <$> readProcess dockercmd ["images", "--all", "--quiet"] runProp :: String -> RunParam -> Property -runProp field val = pureAttrProperty (param) $ dockerAttr $ +runProp field val = pureInfoProperty (param) $ dockerInfo $ mempty { _dockerRunParams = [\_ -> "--"++param] } where param = field++"="++val genProp :: String -> (HostName -> RunParam) -> Property -genProp field mkval = pureAttrProperty field $ dockerAttr $ +genProp field mkval = pureInfoProperty field $ dockerInfo $ mempty { _dockerRunParams = [\hn -> "--"++field++"=" ++ mkval hn] } -dockerAttr :: DockerAttr -> Attr -dockerAttr a = mempty { _dockerattr = a } +dockerInfo :: DockerInfo -> Info +dockerInfo i = mempty { _dockerinfo = i } -- | The ContainerIdent of a container is written to -- /.propellor-ident inside it. This can be checked to see if diff --git a/src/Propellor/Property/Hostname.hs b/src/Propellor/Property/Hostname.hs index 3a6283cf..10fda040 100644 --- a/src/Propellor/Property/Hostname.hs +++ b/src/Propellor/Property/Hostname.hs @@ -3,7 +3,7 @@ module Propellor.Property.Hostname where import Propellor import qualified Propellor.Property.File as File --- | Ensures that the hostname is set to the HostAttr value. +-- | Ensures that the hostname is set to the HostInfo value. -- Configures /etc/hostname and the current hostname. -- -- A FQDN also configures /etc/hosts, with an entry for 127.0.1.1, which is diff --git a/src/Propellor/Types.hs b/src/Propellor/Types.hs index d91ce71b..383797a9 100644 --- a/src/Propellor/Types.hs +++ b/src/Propellor/Types.hs @@ -3,8 +3,8 @@ module Propellor.Types ( Host(..) - , Attr - , getAttr + , Info + , getInfo , Propellor(..) , Property(..) , RevertableProperty(..) @@ -29,21 +29,21 @@ import System.Console.ANSI import "mtl" Control.Monad.Reader import "MonadCatchIO-transformers" Control.Monad.CatchIO -import Propellor.Types.Attr +import Propellor.Types.Info import Propellor.Types.OS import Propellor.Types.Dns -- | Everything Propellor knows about a system: Its hostname, --- properties and attributes. +-- properties and other info. data Host = Host { hostName :: HostName , hostProperties :: [Property] - , hostAttr :: Attr + , hostInfo :: Info } deriving (Show) --- | Propellor's monad provides read-only access to the host it's running --- on, including its attributes. +-- | Propellor's monad provides read-only access to info about the host +-- it's running on. newtype Propellor p = Propellor { runWithHost :: ReaderT Host IO p } deriving ( Monad @@ -61,8 +61,8 @@ data Property = Property { propertyDesc :: Desc , propertySatisfy :: Propellor Result -- ^ must be idempotent; may run repeatedly - , propertyAttr :: Attr - -- ^ a property can set an attribute of the host that has the property. + , propertyInfo :: Info + -- ^ a property can add info to the host. } instance Show Property where @@ -78,15 +78,15 @@ class IsProp p where -- | Indicates that the first property can only be satisfied -- once the second one is. requires :: p -> Property -> p - getAttr :: p -> Attr + getInfo :: p -> Info instance IsProp Property where describe p d = p { propertyDesc = d } toProp p = p - getAttr = propertyAttr - x `requires` y = Property (propertyDesc x) satisfy attr + getInfo = propertyInfo + x `requires` y = Property (propertyDesc x) satisfy info where - attr = getAttr y <> getAttr x + info = getInfo y <> getInfo x satisfy = do r <- propertySatisfy y case r of @@ -101,8 +101,8 @@ instance IsProp RevertableProperty where toProp (RevertableProperty p1 _) = p1 (RevertableProperty p1 p2) `requires` y = RevertableProperty (p1 `requires` y) p2 - -- | Return the Attr of the currently active side. - getAttr (RevertableProperty p1 _p2) = getAttr p1 + -- | Return the Info of the currently active side. + getInfo (RevertableProperty p1 _p2) = getInfo p1 type Desc = String diff --git a/src/Propellor/Types/Attr.hs b/src/Propellor/Types/Attr.hs deleted file mode 100644 index 4389a4e5..00000000 --- a/src/Propellor/Types/Attr.hs +++ /dev/null @@ -1,65 +0,0 @@ -module Propellor.Types.Attr where - -import Propellor.Types.OS -import qualified Propellor.Types.Dns as Dns - -import qualified Data.Set as S -import Data.Monoid - --- | The attributes of a host. -data Attr = Attr - { _os :: Val System - , _sshPubKey :: Val String - , _dns :: S.Set Dns.Record - , _namedconf :: Dns.NamedConfMap - , _dockerattr :: DockerAttr - } - deriving (Eq, Show) - -instance Monoid Attr where - mempty = Attr mempty mempty mempty mempty mempty - mappend old new = Attr - { _os = _os old <> _os new - , _sshPubKey = _sshPubKey old <> _sshPubKey new - , _dns = _dns old <> _dns new - , _namedconf = _namedconf old <> _namedconf new - , _dockerattr = _dockerattr old <> _dockerattr new - } - -data Val a = Val a | NoVal - deriving (Eq, Show) - -instance Monoid (Val a) where - mempty = NoVal - mappend old new = case new of - NoVal -> old - _ -> new - -fromVal :: Val a -> Maybe a -fromVal (Val a) = Just a -fromVal NoVal = Nothing - -data DockerAttr = DockerAttr - { _dockerImage :: Val String - , _dockerRunParams :: [HostName -> String] - } - -instance Eq DockerAttr where - x == y = and - [ _dockerImage x == _dockerImage y - , let simpl v = map (\a -> a "") (_dockerRunParams v) - in simpl x == simpl y - ] - -instance Monoid DockerAttr where - mempty = DockerAttr mempty mempty - mappend old new = DockerAttr - { _dockerImage = _dockerImage old <> _dockerImage new - , _dockerRunParams = _dockerRunParams old <> _dockerRunParams new - } - -instance Show DockerAttr where - show a = unlines - [ "docker image " ++ show (_dockerImage a) - , "docker run params " ++ show (map (\mk -> mk "") (_dockerRunParams a)) - ] diff --git a/src/Propellor/Types/Info.hs b/src/Propellor/Types/Info.hs new file mode 100644 index 00000000..5f034492 --- /dev/null +++ b/src/Propellor/Types/Info.hs @@ -0,0 +1,65 @@ +module Propellor.Types.Info where + +import Propellor.Types.OS +import qualified Propellor.Types.Dns as Dns + +import qualified Data.Set as S +import Data.Monoid + +-- | Information about a host. +data Info = Info + { _os :: Val System + , _sshPubKey :: Val String + , _dns :: S.Set Dns.Record + , _namedconf :: Dns.NamedConfMap + , _dockerinfo :: DockerInfo + } + deriving (Eq, Show) + +instance Monoid Info where + mempty = Info mempty mempty mempty mempty mempty + mappend old new = Info + { _os = _os old <> _os new + , _sshPubKey = _sshPubKey old <> _sshPubKey new + , _dns = _dns old <> _dns new + , _namedconf = _namedconf old <> _namedconf new + , _dockerinfo = _dockerinfo old <> _dockerinfo new + } + +data Val a = Val a | NoVal + deriving (Eq, Show) + +instance Monoid (Val a) where + mempty = NoVal + mappend old new = case new of + NoVal -> old + _ -> new + +fromVal :: Val a -> Maybe a +fromVal (Val a) = Just a +fromVal NoVal = Nothing + +data DockerInfo = DockerInfo + { _dockerImage :: Val String + , _dockerRunParams :: [HostName -> String] + } + +instance Eq DockerInfo where + x == y = and + [ _dockerImage x == _dockerImage y + , let simpl v = map (\a -> a "") (_dockerRunParams v) + in simpl x == simpl y + ] + +instance Monoid DockerInfo where + mempty = DockerInfo mempty mempty + mappend old new = DockerInfo + { _dockerImage = _dockerImage old <> _dockerImage new + , _dockerRunParams = _dockerRunParams old <> _dockerRunParams new + } + +instance Show DockerInfo where + show a = unlines + [ "docker image " ++ show (_dockerImage a) + , "docker run params " ++ show (map (\mk -> mk "") (_dockerRunParams a)) + ] -- cgit v1.2.3 From a1341ccb315a98e407a25bf25411759b6f8f58d2 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 9 Jun 2014 12:29:33 -0400 Subject: propellor spin --- Makefile | 6 +++--- propellor.cabal | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 2f339a89..79852688 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ dev: build tags build: dist/setup-config if ! $(CABAL) build; then $(CABAL) configure; $(CABAL) build; fi - ln -sf dist/build/config/config propellor + ln -sf dist/build/propellor-config/propellor-config propellor deps: @if [ $$(whoami) = root ]; then apt-get --no-upgrade --no-install-recommends -y install gnupg ghc cabal-install libghc-missingh-dev libghc-ansi-terminal-dev libghc-ifelse-dev libghc-unix-compat-dev libghc-hslogger-dev libghc-network-dev libghc-quickcheck2-dev libghc-mtl-dev libghc-monadcatchio-transformers-dev; fi || true @@ -19,13 +19,13 @@ dist/setup-config: propellor.cabal install: install -d $(DESTDIR)/usr/bin $(DESTDIR)/usr/src/propellor - install -s dist/build/wrapper/wrapper $(DESTDIR)/usr/bin/propellor + install -s dist/build/propellor/propellor $(DESTDIR)/usr/bin/propellor $(CABAL) sdist cat dist/propellor-*.tar.gz | \ (cd $(DESTDIR)/usr/src/propellor && tar zx --strip-components=1) clean: - rm -rf dist Setup tags propellor propellor-wrapper privdata/local + rm -rf dist Setup tags propellor privdata/local find -name \*.o -exec rm {} \; find -name \*.hi -exec rm {} \; diff --git a/propellor.cabal b/propellor.cabal index ff361da8..2ac8a44a 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -33,7 +33,7 @@ Description: . It is configured using haskell. -Executable wrapper +Executable propellor Main-Is: wrapper.hs GHC-Options: -Wall -threaded -O0 Hs-Source-Dirs: src @@ -45,7 +45,7 @@ Executable wrapper if (! os(windows)) Build-Depends: unix -Executable config +Executable propellor-config Main-Is: config.hs GHC-Options: -Wall -threaded -O0 Hs-Source-Dirs: src -- cgit v1.2.3