diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,24 @@
+propellor (5.1.0) unstable; urgency=medium
+
+  [ Sean Whitton ]
+  * File.isSymlinkedTo now revertable. (minor API change)
+  * Sbuild module changes:
+    - Type of Sbuild.built changed to accept additional properties to be
+      ensured inside schroots. (API change)
+      See the suggested usage in module's documentation for new syntax.
+    - Drop Sbuild.installed, Sbuild.builtFor, Sbuild.updated,
+      Sbuild.updatedFor. (API change)
+      Use Sbuild.built instead.  See suggested usage in module's documentation.
+    - Propellor no longer sets up apt proxies in sbuild chroots automatically.
+      Instead, pass the new Sbuild.useHostProxy to Sbuild.built to have
+      Propellor propagate the host's Apt proxy configuration into the chroot.
+      See suggested usage in module's documentation.
+    - Internally, Propellor no longer invokes sbuild-createchroot(1) to build
+      schroots.
+    - Update documentation.
+
+ -- Joey Hess <id@joeyh.name>  Thu, 23 Nov 2017 10:38:16 -0400
+
 propellor (5.0.0) unstable; urgency=medium
 
   * Debootstrap.built now supports bootstrapping chroots for foreign
diff --git a/debian/changelog b/debian/changelog
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,24 @@
+propellor (5.1.0) unstable; urgency=medium
+
+  [ Sean Whitton ]
+  * File.isSymlinkedTo now revertable. (minor API change)
+  * Sbuild module changes:
+    - Type of Sbuild.built changed to accept additional properties to be
+      ensured inside schroots. (API change)
+      See the suggested usage in module's documentation for new syntax.
+    - Drop Sbuild.installed, Sbuild.builtFor, Sbuild.updated,
+      Sbuild.updatedFor. (API change)
+      Use Sbuild.built instead.  See suggested usage in module's documentation.
+    - Propellor no longer sets up apt proxies in sbuild chroots automatically.
+      Instead, pass the new Sbuild.useHostProxy to Sbuild.built to have
+      Propellor propagate the host's Apt proxy configuration into the chroot.
+      See suggested usage in module's documentation.
+    - Internally, Propellor no longer invokes sbuild-createchroot(1) to build
+      schroots.
+    - Update documentation.
+
+ -- Joey Hess <id@joeyh.name>  Thu, 23 Nov 2017 10:38:16 -0400
+
 propellor (5.0.0) unstable; urgency=medium
 
   * Debootstrap.built now supports bootstrapping chroots for foreign
diff --git a/propellor.cabal b/propellor.cabal
--- a/propellor.cabal
+++ b/propellor.cabal
@@ -1,5 +1,5 @@
 Name: propellor
-Version: 5.0.0
+Version: 5.1.0
 Cabal-Version: >= 1.20
 License: BSD2
 Maintainer: Joey Hess <id@joeyh.name>
diff --git a/src/Propellor/Engine.hs b/src/Propellor/Engine.hs
--- a/src/Propellor/Engine.hs
+++ b/src/Propellor/Engine.hs
@@ -102,7 +102,7 @@
 			`catchIO` const alreadyrunning
 		return l
 	unlock = closeFd
-	alreadyrunning = error "Propellor is already running on this host!"
+	alreadyrunning = giveup "Propellor is already running on this host!"
 
 -- | Chains to a propellor sub-Process, forwarding its output on to the
 -- display, except for the last line which is a Result.
diff --git a/src/Propellor/Property/Apt.hs b/src/Propellor/Property/Apt.hs
--- a/src/Propellor/Property/Apt.hs
+++ b/src/Propellor/Property/Apt.hs
@@ -501,12 +501,16 @@
 
 -- | Set apt's proxy
 proxy :: Url -> Property (HasInfo + DebianLike)
-proxy u = tightenTargets $
-	proxyInfo `before` proxyConfig `describe` desc
+proxy u = setInfoProperty (proxy' u) (proxyInfo u)
   where
-	proxyInfo = pureInfoProperty desc (InfoVal (HostAptProxy u))
-	proxyConfig = "/etc/apt/apt.conf.d/20proxy" `File.hasContent`
+	proxyInfo = toInfo . InfoVal . HostAptProxy
+
+proxy' :: Url -> Property DebianLike
+proxy' u = tightenTargets $
+	"/etc/apt/apt.conf.d/20proxy" `File.hasContent`
 		[ "Acquire::HTTP::Proxy \"" ++ u ++ "\";" ]
+		`describe` desc
+  where
 	desc = (u ++ " apt proxy selected")
 
 -- | Cause apt to proxy downloads via an apt cacher on localhost
diff --git a/src/Propellor/Property/File.hs b/src/Propellor/Property/File.hs
--- a/src/Propellor/Property/File.hs
+++ b/src/Propellor/Property/File.hs
@@ -126,18 +126,30 @@
 
 -- | Creates or atomically updates a symbolic link.
 --
--- Does not overwrite regular files or directories.
-isSymlinkedTo :: FilePath -> LinkTarget -> Property UnixLike
-link `isSymlinkedTo` (LinkTarget target) = property desc $
-	go =<< (liftIO $ tryIO $ getSymbolicLinkStatus link)
+-- Revert to ensure no symlink is present.
+--
+-- Does not overwrite or delete regular files or directories.
+isSymlinkedTo :: FilePath -> LinkTarget -> RevertableProperty UnixLike UnixLike
+link `isSymlinkedTo` (LinkTarget target) = linked <!> notLinked
   where
-	desc = link ++ " is symlinked to " ++ target
+	linked = property (link ++ " is symlinked to " ++ target) $
+		go =<< getLinkStatus
+
 	go (Right stat) =
 		if isSymbolicLink stat
 			then checkLink
 			else nonSymlinkExists
 	go (Left _) = makeChange $ createSymbolicLink target link
 
+	notLinked = property (link ++ "does not exist as a symlink") $
+		stop =<< getLinkStatus
+
+	stop (Right stat) =
+		if isSymbolicLink stat
+			then makeChange $ nukeFile link
+			else nonSymlinkExists
+	stop (Left _) = noChange
+
 	nonSymlinkExists = do
 		warningMessage $ link ++ " exists and is not a symlink"
 		return FailedChange
@@ -147,6 +159,8 @@
 			then noChange
 			else makeChange updateLink
 	updateLink = createSymbolicLink target `viaStableTmp` link
+
+	getLinkStatus = liftIO $ tryIO $ getSymbolicLinkStatus link
 
 -- | Ensures that a file is a copy of another (regular) file.
 isCopyOf :: FilePath -> FilePath -> Property UnixLike
diff --git a/src/Propellor/Property/Firejail.hs b/src/Propellor/Property/Firejail.hs
--- a/src/Propellor/Property/Firejail.hs
+++ b/src/Propellor/Property/Firejail.hs
@@ -26,6 +26,6 @@
 	`requires` installed
 	`describe` unwords ("firejail jailed":ps)
 
-jailed' :: String -> Property UnixLike
+jailed' :: String -> RevertableProperty UnixLike UnixLike
 jailed' p = ("/usr/local/bin" </> p)
 	`File.isSymlinkedTo` File.LinkTarget "/usr/bin/firejail"
diff --git a/src/Propellor/Property/Machine.hs b/src/Propellor/Property/Machine.hs
--- a/src/Propellor/Property/Machine.hs
+++ b/src/Propellor/Property/Machine.hs
@@ -30,7 +30,7 @@
 -- > sheeva = host "sheeva.example.com" $ props
 -- > 	& osDebian Unstable ARMEL
 -- > 	& marvell_SheevaPlug Marvell_SheevaPlug_SDCard
--- >	& hasPartiton
+-- >	& hasPartition
 -- >		( partition EXT4
 -- > 		`mountedAt` "/"
 -- >		`addFreeSpace` MegaBytes 2048
diff --git a/src/Propellor/Property/Sbuild.hs b/src/Propellor/Property/Sbuild.hs
--- a/src/Propellor/Property/Sbuild.hs
+++ b/src/Propellor/Property/Sbuild.hs
@@ -6,31 +6,38 @@
 
 Build and maintain schroots for use with sbuild.
 
-For convenience we set up several enhancements, such as ccache and
-eatmydata.  This means we have to make several assumptions:
+For convenience we set up several enhancements, such as ccache and eatmydata.
+This means we have to make several assumptions:
 
-1. you want to build for a Debian release strictly newer than squeeze,
-or for a Buntish release newer than or equal to trusty
+1. you want to build for a Debian release strictly newer than squeeze, or for a
+Buntish release newer than or equal to trusty
 
 2. if you want to build for Debian stretch or newer, you have sbuild 0.70.0 or
-newer (there is a backport to jessie)
+newer
 
-The latter is due to the migration from GnuPG v1 to GnuPG v2.1 in
-Debian stretch, which older sbuild can't handle.
+The latter is due to the migration from GnuPG v1 to GnuPG v2.1 in Debian
+stretch, which older sbuild can't handle.
 
 Suggested usage in @config.hs@:
 
->  & Apt.installed ["piuparts", "autopkgtest", "lintian"]
->  & Sbuild.builtFor (System (Debian Linux Unstable) X86_32) Sbuild.UseCcache
->  & Sbuild.updatedFor (System (Debian Linux Unstable) X86_32) `period` Weekly 1
->  & Sbuild.usableBy (User "spwhitton")
->  & Schroot.overlaysInTmpfs
+>  mybox = host "mybox.example.com" $ props
+>  	& osDebian (Stable "stretch") X86_64
+>  	& Apt.useLocalCacher
+>  	& sidSchrootBuilt
+>  	& Sbuild.usableBy (User "spwhitton")
+>  	& Schroot.overlaysInTmpfs
+>    where
+>  	sidSchrootBuilt = Sbuild.built Sbuild.UseCcache $ props
+>  		& osDebian Unstable X86_32
+>  		& Sbuild.update `period` Weekly (Just 1)
+>  		& Sbuild.useHostProxy mybox
 
 If you are using sbuild older than 0.70.0, you also need:
 
 >  & Sbuild.keypairGenerated
 
-In @~/.sbuildrc@ (sbuild 0.71.0 or newer):
+To take advantage of the piuparts and autopkgtest support, add to your
+@~/.sbuildrc@ (assumes sbuild 0.71.0 or newer):
 
 >  $piuparts_opts = [
 >      '--no-eatmydata',
@@ -41,40 +48,17 @@
 >
 >  $autopkgtest_root_args = "";
 >  $autopkgtest_opts = ["--", "schroot", "%r-%a-sbuild"];
-
-We use @sbuild-createchroot(1)@ to create a chroot to the
-specification of @sbuild-setup(7)@.  This avoids running propellor
-inside the chroot to set it up.  While that approach is flexible, a
-propellor spin pulls in a lot of dependencies.  This could defeat
-using sbuild to determine if you've included all necessary build
-dependencies in your source package control file.
-
-Nevertheless, the chroot that @sbuild-createchroot(1)@ creates might not meet
-your needs.  For example, you might need to enable apt's https support.  In that
-case you can do something like this in @config.hs@:
-
->  & Sbuild.built (System (Debian Linux Unstable) X86_32) `before` mySetup
->    where
->  	mySetup = Chroot.provisioned myChroot
->  	myChroot = Chroot.debootstrapped
->  		 	Debootstrap.BuilddD "/srv/chroot/unstable-i386"
->  		-- the extra configuration you need:
->  		& Apt.installed ["apt-transport-https"]
 -}
 
--- Also see the --setup-only option of sbuild-createchroot
-
 module Propellor.Property.Sbuild (
 	-- * Creating and updating sbuild schroots
-	SbuildSchroot(..),
 	UseCcache(..),
 	built,
-	updated,
-	builtFor,
-	updatedFor,
+	-- * Properties for use inside sbuild schroots
+	update,
+	useHostProxy,
 	-- * Global sbuild configuration
 	-- blockNetwork,
-	installed,
 	keypairGenerated,
 	keypairInsecurelyGenerated,
 	usableBy,
@@ -82,157 +66,125 @@
 ) where
 
 import Propellor.Base
+import Propellor.Types.Core
 import Propellor.Types.Info
 import Propellor.Property.Debootstrap (extractSuite)
-import Propellor.Property.Chroot.Util
 import qualified Propellor.Property.Apt as Apt
 import qualified Propellor.Property.Ccache as Ccache
+import qualified Propellor.Property.Chroot as Chroot
 import qualified Propellor.Property.ConfFile as ConfFile
+import qualified Propellor.Property.Debootstrap as Debootstrap
 import qualified Propellor.Property.File as File
 -- import qualified Propellor.Property.Firewall as Firewall
 import qualified Propellor.Property.Schroot as Schroot
 import qualified Propellor.Property.Reboot as Reboot
 import qualified Propellor.Property.User as User
 import Utility.FileMode
-import Utility.Split
 
 import Data.List
 
-type Suite = String
-
--- | An sbuild schroot, such as would be listed by @schroot -l@
---
--- Parts of the sbuild toolchain cannot distinguish between schroots with both
--- the same suite and the same architecture, so neither do we
-data SbuildSchroot = SbuildSchroot Suite Architecture
-
-instance ConfigurableValue SbuildSchroot where
-	val (SbuildSchroot suite arch) = suite ++ "-" ++ architectureToDebianArchString arch
-
 -- | Whether an sbuild schroot should use ccache during builds
 --
 -- ccache is generally useful but it breaks building some packages.  This data
 -- types allows you to toggle it on and off for particular schroots.
 data UseCcache = UseCcache | NoCcache
 
--- | Build and configure a schroot for use with sbuild using a distribution's
--- standard mirror
+-- | Build and configure a schroot for use with sbuild
 --
--- This function is a convenience wrapper around 'built', allowing the user to
--- identify the schroot and distribution using the 'System' type
-builtFor :: System -> UseCcache -> RevertableProperty DebianLike UnixLike
-builtFor sys cc = go <!> deleted
+-- The second parameter should specify, at a minimum, the operating system for
+-- the schroot.  This is usually done using a property like 'osDebian'
+built
+	:: UseCcache
+	-> Props metatypes
+	-> RevertableProperty (HasInfo + DebianLike) Linux
+built cc ps = case schrootSystem ps of
+	Nothing -> emitError
+	Just s@(System _ arch) -> case extractSuite s of
+		Nothing -> emitError
+		Just suite -> built' cc ps suite
+			(architectureToDebianArchString arch)
   where
-	go = Apt.withMirror goDesc $ \u -> property' goDesc $ \w ->
-		case schrootFromSystem sys of
-			Just s  -> ensureProperty w $
-				setupRevertableProperty $ built s u cc
-			_ -> errorMessage
-				("don't know how to debootstrap " ++ show sys)
-	deleted = property' ("no sbuild schroot for " ++ show sys) $
-		\w -> case schrootFromSystem sys of
-			Just s  -> ensureProperty w $
-				undoRevertableProperty $ built s "dummy" cc
-			Nothing -> noChange
-	goDesc = "sbuild schroot for " ++ show sys
+	schrootSystem :: Props metatypes -> Maybe System
+	schrootSystem (Props ps') = fromInfoVal . fromInfo $
+		mconcat (map getInfo ps')
 
--- | Build and configure a schroot for use with sbuild
-built :: SbuildSchroot -> Apt.Url -> UseCcache -> RevertableProperty DebianLike UnixLike
-built s@(SbuildSchroot suite arch) mirror cc =
-	((go `before` enhancedConf)
-	`requires` ccacheMaybePrepared cc
-	`requires` installed
-	`requires` overlaysKernel
-	`requires` cleanupOldConfig)
-	<!> deleted
+	emitError :: RevertableProperty (HasInfo + DebianLike) Linux
+	emitError = impossible theError <!> impossible theError
+	theError = "sbuild schroot does not specify suite and/or architecture"
+
+built'
+	:: UseCcache
+	-> Props metatypes
+	-> String
+	-> String
+	-> RevertableProperty (HasInfo + DebianLike) Linux
+built' cc (Props ps) suite arch = provisioned <!> deleted
   where
-	go :: Property DebianLike
-	go = check (isUnpopulated (schrootRoot s) <||> ispartial) $
-		property' ("built sbuild schroot for " ++ val s) make
-	make w = do
-		de <- liftIO standardPathEnv
-		let params = Param <$>
-			[ "--arch=" ++ architectureToDebianArchString arch
-			, "--chroot-suffix=-propellor"
-			, "--include=eatmydata,ccache"
-			, suite
-			, schrootRoot s
-			, mirror
-			]
-		ifM (liftIO $
-			boolSystemEnv "sbuild-createchroot" params (Just de))
-			( ensureProperty w $ fixConfFile s
-			, return FailedChange
-			)
+	provisioned :: Property (HasInfo + DebianLike)
+	provisioned = combineProperties desc $ props
+		& cleanupOldConfig
+		& overlaysKernel
+		& preReqsInstalled
+		& ccacheMaybePrepared cc
+		& Chroot.provisioned schroot
+		& conf suite arch
+	  where
+		desc = "built sbuild schroot for " ++ suiteArch
+
 	-- TODO we should kill any sessions still using the chroot
 	-- before destroying it (as suggested by sbuild-destroychroot)
-	deleted = check (not <$> isUnpopulated (schrootRoot s)) $
-		property ("no sbuild schroot for " ++ val s) $ do
-			liftIO $ removeChroot $ schrootRoot s
-			liftIO $ nukeFile
-				("/etc/sbuild/chroot" </> val s ++ "-sbuild")
-			makeChange $ nukeFile (schrootConf s)
-
-	enhancedConf =
-		combineProperties ("enhanced schroot conf for " ++ val s) $ props
-			& aliasesLine
-			-- set up an apt proxy/cacher
-			& proxyCacher
-			-- enable ccache and eatmydata for speed
-			& ConfFile.containsIniSetting (schrootConf s)
-				( val s ++ "-sbuild"
-				, "command-prefix"
-				, intercalate "," commandPrefix
-				)
+	deleted :: Property Linux
+	deleted = combineProperties desc $ props
+		! Chroot.provisioned schroot
+		! compatSymlink
+		& File.notPresent schrootConf
+	  where
+		desc = "no sbuild schroot for " ++ suiteArch
 
-	-- set the apt proxy inside the chroot.  If the host has an apt proxy
-	-- set, assume that it does some sort of caching.  Otherwise, set up a
-	-- local apt-cacher-ng instance
-	--
-	-- (if we didn't assume that the apt proxy does some sort of caching,
-	-- we'd need to complicate the Apt.HostAptProxy type to indicate whether
-	-- the proxy caches, and if it doesn't, set up apt-cacher-ng as an
-	-- intermediary proxy between the chroot's apt and the Apt.HostAptProxy
-	-- proxy.  This complexity is more likely to cause problems than help
-	-- anyone)
-	proxyCacher :: Property DebianLike
-	proxyCacher = property' "set schroot apt proxy" $ \w -> do
-		proxyInfo <- getProxyInfo
-		ensureProperty w $ case proxyInfo of
-			Just (Apt.HostAptProxy u) -> setChrootProxy u
-			Nothing -> (Apt.serviceInstalledRunning "apt-cacher-ng"
-				`before` setChrootProxy "http://localhost:3142")
+	conf suite' arch' = combineProperties "sbuild config file" $ props
+		& pair "description" (suite' ++ "/" ++ arch' ++ " autobuilder")
+		& pair "groups" "root,sbuild"
+		& pair "root-groups" "root,sbuild"
+		& pair "profile" "sbuild"
+		& pair "type" "directory"
+		& pair "directory" schrootRoot
+		& unionTypeOverlay
+		& aliasesLine
+		& pair "command-prefix" (intercalate "," commandPrefix)
 	  where
-		getProxyInfo :: Propellor (Maybe Apt.HostAptProxy)
-		getProxyInfo = fromInfoVal <$> askInfo
-		setChrootProxy :: Apt.Url -> Property DebianLike
-		setChrootProxy u = tightenTargets $ File.hasContent
-			(schrootRoot s </> "etc/apt/apt.conf.d/20proxy")
-			[ "Acquire::HTTP::Proxy \"" ++ u ++ "\";" ]
+		pair k v = ConfFile.containsIniSetting schrootConf
+			(suiteArch ++ "-sbuild", k, v)
+		unionTypeOverlay :: Property DebianLike
+		unionTypeOverlay = property' "add union-type = overlay" $ \w ->
+			Schroot.usesOverlays >>= \usesOverlays ->
+				if usesOverlays
+				then ensureProperty w $
+					pair "union-type" "overlay"
+				else noChange
 
+	compatSymlink = File.isSymlinkedTo
+		("/etc/sbuild/chroot" </> suiteArch ++ "-sbuild")
+		(File.LinkTarget schrootRoot)
+
 	-- if we're building a sid chroot, add useful aliases
 	-- In order to avoid more than one schroot getting the same aliases, we
 	-- only do this if the arch of the chroot equals the host arch.
 	aliasesLine :: Property UnixLike
 	aliasesLine = property' "maybe set aliases line" $ \w ->
-		sidHostArchSchroot s >>= \isSidHostArchSchroot ->
+		sidHostArchSchroot suite arch >>= \isSidHostArchSchroot ->
 			if isSidHostArchSchroot
 			then ensureProperty w $
-				ConfFile.containsIniSetting
-					(schrootConf s)
-					( val s ++ "-sbuild"
+				ConfFile.containsIniSetting schrootConf
+					( suiteArch ++ "-sbuild"
 					, "aliases"
 					, aliases
 					)
 			else return NoChange
 
-	-- If the user has indicated that this host should use
+	-- if the user has indicated that this host should use
 	-- union-type=overlay schroots, we need to ensure that we have rebooted
-	-- to a kernel supporting OverlayFS before we execute
-	-- sbuild-setupchroot(1).  Otherwise, sbuild-setupchroot(1) will fail to
-	-- add the union-type=overlay line to the schroot config.
-	-- (We could just add that line ourselves, but then sbuild wouldn't work
-	-- for the user, so we might as well do the reboot for them.)
+	-- to a kernel supporting OverlayFS.  Otherwise, executing sbuild(1)
+	-- will fail.
 	overlaysKernel :: Property DebianLike
 	overlaysKernel = property' "reboot for union-type=overlay" $ \w ->
 		Schroot.usesOverlays >>= \usesOverlays ->
@@ -249,22 +201,27 @@
 				check (doesFileExist fstab)
 				(File.lacksLine fstab aptCacheLine)
 			void $ liftIO . tryIO $ removeDirectoryRecursive profile
-			void $ liftIO $ nukeFile (schrootPiupartsConf s)
+			void $ liftIO $ nukeFile schrootPiupartsConf
 			-- assume this did nothing
 			noChange
 	  where
 		fstab = "/etc/schroot/sbuild/fstab"
 		profile = "/etc/schroot/piuparts"
+		schrootPiupartsConf = "/etc/schroot/chroot.d"
+			</> suiteArch ++ "-piuparts-propellor"
 
-	-- A failed debootstrap run will leave a debootstrap directory;
-	-- recover by deleting it and trying again.
-	ispartial = ifM (doesDirectoryExist (schrootRoot s </> "debootstrap"))
-		( do
-			removeChroot $ schrootRoot s
-			return True
-		, return False
-		)
+	-- the schroot itself
+	schroot = Chroot.debootstrapped Debootstrap.BuilddD
+			schrootRoot (Props schrootProps)
+	schrootProps =
+		ps ++ [toChildProperty Apt.stdSourcesList
+		, toChildProperty $ Apt.installed ["eatmydata", "ccache"]]
 
+	-- static values
+	suiteArch = suite ++ "-" ++ arch
+	schrootRoot = "/srv/chroot" </> suiteArch
+	schrootConf = "/etc/schroot/chroot.d"
+		</> suiteArch ++ "-sbuild-propellor"
 	aliases = intercalate ","
 		[ "sid"
 		-- if the user wants to build for experimental, they would use
@@ -277,10 +234,9 @@
 		, "UNRELEASED"
 		-- the following is for dgit compatibility:
 		, "UNRELEASED-"
-			++ architectureToDebianArchString arch
+			++ arch
 			++ "-sbuild"
 		]
-
 	commandPrefix = case cc of
 		UseCcache -> "/var/cache/ccache-sbuild/sbuild-setup":base
 		_ -> base
@@ -289,72 +245,41 @@
 
 -- | Ensure that an sbuild schroot's packages and apt indexes are updated
 --
--- This function is a convenience wrapper around 'updated', allowing the user to
--- identify the schroot using the 'System' type
-updatedFor :: System -> Property DebianLike
-updatedFor system = property' ("updated sbuild schroot for " ++ show system) $
-	\w -> case schrootFromSystem system of
-		Just s  -> ensureProperty w $ updated s
-		Nothing -> errorMessage
-			("don't know how to debootstrap " ++ show system)
-
--- | Ensure that an sbuild schroot's packages and apt indexes are updated
-updated :: SbuildSchroot -> Property DebianLike
-updated s@(SbuildSchroot suite arch) =
-	check (doesDirectoryExist (schrootRoot s)) $ go
-	`describe` ("updated schroot for " ++ val s)
-	`requires` installed
-  where
-	go :: Property DebianLike
-	go = tightenTargets $ cmdProperty
-		"sbuild-update" ["-udr", suite ++ "-" ++ architectureToDebianArchString arch]
-		`assume` MadeChange
+-- This replaces use of sbuild-update(1).
+update :: Property DebianLike
+update = Apt.update `before` Apt.upgrade `before` Apt.autoRemove
 
--- Find the conf file that sbuild-createchroot(1) made when we passed it
--- --chroot-suffix=propellor, and edit and rename such that it is as if we
--- passed --chroot-suffix=sbuild (the default).  Replace the random suffix with
--- 'propellor'.
---
--- We had to pass --chroot-suffix=propellor in order that we can find a unique
--- config file for the schroot we just built, despite the random suffix.
+-- | Ensure that an sbuild schroot uses the host's Apt proxy.
 --
--- The properties in this module only permit the creation of one chroot for a
--- given suite and architecture, so we don't need the suffix to be random.
-fixConfFile :: SbuildSchroot -> Property UnixLike
-fixConfFile s@(SbuildSchroot suite arch) =
-	property' ("schroot for " ++ val s ++ " config file fixed") $ \w -> do
-		confs <- liftIO $ dirContents dir
-		let old = concat $ filter (tempPrefix `isPrefixOf`) confs
-		liftIO $ moveFile old new
-		liftIO $ moveFile
-			("/etc/sbuild/chroot" </> val s ++ "-propellor")
-			("/etc/sbuild/chroot" </> val s ++ "-sbuild")
-		ensureProperty w $
-			File.fileProperty "replace dummy suffix" (map munge) new
+-- This property is standardly used when the host has 'Apt.useLocalCacher'.
+useHostProxy :: Host -> Property DebianLike
+useHostProxy h = property' "use host's apt proxy" $ \w ->
+	-- Note that we can't look at getProxyInfo outside the property,
+	-- as that would loop, but it's ok to look at it inside the
+	-- property. Thus the slightly strange construction here.
+	case getProxyInfo of
+		Just (Apt.HostAptProxy u) -> ensureProperty w (Apt.proxy' u)
+		Nothing -> noChange
   where
-	new = schrootConf s
-	dir = takeDirectory new
-	tempPrefix = dir </> suite ++ "-" ++ architectureToDebianArchString arch ++ "-propellor-"
-	munge = replace "-propellor]" "-sbuild]"
-
+	getProxyInfo = fromInfoVal . fromInfo . hostInfo $ h
 
 aptCacheLine :: String
 aptCacheLine = "/var/cache/apt/archives /var/cache/apt/archives none rw,bind 0 0"
 
--- | Ensure that sbuild is installed
-installed :: Property DebianLike
-installed = Apt.installed ["sbuild"]
+-- | Ensure that sbuild and associated utilities are installed
+preReqsInstalled :: Property DebianLike
+preReqsInstalled = Apt.installed ["piuparts", "autopkgtest", "lintian", "sbuild"]
 
 -- | Add an user to the sbuild group in order to use sbuild
 usableBy :: User -> Property DebianLike
-usableBy u = User.hasGroup u (Group "sbuild") `requires` installed
+usableBy u = User.hasGroup u (Group "sbuild") `requires` preReqsInstalled
 
 -- | Generate the apt keys needed by sbuild
 --
 -- You only need this if you are using sbuild older than 0.70.0.
 keypairGenerated :: Property DebianLike
 keypairGenerated = check (not <$> doesFileExist secKeyFile) $ go
-	`requires` installed
+	`requires` preReqsInstalled
 	-- Work around Debian bug #792100 which is present in Jessie.
 	-- Since this is a harmless mkdir, don't actually check the OS
 	`requires` File.dirExists "/root/.gnupg"
@@ -454,12 +379,12 @@
 userConfig :: User -> Property DebianLike
 userConfig user@(User u) = go
 	`requires` usableBy user
-	`requires` Apt.installed ["piuparts", "autopkgtest", "lintian"]
+	`requires` preReqsInstalled
   where
 	go :: Property DebianLike
 	go = property' ("~/.sbuildrc for " ++ u) $ \w -> do
-    		h <- liftIO (User.homedir user)
-    		ensureProperty w $ File.hasContent (h </> ".sbuildrc")
+		h <- liftIO (User.homedir user)
+		ensureProperty w $ File.hasContent (h </> ".sbuildrc")
 			[ "$run_lintian = 1;"
 			, ""
 			, "$run_piuparts = 1;"
@@ -477,22 +402,6 @@
 
 -- ==== utility functions ====
 
-schrootFromSystem :: System -> Maybe SbuildSchroot
-schrootFromSystem system@(System _ arch) =
-	extractSuite system
-	>>= \suite -> return $ SbuildSchroot suite arch
-
-schrootRoot :: SbuildSchroot -> FilePath
-schrootRoot (SbuildSchroot s a) = "/srv/chroot" </> s ++ "-" ++ architectureToDebianArchString a
-
-schrootConf :: SbuildSchroot -> FilePath
-schrootConf (SbuildSchroot s a) =
-	"/etc/schroot/chroot.d" </> s ++ "-" ++ architectureToDebianArchString a ++ "-sbuild-propellor"
-
-schrootPiupartsConf :: SbuildSchroot -> FilePath
-schrootPiupartsConf (SbuildSchroot s a) =
-	"/etc/schroot/chroot.d" </> s ++ "-" ++ architectureToDebianArchString a ++ "-piuparts-propellor"
-
 -- Determine whether a schroot is
 --
 -- (i)  Debian sid, and
@@ -501,10 +410,11 @@
 -- This is the "sid host arch schroot".  It is considered the default schroot
 -- for sbuild builds, so we add useful aliases that work well with the suggested
 -- ~/.sbuildrc given in the haddock
-sidHostArchSchroot :: SbuildSchroot -> Propellor Bool
-sidHostArchSchroot (SbuildSchroot suite arch) = do
+sidHostArchSchroot :: String -> String -> Propellor Bool
+sidHostArchSchroot suite arch = do
 	maybeOS <- getOS
 	return $ case maybeOS of
 		Nothing -> False
 		Just (System _ hostArch) ->
-			suite == "unstable" && hostArch == arch
+			let hostArch' = architectureToDebianArchString hostArch
+			in suite == "unstable" && hostArch' == arch
diff --git a/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs b/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs
--- a/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs
+++ b/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs
@@ -177,13 +177,10 @@
 armAutoBuilder suite arch flavor =
 	propertyList "arm git-annex autobuilder" $ props
 		& standardAutoBuilder suite arch flavor
-		& buildDepsNoHaskellLibs
+		& buildDepsApt
 		-- Works around ghc crash with parallel builds on arm.
 		& (homedir </> ".cabal" </> "config")
 			`File.lacksLine` "jobs: $ncpus"
-		-- Install patched haskell packages for portability to
-		-- arm NAS's using old kernel versions.
-		& haskellPkgsInstalled "linux"
 
 androidAutoBuilderContainer :: Times -> TimeOut -> Systemd.Container
 androidAutoBuilderContainer crontimes timeout =
diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs
--- a/src/Propellor/Property/SiteSpecific/JoeySites.hs
+++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs
@@ -595,19 +595,16 @@
 		[ "#!/bin/sh"
 		, "# deployed with propellor"
 		, "set -e"
-		, "pass=$HOME/.pine-password"
-		, "if [ ! -e $pass ]; then"
-		, "\ttouch $pass"
-		, "fi"
-		, "chmod 600 $pass"
-		, "exec alpine -passfile $pass \"$@\""
+		, "exec alpine \"$@\""
 		]
 		`onChange` (pinescript `File.mode`
 			combineModes (readModes ++ executeModes))
 		`describe` "pine wrapper script"
+	-- Make pine use dovecot pipe to read maildir.
 	& "/etc/pine.conf" `File.hasContent`
 		[ "# deployed with propellor"
-		, "inbox-path={localhost/novalidate-cert/NoRsh}inbox"
+		, "inbox-path={localhost}inbox"
+		, "rsh-command=/usr/lib/dovecot/imap"
 		]
 		`describe` "pine configured to use local imap server"
 
@@ -912,7 +909,7 @@
 homePowerMonitor :: IsContext c => User -> c -> (SshKeyType, Ssh.PubKeyText) -> Property (HasInfo + DebianLike)
 homePowerMonitor user ctx sshkey = propertyList "home power monitor" $ props
 	& Apache.installed
-	& Apt.installed ["python", "python-pymodbus", "rrdtool"]
+	& Apt.installed ["python", "python-pymodbus", "rrdtool", "rsync"]
 	& File.ownerGroup "/var/www/html" user (userGroup user)
 	& Git.cloned user "git://git.kitenet.net/joey/homepower" d Nothing
 	& buildpoller
