From 998320c9b17cd4399c109f536b6ae6b658197a42 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 12 Feb 2015 12:50:17 -0400 Subject: [PATCH 01/15] diatom is dead --- config-joey.hs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/config-joey.hs b/config-joey.hs index f87db43..1bd558f 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -43,7 +43,6 @@ hosts = -- (o) ` , clam , orca , kite - , diatom , elephant , beaver ] ++ monsters @@ -223,16 +222,6 @@ kite = standardSystemUnhardened "kite.kitenet.net" Testing "amd64" & branchableSecondary & Dns.secondaryFor ["animx"] hosts "animx.eu.org" -diatom :: Host -diatom = standardSystem "diatom.kitenet.net" (Stable "wheezy") "amd64" - [ "dying" ] - & ipv4 "107.170.31.195" - & Ssh.hostKeys hostContext - [ (SshDsa, "ssh-dss AAAAB3NzaC1kc3MAAACBAO9tnPUT4p+9z7K6/OYuiBNHaij4Nzv5YVBih1vMl+ALz0gYAj8RWJzXmqp5buFAyfgOoLw+H9s1bBS01Sy3i07Dm6cx1fWG4RXL/E/3w1tavX99GD2bBxDBu890ebA5Tp+eFRJkS9+JwSvFiF6CP7NbVjifCagoUO56Ig048RwDAAAAFQDPY2xM3q6KwsVQliel23nrd0rV2QAAAIEAga3hj1hL00rYPNnAUzT8GAaSP62S4W68lusErH+KPbsMwFBFY/Ib1FVf8k6Zn6dZLh/HH/RtJi0JwdzPI1IFW+lwVbKfwBvhQ1lw9cH2rs1UIVgi7Wxdgfy8gEWxf+QIqn62wG+Ulf/HkWGvTrRpoJqlYRNS/gnOWj9Z/4s99koAAACBAM/uJIo2I0nK15wXiTYs/NYUZA7wcErugFn70TRbSgduIFH6U/CQa3rgHJw9DCPCQJLq7pwCnFH7too/qaK+czDk04PsgqV0+Jc7957gU5miPg50d60eJMctHV4eQ1FpwmGGfXxRBR9k2ZvikWYatYir3L6/x1ir7M0bA9IzNU45") - , (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA2QAJEuvbTmaN9ex9i9bjPhMGj+PHUYq2keIiaIImJ+8mo+yKSaGUxebG4tpuDPx6KZjdycyJt74IXfn1voGUrfzwaEY9NkqOP3v6OWTC3QeUGqDCeJ2ipslbEd9Ep9XBp+/ldDQm60D0XsIZdmDeN6MrHSbKF4fXv1bqpUoUILk=") - ] - & alias "ns2.kitenet.net" - elephant :: Host elephant = standardSystem "elephant.kitenet.net" Unstable "amd64" [ "Storage, big data, and backups, omnomnom!" @@ -265,7 +254,6 @@ elephant = standardSystem "elephant.kitenet.net" Unstable "amd64" & alias "znc.kitenet.net" & JoeySites.ircBouncer - -- I'd rather this were on diatom, but it needs unstable. & alias "kgb.kitenet.net" & JoeySites.kgbServer From fac02a6a82bb8a377f63e5e83c7afeb228bb0538 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 13 Feb 2015 15:59:50 -0400 Subject: [PATCH 02/15] propellor spin --- src/Propellor/Property/SiteSpecific/JoeySites.hs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs index 9644cb7..78751c7 100644 --- a/src/Propellor/Property/SiteSpecific/JoeySites.hs +++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs @@ -125,17 +125,6 @@ mumbleServer hosts = combineProperties hn $ props where hn = "mumble.debian.net" -obnamLowMem :: Property NoInfo -obnamLowMem = combineProperties "obnam tuned for low memory use" - [ Obnam.latestVersion - , "/etc/obnam.conf" `File.containsLines` - [ "[config]" - , "# Suggested by liw to keep Obnam memory consumption down (at some speed cost)." - , "upload-queue-size = 96" - , "lru-size = 96" - ] - ] - -- git.kitenet.net and git.joeyh.name gitServer :: [Host] -> Property HasInfo gitServer hosts = propertyList "git.kitenet.net setup" $ props @@ -282,7 +271,7 @@ gitAnnexDistributor = combineProperties "git-annex distributor, including rsync & "/etc/default/rsync" `File.containsLine` "RSYNC_ENABLE=true" `onChange` Service.running "rsync" & endpoint "/srv/web/downloads.kitenet.net/git-annex/autobuild" - & endpoint "/srv/web/downloads.kitenet.net/git-annex/autobuild/x86_64-apple-mavericks" + & endpoint "/srv/web/downloads.kitenet.net/git-annex/autobuild/x86_64-apple-yosemite" -- git-annex distribution signing key & Gpg.keyImported (Gpg.GpgKeyId "89C809CB") "joey" where From 90643c1d986438d039b14be90bc994b6ae9cf001 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 13 Feb 2015 16:00:48 -0400 Subject: [PATCH 03/15] propellor spin From be1a3a7c89ca8ea8aecb9a9748380ef840598171 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 16 Feb 2015 19:01:32 -0400 Subject: [PATCH 04/15] When running shimmed (eg in a docker container), improve process name visible in ps. --- debian/changelog | 7 +++++++ src/Propellor/Shim.hs | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index dfe3b3c..ef4b8a2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +propellor (2.1.1) UNRELEASED; urgency=medium + + * When running shimmed (eg in a docker container), + improve process name visible in ps. + + -- Joey Hess Mon, 16 Feb 2015 19:00:48 -0400 + propellor (2.1.0) unstable; urgency=medium * Additional tor properties, including support for making relays, diff --git a/src/Propellor/Shim.hs b/src/Propellor/Shim.hs index da4c96e..e1ea282 100644 --- a/src/Propellor/Shim.hs +++ b/src/Propellor/Shim.hs @@ -33,6 +33,9 @@ setup propellorbin propellorbinpath dest = checkAlreadyShimmed propellorbin $ do let linker = (dest ++) $ fromMaybe (error "cannot find ld-linux linker") $ headMaybe $ filter ("ld-linux" `isInfixOf`) libs' + let linkersym = takeDirectory linker takeFileName propellorbin + createSymbolicLink linkersym (takeFileName linker) + let gconvdir = (dest ++) $ takeDirectory $ fromMaybe (error "cannot find gconv directory") $ headMaybe $ filter ("/gconv/" `isInfixOf`) glibclibs @@ -42,7 +45,7 @@ setup propellorbin propellorbinpath dest = checkAlreadyShimmed propellorbin $ do [ shebang , "GCONV_PATH=" ++ shellEscape gconvdir , "export GCONV_PATH" - , "exec " ++ unwords (map shellEscape $ linker : linkerparams) ++ + , "exec " ++ unwords (map shellEscape $ linkersym : linkerparams) ++ " " ++ shellEscape (fromMaybe propellorbin propellorbinpath) ++ " \"$@\"" ] modifyFileMode shim (addModes executeModes) From 5b56a416c17be95ad5b54a886a29ef3b6a72d223 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 19 Feb 2015 18:40:50 -0400 Subject: [PATCH 05/15] endpoint --- src/Propellor/Property/SiteSpecific/JoeySites.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs index 78751c7..005f12d 100644 --- a/src/Propellor/Property/SiteSpecific/JoeySites.hs +++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs @@ -272,6 +272,7 @@ gitAnnexDistributor = combineProperties "git-annex distributor, including rsync `onChange` Service.running "rsync" & endpoint "/srv/web/downloads.kitenet.net/git-annex/autobuild" & endpoint "/srv/web/downloads.kitenet.net/git-annex/autobuild/x86_64-apple-yosemite" + & endpoint "/srv/web/downloads.kitenet.net/git-annex/autobuild/windows" -- git-annex distribution signing key & Gpg.keyImported (Gpg.GpgKeyId "89C809CB") "joey" where From fa7656f74356ca1f85f225cbdf2f6c1f56fe788f Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 25 Feb 2015 14:58:40 -0400 Subject: [PATCH 06/15] Add shebang to cron.daily etc files. --- debian/changelog | 1 + src/Propellor/Property/Cron.hs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index ef4b8a2..b31c7ed 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ propellor (2.1.1) UNRELEASED; urgency=medium * When running shimmed (eg in a docker container), improve process name visible in ps. + * Add shebang to cron.daily etc files. -- Joey Hess Mon, 16 Feb 2015 19:00:48 -0400 diff --git a/src/Propellor/Property/Cron.hs b/src/Propellor/Property/Cron.hs index fd365c8..2a28a15 100644 --- a/src/Propellor/Property/Cron.hs +++ b/src/Propellor/Property/Cron.hs @@ -30,7 +30,10 @@ data Times job :: Desc -> Times -> UserName -> FilePath -> String -> Property NoInfo job desc times user cddir command = combineProperties ("cronned " ++ desc) [ cronjobfile `File.hasContent` - [ "# Generated by propellor" + [ case times of + Times _ -> "" + _ -> "#!/bin/sh\nset -e" + , "# Generated by propellor" , "" , "SHELL=/bin/sh" , "PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin" From e8b0e7c6ca34365710d1066984bd3d7026621b70 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 27 Feb 2015 18:55:51 -0400 Subject: [PATCH 07/15] propellor spin --- config-joey.hs | 5 +- debian/changelog | 3 +- propellor.cabal | 2 +- src/Propellor/Property/Tor.hs | 108 ++++++++++++++++++---------------- 4 files changed, 64 insertions(+), 54 deletions(-) diff --git a/config-joey.hs b/config-joey.hs index 1bd558f..bd1a496 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -84,8 +84,9 @@ clam = standardSystem "clam.kitenet.net" Unstable "amd64" & Ssh.randomHostKeys & Apt.unattendedUpgrades & Network.ipv6to4 - & Tor.named "kite1" Tor.isRelay' - & Postfix.satellite + & Tor.isRelay + & Tor.named "kite1" + & Tor.bandwidthRate "128 kibibytes" & Docker.configured & Docker.garbageCollected `period` Daily diff --git a/debian/changelog b/debian/changelog index b31c7ed..47e683c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,9 @@ -propellor (2.1.1) UNRELEASED; urgency=medium +propellor (2.2.0) UNRELEASED; urgency=medium * When running shimmed (eg in a docker container), improve process name visible in ps. * Add shebang to cron.daily etc files. + * Some changes to tor configuration, minor API change. -- Joey Hess Mon, 16 Feb 2015 19:00:48 -0400 diff --git a/propellor.cabal b/propellor.cabal index 41520ba..0615457 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -1,5 +1,5 @@ Name: propellor -Version: 2.1.0 +Version: 2.2.0 Cabal-Version: >= 1.6 License: BSD3 Maintainer: Joey Hess diff --git a/src/Propellor/Property/Tor.hs b/src/Propellor/Property/Tor.hs index 8176e64..bf03d63 100644 --- a/src/Propellor/Property/Tor.hs +++ b/src/Propellor/Property/Tor.hs @@ -5,6 +5,7 @@ import qualified Propellor.Property.File as File import qualified Propellor.Property.Apt as Apt import qualified Propellor.Property.Service as Service import Utility.FileMode +import Utility.DataUnits import System.Posix.Files import Data.Char @@ -17,60 +18,36 @@ type NodeName = String -- -- Uses port 443 isBridge :: Property NoInfo -isBridge = isBridge' [] - -isBridge' :: [String] -> Property NoInfo -isBridge' extraconfig = server config +isBridge = configured + [ ("BridgeRelay", "1") + , ("Exitpolicy", "reject *:*") + , ("ORPort", "443") + ] `describe` "tor bridge" - where - config = - [ "BridgeRelay 1" - , "Exitpolicy reject *:*" - , "ORPort 443" - ] ++ extraconfig + `requires` server -- | Sets up a tor relay. -- -- Uses port 443 isRelay :: Property NoInfo -isRelay = isRelay' [] - -isRelay' :: [String] -> Property NoInfo -isRelay' extraconfig = server config +isRelay = configured + [ ("BridgeRelay", "0") + , ("Exitpolicy", "reject *:*") + , ("ORPort", "443") + ] `describe` "tor relay" - where - config = - [ "BridgeRelay 0" - , "Exitpolicy reject *:*" - , "ORPort 443" - ] ++ extraconfig + `requires` server --- | Converts a property like isBridge' or isRelay' to be a named --- node, with a known private key. +-- | 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. --- --- The base property can be used to start out and then upgraded to --- a named property later. -named :: NodeName -> ([String] -> Property NoInfo) -> Property HasInfo -named n basep = p `describe` (getDesc p ++ " " ++ n) +named :: NodeName -> Property HasInfo +named n = configured [("Nickname", n')] + `describe` ("tor node named " ++ n') + `requires` torPrivKey (Context ("tor " ++ n)) where - p = basep ["Nickname " ++ saneNickname n] - `requires` torPrivKey (Context ("tor " ++ n)) - --- | A tor server (bridge, relay, or exit) --- Don't use if you just want to run tor for personal use. -server :: [String] -> Property NoInfo -server extraconfig = setup - `requires` Apt.installed ["tor", "ntp"] - `describe` "tor server" - where - setup = mainConfig `File.hasContent` config - `onChange` restarted - config = - [ "SocksPort 0" - ] ++ extraconfig + n' = saneNickname n torPrivKey :: Context -> Property HasInfo torPrivKey context = f `File.hasPrivContent` context @@ -80,15 +57,47 @@ torPrivKey context = f `File.hasPrivContent` context where f = "/var/lib/tor/keys/secret_id_key" +-- | A tor server (bridge, relay, or exit) +-- Don't use if you just want to run tor for personal use. +server :: Property NoInfo +server = configured [("SocksPort", "0")] + `requires` Apt.installed ["tor", "ntp"] + `describe` "tor server" + +-- | 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 NoInfo +configured settings = File.fileProperty "tor configured" go mainConfig + `onChange` restarted + where + ks = map fst settings + go ls = map toconfig $ + filter (\(k, _) -> k `notElem` ks) (map fromconfig ls) + ++ settings + toconfig (k, v) = k ++ " " ++ v + fromconfig = separate (== ' ') + +type BwLimit = String + +-- | Limit incoming and outgoing traffic to the specified +-- amount, per second. +-- +-- For example, "30 kibibytes" is the minimum limit for a useful relay. +bandwidthRate :: BwLimit -> Property NoInfo +bandwidthRate s = case readSize dataUnits s of + Just sz -> configured [("BandwidthRate", show sz ++ " bytes")] + Nothing -> property ("unable to parse " ++ s) noChange + hiddenServiceAvailable :: HiddenServiceName -> Int -> Property NoInfo hiddenServiceAvailable hn port = hiddenServiceHostName prop where - prop = mainConfig `File.containsLines` - [ unwords ["HiddenServiceDir", varLib hn] - , unwords ["HiddenServicePort", show port, "127.0.0.1:" ++ show port] + prop = configured + [ ("HiddenServiceDir", varLib hn) + , ("HiddenServicePort", unwords [show port, "127.0.0.1:" ++ show port]) ] `describe` "hidden service available" - `onChange` Service.reloaded "tor" hiddenServiceHostName p = adjustPropertySatisfy p $ \satisfy -> do r <- satisfy h <- liftIO $ readFile (varLib hn "hostname") @@ -96,12 +105,11 @@ hiddenServiceAvailable hn port = hiddenServiceHostName prop return r hiddenService :: HiddenServiceName -> Int -> Property NoInfo -hiddenService hn port = mainConfig `File.containsLines` - [ unwords ["HiddenServiceDir", varLib hn] - , unwords ["HiddenServicePort", show port, "127.0.0.1:" ++ show port] +hiddenService hn port = configured + [ ("HiddenServiceDir", varLib hn) + , ("HiddenServicePort", unwords [show port, "127.0.0.1:" ++ show port]) ] `describe` unwords ["hidden service available:", hn, show port] - `onChange` restarted hiddenServiceData :: IsContext c => HiddenServiceName -> c -> Property HasInfo hiddenServiceData hn context = combineProperties desc From f0a4e642c490c4a91e62788e0c46f192b402e7f0 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 27 Feb 2015 19:01:11 -0400 Subject: [PATCH 08/15] propellor spin --- src/Propellor/Property/Tor.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Propellor/Property/Tor.hs b/src/Propellor/Property/Tor.hs index bf03d63..27c9761 100644 --- a/src/Propellor/Property/Tor.hs +++ b/src/Propellor/Property/Tor.hs @@ -9,6 +9,7 @@ import Utility.DataUnits import System.Posix.Files import Data.Char +import Data.List type HiddenServiceName = String @@ -73,7 +74,7 @@ configured settings = File.fileProperty "tor configured" go mainConfig `onChange` restarted where ks = map fst settings - go ls = map toconfig $ + go ls = sort $ map toconfig $ filter (\(k, _) -> k `notElem` ks) (map fromconfig ls) ++ settings toconfig (k, v) = k ++ " " ++ v From d67d59a25a951f236ee9bde74fd29ed773b3dd86 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 27 Feb 2015 19:14:20 -0400 Subject: [PATCH 09/15] propellor spin --- config-joey.hs | 2 +- src/Propellor/Property/Tor.hs | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/config-joey.hs b/config-joey.hs index bd1a496..f9f4eaa 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -86,7 +86,7 @@ clam = standardSystem "clam.kitenet.net" Unstable "amd64" & Network.ipv6to4 & Tor.isRelay & Tor.named "kite1" - & Tor.bandwidthRate "128 kibibytes" + & Tor.bandwidthRate (Tor.PerMonth "400 GB") & Docker.configured & Docker.garbageCollected `period` Daily diff --git a/src/Propellor/Property/Tor.hs b/src/Propellor/Property/Tor.hs index 27c9761..3a0926b 100644 --- a/src/Propellor/Property/Tor.hs +++ b/src/Propellor/Property/Tor.hs @@ -80,15 +80,24 @@ configured settings = File.fileProperty "tor configured" go mainConfig toconfig (k, v) = k ++ " " ++ v fromconfig = separate (== ' ') -type BwLimit = String +data BwLimit + = PerSecond String + | PerDay String + | PerMonth String -- | Limit incoming and outgoing traffic to the specified --- amount, per second. +-- amount each. -- --- For example, "30 kibibytes" is the minimum limit for a useful relay. +-- For example, PerSecond "30 kibibytes" is the minimum limit +-- for a useful relay. bandwidthRate :: BwLimit -> Property NoInfo -bandwidthRate s = case readSize dataUnits s of - Just sz -> configured [("BandwidthRate", show sz ++ " bytes")] +bandwidthRate (PerSecond s) = bandwidthRate' s 1 +bandwidthRate (PerDay s) = bandwidthRate' s (24*60*60) +bandwidthRate (PerMonth s) = bandwidthRate' s (31*24*60*60) + +bandwidthRate' :: String -> Integer -> Property NoInfo +bandwidthRate' s divby = case readSize dataUnits s of + Just sz -> configured [("BandwidthRate", show (sz `div` divby) ++ " bytes")] Nothing -> property ("unable to parse " ++ s) noChange hiddenServiceAvailable :: HiddenServiceName -> Int -> Property NoInfo From 1a62575d3dc8ce703705de08ccd27b4b034a3388 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 27 Feb 2015 19:17:42 -0400 Subject: [PATCH 10/15] propellor spin --- src/Propellor/Property/Tor.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Propellor/Property/Tor.hs b/src/Propellor/Property/Tor.hs index 3a0926b..7a49082 100644 --- a/src/Propellor/Property/Tor.hs +++ b/src/Propellor/Property/Tor.hs @@ -97,7 +97,9 @@ bandwidthRate (PerMonth s) = bandwidthRate' s (31*24*60*60) bandwidthRate' :: String -> Integer -> Property NoInfo bandwidthRate' s divby = case readSize dataUnits s of - Just sz -> configured [("BandwidthRate", show (sz `div` divby) ++ " bytes")] + Just sz -> let v = show (sz `div` divby) ++ " bytes" + in configured [("BandwidthRate", v)] + `describe` ("tor BandwidthRate " ++ v) Nothing -> property ("unable to parse " ++ s) noChange hiddenServiceAvailable :: HiddenServiceName -> Int -> Property NoInfo From dc03e317b40d640e6501be0fce3e32bc29699fbb Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 28 Feb 2015 12:20:03 -0400 Subject: [PATCH 11/15] Propellor now builds itself without needing the Makefile. --- Makefile | 19 +++++++++-------- debian/changelog | 1 + propellor.cabal | 1 + src/Propellor/Bootstrap.hs | 42 ++++++++++++++++++++++++++++++++++++++ src/Propellor/CmdLine.hs | 35 ++++++++++++++++--------------- src/wrapper.hs | 12 +++++------ 6 files changed, 78 insertions(+), 32 deletions(-) create mode 100644 src/Propellor/Bootstrap.hs diff --git a/Makefile b/Makefile index 414f674..d706d8e 100644 --- a/Makefile +++ b/Makefile @@ -9,18 +9,10 @@ run: deps build dev: build tags -build: dist/setup-config - @if ! $(CABAL) build; then $(CABAL) configure; $(CABAL) build; fi - @ln -sf dist/build/propellor-config/propellor-config propellor - deps: @if [ $$(whoami) = root ]; then apt-get --no-upgrade --no-install-recommends -y install $(DEBDEPS) || (apt-get update && apt-get --no-upgrade --no-install-recommends -y install $(DEBDEPS)); fi || true @if [ $$(whoami) = root ]; then apt-get --no-upgrade --no-install-recommends -y install libghc-async-dev || (cabal update; cabal install async); fi || true -dist/setup-config: propellor.cabal - @if [ "$(CABAL)" = ./Setup ]; then ghc --make Setup; fi - @$(CABAL) configure - install: propellor.1 install -d $(DESTDIR)/usr/bin $(DESTDIR)/usr/src/propellor install -s dist/build/propellor/propellor $(DESTDIR)/usr/bin/propellor @@ -56,3 +48,14 @@ hackage: @cabal upload dist/*.tar.gz .PHONY: tags + +# The rules below are only used when bootstrapping new propellor +# installations; propellor contains equivilant haksell code. + +build: dist/setup-config + @if ! $(CABAL) build; then $(CABAL) configure; $(CABAL) build; fi + @ln -sf dist/build/propellor-config/propellor-config propellor + +dist/setup-config: propellor.cabal + @if [ "$(CABAL)" = ./Setup ]; then ghc --make Setup; fi + @$(CABAL) configure diff --git a/debian/changelog b/debian/changelog index 47e683c..ca7452a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,7 @@ propellor (2.2.0) UNRELEASED; urgency=medium improve process name visible in ps. * Add shebang to cron.daily etc files. * Some changes to tor configuration, minor API change. + * Propellor now builds itself without needing the Makefile. -- Joey Hess Mon, 16 Feb 2015 19:00:48 -0400 diff --git a/propellor.cabal b/propellor.cabal index 0615457..ff37003 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -128,6 +128,7 @@ Library Propellor.Types.Result Propellor.Types.CmdLine Other-Modules: + Propellor.Bootstrap Propellor.Git Propellor.Gpg Propellor.Spin diff --git a/src/Propellor/Bootstrap.hs b/src/Propellor/Bootstrap.hs new file mode 100644 index 0000000..7ad4bb1 --- /dev/null +++ b/src/Propellor/Bootstrap.hs @@ -0,0 +1,42 @@ +module Propellor.Bootstrap ( + buildPropellor +) where + +import Propellor +import Utility.SafeCommand + +import System.Posix.Files + +buildPropellor :: IO () +buildPropellor = unlessM (actionMessage "Propellor build" build) $ + errorMessage "Propellor build failed!" + +-- Build propellor using cabal, and symlink propellor to where cabal +-- leaves the built binary. +-- +-- For speed, only runs cabal configure when it's not been run before. +-- If the build fails cabal may need to have configure re-run. +build :: IO Bool +build = catchBoolIO $ do + make "dist/setup-config" ["propellor.cabal"] $ + cabal ["configure"] + unlessM (cabal ["build"]) $ do + void $ cabal ["configure"] + unlessM (cabal ["build"]) $ + error "cabal build failed" + nukeFile "propellor" + createSymbolicLink "dist/build/propellor-config/propellor-config" "propellor" + return True + +make :: FilePath -> [FilePath] -> IO Bool -> IO () +make dest srcs builder = do + dt <- getmtime dest + st <- mapM getmtime srcs + when (dt == Nothing || any (> dt) st) $ + unlessM builder $ + error $ "failed to make " ++ dest + where + getmtime = catchMaybeIO . getModificationTime + +cabal :: [String] -> IO Bool +cabal = boolSystem "cabal" . map Param diff --git a/src/Propellor/CmdLine.hs b/src/Propellor/CmdLine.hs index 15dc09c..9d7d0d9 100644 --- a/src/Propellor/CmdLine.hs +++ b/src/Propellor/CmdLine.hs @@ -12,6 +12,7 @@ import qualified Network.BSD import Propellor import Propellor.Gpg import Propellor.Git +import Propellor.Bootstrap import Propellor.Spin import Propellor.Types.CmdLine import qualified Propellor.Property.Docker as Docker @@ -31,6 +32,7 @@ usage h = hPutStrLn h $ unlines , " propellor --edit field context" , " propellor --list-fields" , " propellor --merge" + , " propellor --build" ] usageError :: [String] -> IO a @@ -128,19 +130,16 @@ unknownhost h hosts = errorMessage $ unlines ] buildFirst :: CmdLine -> IO () -> IO () -buildFirst cmdline next = ifM (doesFileExist "Makefile") - ( do - oldtime <- getmtime - ifM (actionMessage "Propellor build" $ boolSystem "make" [Param "build"]) - ( do - newtime <- getmtime - if newtime == oldtime - then next - else void $ boolSystem "./propellor" [Param "--continue", Param (show cmdline)] - , errorMessage "Propellor build failed!" - ) - , next - ) +buildFirst cmdline next = do + oldtime <- getmtime + buildPropellor + newtime <- getmtime + if newtime == oldtime + then next + else void $ boolSystem "./propellor" + [ Param "--continue" + , Param (show cmdline) + ] where getmtime = catchMaybeIO $ getModificationTime "propellor" @@ -155,10 +154,12 @@ updateFirst cmdline next = ifM hasOrigin (updateFirst' cmdline next, next) updateFirst' :: CmdLine -> IO () -> IO () updateFirst' cmdline next = ifM fetchOrigin - ( ifM (actionMessage "Propellor build" $ boolSystem "make" [Param "build"]) - ( void $ boolSystem "./propellor" [Param "--continue", Param (show cmdline)] - , errorMessage "Propellor build failed!" - ) + ( do + buildPropellor + void $ boolSystem "./propellor" + [ Param "--continue" + , Param (show cmdline) + ] , next ) diff --git a/src/wrapper.hs b/src/wrapper.hs index 304e833..034eb2b 100644 --- a/src/wrapper.hs +++ b/src/wrapper.hs @@ -15,6 +15,7 @@ module Main where import Propellor.Message +import Propellor.Bootstrap import Utility.UserInfo import Utility.Monad import Utility.Process @@ -91,13 +92,10 @@ wrapper args propellordir propellorbin = do warnoutofdate propellordir True buildruncfg = do changeWorkingDirectory propellordir - ifM (boolSystem "make" [Param "build"]) - ( do - putStrLn "" - putStrLn "" - chain - , error "Propellor build failed." - ) + buildPropellor + putStrLn "" + putStrLn "" + chain chain = do (_, _, _, pid) <- createProcess (proc propellorbin args) exitWith =<< waitForProcess pid From e26c232d154eb1a6b6eca631414ed7526993f88c Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 28 Feb 2015 12:50:28 -0400 Subject: [PATCH 12/15] avoid using the makefile when bootstrapping with --spin --- Makefile | 15 ++++------- debian/changelog | 3 ++- src/Propellor/Bootstrap.hs | 53 +++++++++++++++++++++++++++++++++++++- src/Propellor/Spin.hs | 5 ++-- 4 files changed, 62 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index d706d8e..acd70a5 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,12 @@ CABAL?=cabal -DEBDEPS=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 - -# this target is provided to keep old versions of the propellor cron job -# working, and will eventually be removed -run: deps build +# this target is provided (and is first) to keep old versions of the +# propellor cron job working, and will eventually be removed +run: build ./propellor dev: build tags -deps: - @if [ $$(whoami) = root ]; then apt-get --no-upgrade --no-install-recommends -y install $(DEBDEPS) || (apt-get update && apt-get --no-upgrade --no-install-recommends -y install $(DEBDEPS)); fi || true - @if [ $$(whoami) = root ]; then apt-get --no-upgrade --no-install-recommends -y install libghc-async-dev || (cabal update; cabal install async); fi || true - install: propellor.1 install -d $(DESTDIR)/usr/bin $(DESTDIR)/usr/src/propellor install -s dist/build/propellor/propellor $(DESTDIR)/usr/bin/propellor @@ -50,7 +44,8 @@ hackage: .PHONY: tags # The rules below are only used when bootstrapping new propellor -# installations; propellor contains equivilant haksell code. +# installations and building packages; propellor contains equivilant +# haskell code that it uses to re-build itself. build: dist/setup-config @if ! $(CABAL) build; then $(CABAL) configure; $(CABAL) build; fi diff --git a/debian/changelog b/debian/changelog index ca7452a..5dc849d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,7 +4,8 @@ propellor (2.2.0) UNRELEASED; urgency=medium improve process name visible in ps. * Add shebang to cron.daily etc files. * Some changes to tor configuration, minor API change. - * Propellor now builds itself without needing the Makefile. + * Propellor now builds itself, and gets its build dependencies installed + when deploying to a new host, without needing the Makefile. -- Joey Hess Mon, 16 Feb 2015 19:00:48 -0400 diff --git a/src/Propellor/Bootstrap.hs b/src/Propellor/Bootstrap.hs index 7ad4bb1..0b3072b 100644 --- a/src/Propellor/Bootstrap.hs +++ b/src/Propellor/Bootstrap.hs @@ -1,11 +1,62 @@ module Propellor.Bootstrap ( - buildPropellor + bootstrapPropellorCommand, + installGitCommand, + buildPropellor, ) where import Propellor import Utility.SafeCommand import System.Posix.Files +import Data.List + +type ShellCommand = String + +-- Shell command line to build propellor, used when bootstrapping on a new +-- host. Should be run inside the propellor source tree, and will install +-- all necessary build dependencies. +bootstrapPropellorCommand :: ShellCommand +bootstrapPropellorCommand = "if ! test -x ./propellor; then " ++ go ++ "; fi" + where + go = intercalate " && " + [ depsCommand + , buildCommand + ] + +buildCommand :: ShellCommand +buildCommand = intercalate " && " + [ "cabal configure" + , "cabal build" + , "ln -sf dist/build/propellor-config/propellor-config propellor" + ] + +depsCommand :: ShellCommand +depsCommand = "(" ++ aptinstall debdeps ++ " || (apt-get update && " ++ aptinstall debdeps ++ ")) || true;" + ++ "(" ++ aptinstall ["libghc-async-dev"] ++ " || (cabal update; cabal install async)) || true" + where + aptinstall ps = "apt-get --no-upgrade --no-install-recommends -y install " ++ unwords ps + + -- This is the same build deps listed in debian/control. + debdeps = + [ "gnupg" + , "ghc" + , "cabal-install" + -- async is not available in debian stable + -- , "libghc-async-dev" + , "libghc-missingh-dev" + , "libghc-hslogger-dev" + , "libghc-unix-compat-dev" + , "libghc-ansi-terminal-dev" + , "libghc-ifelse-dev" + , "libghc-network-dev" + , "libghc-quickcheck2-dev" + , "libghc-mtl-dev" + , "libghc-monadcatchio-transformers-dev" + ] + + +installGitCommand :: ShellCommand +installGitCommand = "if ! git --version >/dev/null; then apt-get update && apt-get --no-install-recommends --no-upgrade -y install git; fi" buildPropellor :: IO () buildPropellor = unlessM (actionMessage "Propellor build" build) $ diff --git a/src/Propellor/Spin.hs b/src/Propellor/Spin.hs index 5063145..f55f297 100644 --- a/src/Propellor/Spin.hs +++ b/src/Propellor/Spin.hs @@ -24,6 +24,7 @@ import Propellor.PrivData.Paths import Propellor.Git import Propellor.Ssh import Propellor.Gpg +import Propellor.Bootstrap import Propellor.Types.CmdLine import qualified Propellor.Shim as Shim import Utility.FileMode @@ -69,7 +70,7 @@ spin target relay hst = do probecmd = intercalate " ; " [ "if [ ! -d " ++ localdir ++ "/.git ]" , "then (" ++ intercalate " && " - [ "if ! git --version || ! make --version; then apt-get update && apt-get --no-install-recommends --no-upgrade -y install git make; fi" + [ installGitCommand , "echo " ++ toMarked statusMarker (show NeedGitClone) ] ++ ") || echo " ++ toMarked statusMarker (show NeedPrecompiled) , "else " ++ updatecmd @@ -78,7 +79,7 @@ spin target relay hst = do updatecmd = intercalate " && " [ "cd " ++ localdir - , "if ! test -x ./propellor; then make deps build; fi" + , bootstrapPropellorCommand , if viarelay then "./propellor --continue " ++ shellEscape (show (Relay target)) From 42c1106ea0926be314e3d7d40b953f8d93950483 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 28 Feb 2015 12:57:20 -0400 Subject: [PATCH 13/15] support installing build deps using pure cabal, rather than debian packages for non-debian systems --- src/Propellor/Bootstrap.hs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Propellor/Bootstrap.hs b/src/Propellor/Bootstrap.hs index 0b3072b..4534083 100644 --- a/src/Propellor/Bootstrap.hs +++ b/src/Propellor/Bootstrap.hs @@ -31,11 +31,15 @@ buildCommand = intercalate " && " ] depsCommand :: ShellCommand -depsCommand = "(" ++ aptinstall debdeps ++ " || (apt-get update && " ++ aptinstall debdeps ++ ")) || true;" - ++ "(" ++ aptinstall ["libghc-async-dev"] ++ " || (cabal update; cabal install async)) || true" +depsCommand = + "(" ++ aptinstall debdeps ++ " || (apt-get update && " ++ aptinstall debdeps ++ ")) && " + ++ "(" ++ aptinstall ["libghc-async-dev"] ++ " || (" ++ cabalinstall ["async"] ++ ")) || " + ++ "(" ++ cabalinstall ["--only-dependencies"] ++ ")" where aptinstall ps = "apt-get --no-upgrade --no-install-recommends -y install " ++ unwords ps + cabalinstall ps = "cabal update; cabal install " ++ unwords ps + -- This is the same build deps listed in debian/control. debdeps = [ "gnupg" From 52721921f67e0646c9581b6b0e535ffdb44a9eb6 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 28 Feb 2015 13:04:57 -0400 Subject: [PATCH 14/15] propellor spin From ec64af82f0f87df939abb6dd0727628a2cd88906 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 28 Feb 2015 13:07:21 -0400 Subject: [PATCH 15/15] propellor spin