Recent changes to this wiki:

add news item for propellor 4.0.3
diff --git a/doc/news/version_4.0.2.mdwn b/doc/news/version_4.0.2.mdwn
deleted file mode 100644
index b955c57..0000000
--- a/doc/news/version_4.0.2.mdwn
+++ /dev/null
@@ -1,12 +0,0 @@
-propellor 4.0.2 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Apt.mirror can be used to set the preferred apt mirror of a host,
-     overriding the default CDN. This info is used by
-     Apt.stdSourcesList and Sbuild.builtFor.
-     Thanks, Sean Whitton.
-   * Property.Partition: Update kpartx output parser, as its output format
-     changed around version 0.6. Both output formats are supported now.
-   * Fix bug when using setContainerProps with a chroot that prevented
-     properties added to a chroot that way from being seen when propellor
-     was running inside the chroot. This affected disk image creation, and
-     possibly other things that use chroots."""]]
\ No newline at end of file
diff --git a/doc/news/version_4.0.3.mdwn b/doc/news/version_4.0.3.mdwn
new file mode 100644
index 0000000..eb46728
--- /dev/null
+++ b/doc/news/version_4.0.3.mdwn
@@ -0,0 +1,6 @@
+propellor 4.0.3 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Added Fstab.listed, Fstab.swap, and Mount.swapOn properties.
+     Thanks, Daniel Brooks.
+   * Added Propellor.Property.Bootstrap, which can be used to make
+     disk images contain their own installation of propellor."""]]
\ No newline at end of file

Added a comment
diff --git a/doc/forum/Work_on_OS_X/comment_4_74b579d4d590432b6bd236ccb929cc11._comment b/doc/forum/Work_on_OS_X/comment_4_74b579d4d590432b6bd236ccb929cc11._comment
new file mode 100644
index 0000000..d386c1b
--- /dev/null
+++ b/doc/forum/Work_on_OS_X/comment_4_74b579d4d590432b6bd236ccb929cc11._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="joelmccracken"
+ avatar="http://cdn.libravatar.org/avatar/45175015b9eb3dd3f6c740b3fe920fed"
+ subject="comment 4"
+ date="2017-04-20T02:23:06Z"
+ content="""
+So, it turns out that yes, root is a thing on os x... but it is complicated. I'm going to put what I learned here because I think it will be useful, at least for telling folks how to use propellor on os x.
+
+1. Enable the root account. Steps are here: https://support.apple.com/en-us/HT204012
+2. password-authentication as root is disabled -- if you try to `ssh root@localhost`, it wont work. you need a key pair. 
+3. use su/sudo to install a public key (probably at `.ssh/id_rsa.pub`) to roots authorized_keys. adapted from: https://discussions.apple.com/thread/4078360?start=0&tstart=0
+4. copy the the pub file to authorized keys: `sudo cp /Users/joel/.ssh/id_rsa.pub /var/root/.ssh/authorized_keys`
+5. you should now be able to `ssh root@localhost` without a password.
+
+I'm not super sure that this is even the best way forward, but lets get this working first, then we'll see.
+"""]]

response
diff --git a/doc/forum/Work_on_OS_X/comment_3_294f4783522a8e4887793aac921ee546._comment b/doc/forum/Work_on_OS_X/comment_3_294f4783522a8e4887793aac921ee546._comment
new file mode 100644
index 0000000..ed654d3
--- /dev/null
+++ b/doc/forum/Work_on_OS_X/comment_3_294f4783522a8e4887793aac921ee546._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2017-04-18T00:08:13Z"
+ content="""
+Yes, this is the place. Or you can email me directly, but I prefer to keep
+discussions public.
+
+`propellor --spin` needs a way to run commands as root on the remote host.
+If ssh as root on OSX is not allowed, it would need a way to get to a user
+who can get root, and it would be very annoying if a password needed to be
+entered since each `propellor --spin` actually makes several ssh connections to
+the remote host. Anything that works within these constraints would be ok.
+"""]]

Added a comment
diff --git a/doc/forum/Work_on_OS_X/comment_2_00b20c240fc13bed6dc54e5b985b41e2._comment b/doc/forum/Work_on_OS_X/comment_2_00b20c240fc13bed6dc54e5b985b41e2._comment
new file mode 100644
index 0000000..aa33c85
--- /dev/null
+++ b/doc/forum/Work_on_OS_X/comment_2_00b20c240fc13bed6dc54e5b985b41e2._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="joelmccracken"
+ avatar="http://cdn.libravatar.org/avatar/45175015b9eb3dd3f6c740b3fe920fed"
+ subject="comment 2"
+ date="2017-04-17T17:47:30Z"
+ content="""
+Sounds good. I contacted the person you linked to, have not heard back yet. 
+
+
+
+The first issue I ran into is that propellor wants to connect to \"root@<hostname>\", and it doesn't look like this is configurable.
+Would you accept a patch to make this configurable?
+
+Additionally, is this the best place to ask questions about what you would/would not accept?
+
+Thank you!!!
+"""]]

response
diff --git a/doc/forum/Work_on_OS_X/comment_1_6d7d5b89f1de9604718f7973e4b3eeb1._comment b/doc/forum/Work_on_OS_X/comment_1_6d7d5b89f1de9604718f7973e4b3eeb1._comment
new file mode 100644
index 0000000..4eac206
--- /dev/null
+++ b/doc/forum/Work_on_OS_X/comment_1_6d7d5b89f1de9604718f7973e4b3eeb1._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2017-04-13T21:36:20Z"
+ content="""
+I got a patch some years back to make propellor compile on OSX.
+I merged it. You might want to get in touch with its author, as
+he may be doing something with propellor on OSX.
+<https://github.com/tittoassini/propellor>
+
+Anyway, I'd probably merge OSX patches, if they were not super
+intrusive. And I don't see why it would be, as propellor already supports
+FreeBSD.
+
+Since `Property` is parameterized by the operating systems it
+supports, it should be easy to start by only porting the core parts
+of propellor, and then port over individual Properties one by one as
+needed. See the commits for the recent FreeBSD port for a nice walkthough
+of the changes you'll want to make.
+"""]]

diff --git a/doc/forum/Work_on_OS_X.mdwn b/doc/forum/Work_on_OS_X.mdwn
new file mode 100644
index 0000000..e3c5fd6
--- /dev/null
+++ b/doc/forum/Work_on_OS_X.mdwn
@@ -0,0 +1,5 @@
+I'm interested in using Propellor on OS X. I understand that it is not supported though.
+
+Is there anyone doing this? If it was developed, would support for OS X be merged upstream?
+
+Thanks!

done
diff --git a/debian/changelog b/debian/changelog
index dcbe0a3..70aa139 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,6 +2,8 @@ propellor (4.0.3) UNRELEASED; urgency=medium
 
   * Added Fstab.listed, Fstab.swap, and Mount.swapOn properties.
     Thanks, Daniel Brooks.
+  * Added Propellor.Property.Bootstrap, which can be used to make
+    disk images contain their own installation of propellor.
 
  -- Joey Hess <id@joeyh.name>  Thu, 06 Apr 2017 19:40:12 -0400
 
diff --git a/doc/todo/property_to_install_propellor.mdwn b/doc/todo/property_to_install_propellor.mdwn
index 25db819..184977f 100644
--- a/doc/todo/property_to_install_propellor.mdwn
+++ b/doc/todo/property_to_install_propellor.mdwn
@@ -12,3 +12,5 @@ Should support:
 Much of this is already implemented, in non-Property form, in
 Propellor.Bootstrap, but will need adjustments for this new context.
 --[[Joey]]
+
+> [[done]]

well, that didnt work :(
diff --git a/doc/todo/property_to_install_propellor/comment_2_9fea601af57777e1cb49952483f4da63._comment b/doc/todo/property_to_install_propellor/comment_2_9fea601af57777e1cb49952483f4da63._comment
new file mode 100644
index 0000000..f862f79
--- /dev/null
+++ b/doc/todo/property_to_install_propellor/comment_2_9fea601af57777e1cb49952483f4da63._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2017-04-09T20:49:04Z"
+ content="""
+Well, seems that `unshare` does not work in a chroot. Hmm.
+"""]]
diff --git a/src/Propellor/Property/Bootstrap.hs b/src/Propellor/Property/Bootstrap.hs
index 6158d96..4a60276 100644
--- a/src/Propellor/Property/Bootstrap.hs
+++ b/src/Propellor/Property/Bootstrap.hs
@@ -77,6 +77,9 @@ clonedFrom reposource = property ("Propellor repo cloned from " ++ originloc) $
 
 -- | Runs the shell command with the true localdir exposed,
 -- not the one bind-mounted into a chroot.
+--
+-- FIXME: unshare -m does not work in a chroot!
+-- "unshare: cannot change root filesystem propagation: Invalid argument"
 exposeTrueLocaldir :: String -> Propellor Bool
 exposeTrueLocaldir s = do
 	s' <- ifM inChroot

added Propellor.Property.Bootstrap (untested)
This commit was sponsored by Jake Vosloo on Patreon.
diff --git a/doc/todo/property_to_install_propellor/comment_1_b05e9a44e5c7130d9cc928223cd82d78._comment b/doc/todo/property_to_install_propellor/comment_1_b05e9a44e5c7130d9cc928223cd82d78._comment
new file mode 100644
index 0000000..5a826fe
--- /dev/null
+++ b/doc/todo/property_to_install_propellor/comment_1_b05e9a44e5c7130d9cc928223cd82d78._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2017-04-09T17:42:10Z"
+ content="""
+Making this work when propellor is setting up a chroot is difficult,
+because the localdir is bind mounted into the chroot.
+
+Hmm, `unshare` could be helpful. Run shell commands to clone the localdir
+inside `unshare -m`, prefixed with a `umount localdir`. This way, the bind
+mount is avoided, and it writes "under" it. Limits the commands that can be
+run to set up the localdir to shell commands, but bootstrap already
+operates on terms of shell commands so that seems ok.
+
+`unshare` is linux-specific; comes in util-linux on modern linuxes.
+"""]]
diff --git a/joeyconfig.hs b/joeyconfig.hs
index e73897b..036c2c9 100644
--- a/joeyconfig.hs
+++ b/joeyconfig.hs
@@ -38,6 +38,7 @@ import qualified Propellor.Property.SiteSpecific.GitAnnexBuilder as GitAnnexBuil
 import qualified Propellor.Property.SiteSpecific.Branchable as Branchable
 import qualified Propellor.Property.SiteSpecific.JoeySites as JoeySites
 import Propellor.Property.DiskImage
+import Propellor.Property.Bootstrap
 
 main :: IO ()           --     _         ______`|                       ,-.__
 main = defaultMain hosts --  /   \___-=O`/|O`/__|                      (____.'
@@ -93,7 +94,7 @@ darkstar = host "darkstar.kitenet.net" $ props
 		[ (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1YoyHxZwG5Eg0yiMTJLSWJ/+dMM6zZkZiR4JJ0iUfP+tT2bm/lxYompbSqBeiCq+PYcSC67mALxp1vfmdOV//LWlbXfotpxtyxbdTcQbHhdz4num9rJQz1tjsOsxTEheX5jKirFNC5OiKhqwIuNydKWDS9qHGqsKcZQ8p+n1g9Lr3nJVGY7eRRXzw/HopTpwmGmAmb9IXY6DC2k91KReRZAlOrk0287LaK3eCe1z0bu7LYzqqS+w99iXZ/Qs0m9OqAPnHZjWQQ0fN4xn5JQpZSJ7sqO38TBAimM+IHPmy2FTNVVn9zGM+vN1O2xr3l796QmaUG1+XLL0shfR/OZbb joey@darkstar")
 		]
 
-	! imageBuilt "/tmp/img" c MSDOS (grubBooted PC)
+	& imageBuilt "/tmp/img" c MSDOS (grubBooted PC)
 		[ partition EXT2 `mountedAt` "/boot"
 			`setFlag` BootFlag
 		, partition EXT4 `mountedAt` "/"
@@ -106,6 +107,7 @@ darkstar = host "darkstar.kitenet.net" $ props
 		& Hostname.setTo "demo"
 		& Apt.installed ["linux-image-amd64"]
 		& User "root" `User.hasInsecurePassword` "root"
+		& bootstrappedFrom GitRepoOutsideChroot
 
 gnu :: Host
 gnu = host "gnu.kitenet.net" $ props
diff --git a/propellor.cabal b/propellor.cabal
index a04089b..f4a1f23 100644
--- a/propellor.cabal
+++ b/propellor.cabal
@@ -87,6 +87,7 @@ Library
     Propellor.Property.Apt
     Propellor.Property.Apt.PPA
     Propellor.Property.Attic
+    Propellor.Property.Bootstrap
     Propellor.Property.Borg
     Propellor.Property.Ccache
     Propellor.Property.Cmd
diff --git a/src/Propellor/Property/Bootstrap.hs b/src/Propellor/Property/Bootstrap.hs
new file mode 100644
index 0000000..6158d96
--- /dev/null
+++ b/src/Propellor/Property/Bootstrap.hs
@@ -0,0 +1,95 @@
+module Propellor.Property.Bootstrap (RepoSource(..), bootstrappedFrom, clonedFrom) where
+
+import Propellor.Base
+import Propellor.Bootstrap
+import Propellor.Property.Chroot
+
+import Data.List
+
+-- | Where a propellor repository should be bootstrapped from.
+data RepoSource
+	= GitRepoUrl String
+	| GitRepoOutsideChroot
+
+-- | Bootstraps a propellor installation into
+-- /usr/local/propellor/
+--
+-- Normally, propellor is already bootstrapped when it runs, so this
+-- property is not useful. However, this can be useful inside a
+-- chroot used to build a disk image, to make the disk image
+-- have propellor installed.
+--
+-- The git repository is cloned (or pulled to update if it already exists).
+--
+-- All build dependencies are installed, using distribution packages
+-- or falling back to using cabal.
+bootstrappedFrom :: RepoSource -> Property Linux
+bootstrappedFrom reposource = go `requires` clonedFrom reposource
+  where
+	go :: Property Linux
+	go = property "Propellor bootstrapped" $ do
+		system <- getOS
+		assumeChange $ exposeTrueLocaldir $ buildShellCommand
+			[ "cd " ++ localdir
+			, bootstrapPropellorCommand system
+			]
+
+-- | Clones the propellor repeository into /usr/local/propellor/
+--
+-- GitRepoOutsideChroot can be used when this is used in a chroot.
+-- In that case, it clones the /usr/local/propellor/ from outside the
+-- chroot into the same path inside the chroot.
+--
+-- If the propellor repo has already been cloned, pulls to get it
+-- up-to-date.
+clonedFrom :: RepoSource -> Property Linux
+clonedFrom reposource = property ("Propellor repo cloned from " ++ originloc) $ do
+	ifM needclone
+		( do
+			let tmpclone = localdir ++ ".tmpclone"
+			system <- getOS
+			assumeChange $ exposeTrueLocaldir $ buildShellCommand
+				[ installGitCommand system
+				, "rm -rf " ++ tmpclone
+				, "git clone " ++ shellEscape originloc ++ " " ++ tmpclone
+				, "mkdir -p " ++ localdir
+				-- This is done rather than deleting
+				-- the old localdir, because if it is bound
+				-- mounted from outside the chroot, deleting
+				-- it after unmounting in unshare will remove
+				-- the bind mount outside the unshare.
+				, "(cd " ++ tmpclone ++ " && tar c) | (cd " ++ localdir ++ " && tar x)"
+				, "rm -rf " ++ tmpclone
+				]
+		, assumeChange $ exposeTrueLocaldir $ buildShellCommand
+			[ "cd " ++ localdir
+			, "git pull"
+			]
+		)
+  where
+	needclone = (inChroot <&&> truelocaldirisempty)
+		<||> (liftIO (not <$> doesDirectoryExist localdir))
+	truelocaldirisempty = exposeTrueLocaldir $
+		"test ! -d " ++ localdir ++ "/.git"
+	originloc = case reposource of
+		GitRepoUrl s -> s
+		GitRepoOutsideChroot -> localdir
+
+-- | Runs the shell command with the true localdir exposed,
+-- not the one bind-mounted into a chroot.
+exposeTrueLocaldir :: String -> Propellor Bool
+exposeTrueLocaldir s = do
+	s' <- ifM inChroot
+		( return $ "unshare -m sh -c " ++ shellEscape
+			("umount " ++ localdir ++ " && ( " ++ s ++ ")")
+		, return s
+		)
+	liftIO $ boolSystem "sh" [ Param "-c", Param s']
+
+assumeChange :: Propellor Bool -> Propellor Result
+assumeChange a = do
+	ok <- a
+	return (cmdResult ok <> MadeChange)
+
+buildShellCommand :: [String] -> String
+buildShellCommand = intercalate "&&" . map (\c -> "(" ++ c ++ ")")
diff --git a/src/Propellor/Property/Cmd.hs b/src/Propellor/Property/Cmd.hs
index 6b84acb..f2de1a2 100644
--- a/src/Propellor/Property/Cmd.hs
+++ b/src/Propellor/Property/Cmd.hs
@@ -33,6 +33,7 @@ module Propellor.Property.Cmd (
 	Script,
 	scriptProperty,
 	userScriptProperty,
+	cmdResult,
 	-- * Lower-level interface for running commands
 	CommandParam(..),
 	boolSystem,

tweaks to db45x's patch
Removed mountNow as a top-level property, as I don't think it makes
sense for anything except for mounted to use it.
db45x's patch turns out to have introduced a bug in mounted's use of
"mountNow src". That made mountNow check if the device was a mount
point, which it isn't. The fix would have been to use "mountNow mnt",
but my inlining of mountnow just basically reverted the part of the
patch that introduced the bug.
swapOn does not involve the fstab so moved to the Mount module.
(Also noticed that Mount.mounted is a kind of weird property, given that
it fails the next time ran. It's only used internally by some chroot
properties, so I left it as-is, but added a comment. It might make sense
to make Mount.mounted check like mountNow does if the thing is already
mounted.)
diff --git a/debian/changelog b/debian/changelog
index c3ae190..dcbe0a3 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+propellor (4.0.3) UNRELEASED; urgency=medium
+
+  * Added Fstab.listed, Fstab.swap, and Mount.swapOn properties.
+    Thanks, Daniel Brooks.
+
+ -- Joey Hess <id@joeyh.name>  Thu, 06 Apr 2017 19:40:12 -0400
+
 propellor (4.0.2) unstable; urgency=medium
 
   * Apt.mirror can be used to set the preferred apt mirror of a host,
diff --git a/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap/comment_5_6dc24952c8efa31a401191a8cf2d0b39._comment b/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap/comment_5_6dc24952c8efa31a401191a8cf2d0b39._comment
new file mode 100644
index 0000000..f87500b
--- /dev/null
+++ b/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap/comment_5_6dc24952c8efa31a401191a8cf2d0b39._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 5"""
+ date="2017-04-06T23:51:08Z"
+ content="""
+Merged. Have not tested it either.
+
+On my Debian system, the swapon command does not support the
+`--no-headings` that you used. It's `--noheadings` here. Is that a typo in
+your patch?
+
+I've simply removed that option for now, since it probably won't
+hurt if it treats the heading like another device that's swapped on.
+"""]]
diff --git a/src/Propellor/Property/Fstab.hs b/src/Propellor/Property/Fstab.hs
index 8196377..29b8542 100644
--- a/src/Propellor/Property/Fstab.hs
+++ b/src/Propellor/Property/Fstab.hs
@@ -15,16 +15,6 @@ import Data.List
 import Utility.Table
 
 -- | Ensures that </etc/fstab> contains a line mounting the specified
--- `Source` on the specified `MountPoint`.
-listed :: FsType -> Source -> MountPoint -> MountOpts -> Property UnixLike
-listed fs src mnt opts = "/etc/fstab" `File.containsLine` l
-	`describe` (mnt ++ " mounted by fstab")
-  where
-	l = intercalate "\t" [src, mnt, fs, formatMountOpts opts, dump, passno]
-	dump = "0"
-	passno = "2"
-
--- | Ensures that </etc/fstab> contains a line mounting the specified
 -- `Source` on the specified `MountPoint`, and that it's currently mounted.
 --
 -- For example:
@@ -34,29 +24,31 @@ listed fs src mnt opts = "/etc/fstab" `File.containsLine` l
 -- Note that if anything else is already mounted at the `MountPoint`, it
 -- will be left as-is by this property.
 mounted :: FsType -> Source -> MountPoint -> MountOpts -> Property Linux
-mounted fs src mnt opts = (listed fs src mnt opts) `onChange` (mountNow src)
+mounted fs src mnt opts = tightenTargets $ 
+	listed fs src mnt opts
+		`onChange` mountnow
+  where
+	-- This use of mountPoints, which is linux-only, is why this
+	-- property currently only supports linux.
+	mountnow = check (notElem mnt <$> mountPoints) $
+		cmdProperty "mount" [mnt]
+
+-- | Ensures that </etc/fstab> contains a line mounting the specified
+-- `Source` on the specified `MountPoint`. Does not ensure that it's
+-- currently `mounted`.
+listed :: FsType -> Source -> MountPoint -> MountOpts -> Property UnixLike
+listed fs src mnt opts = "/etc/fstab" `File.containsLine` l
+	`describe` (mnt ++ " mounted by fstab")
+  where
+	l = intercalate "\t" [src, mnt, fs, formatMountOpts opts, dump, passno]
+	dump = "0"
+	passno = "2"
 
 -- | Ensures that </etc/fstab> contains a line enabling the specified
--- `Source` to be used as swap space, and that it's enabled
+-- `Source` to be used as swap space, and that it's enabled.
 swap :: Source -> Property Linux
-swap src = (listed "swap" src "none" mempty) `onChange` (swapOn src)
-
--- This use of mountPoints, which is linux-only, is why this
--- property currently only supports linux.
-mountNow :: Source -> RevertableProperty Linux Linux
-mountNow mnt = tightenTargets domount <!> tightenTargets doumount
-  where domount = check (notElem mnt <$> mountPoints) $
-		cmdProperty "mount" [mnt]
-        doumount = check (elem mnt <$> mountPoints) $
-		cmdProperty "umount" [mnt]
-
-swapOn :: Source -> RevertableProperty Linux Linux
-swapOn mnt = tightenTargets doswapon <!> tightenTargets doswapoff
-  where swaps = lines <$> readProcess "swapon" ["--no-headings", "--show=NAME"]
-        doswapon = check (notElem mnt <$> swaps) $
-		cmdProperty "swapon" [mnt]
-        doswapoff = check (elem mnt <$> swaps) $
-		cmdProperty "swapoff" [mnt]
+swap src = listed "swap" src "none" mempty
+	`onChange` swapOn src
 
 newtype SwapPartition = SwapPartition FilePath
 
diff --git a/src/Propellor/Property/Mount.hs b/src/Propellor/Property/Mount.hs
index 026509a..5dcc5fe 100644
--- a/src/Propellor/Property/Mount.hs
+++ b/src/Propellor/Property/Mount.hs
@@ -40,6 +40,9 @@ formatMountOpts (MountOpts []) = "defaults"
 formatMountOpts (MountOpts l) = intercalate "," l
 
 -- | Mounts a device, without listing it in </etc/fstab>.
+--
+-- Note that this property will fail if the device is already mounted
+-- at the MountPoint.
 mounted :: FsType -> Source -> MountPoint -> MountOpts -> Property UnixLike
 mounted fs src mnt opts = property (mnt ++ " mounted") $ 
 	toResult <$> liftIO (mount fs src mnt opts)
@@ -52,6 +55,17 @@ bindMount src dest = tightenTargets $
 		`assume` MadeChange
 		`describe` ("bind mounted " ++ src ++ " to " ++ dest)
 
+-- | Enables swapping to a device, which must be formatted already as a swap
+-- partition.
+swapOn :: Source -> RevertableProperty Linux Linux
+swapOn mnt = tightenTargets doswapon <!> tightenTargets doswapoff
+  where
+	swaps = lines <$> readProcess "swapon" ["--show=NAME"]
+	doswapon = check (notElem mnt <$> swaps) $
+		cmdProperty "swapon" [mnt]
+	doswapoff = check (elem mnt <$> swaps) $
+		cmdProperty "swapoff" [mnt]
+
 mount :: FsType -> Source -> MountPoint -> MountOpts -> IO Bool
 mount fs src mnt opts = boolSystem "mount" $
 	[ Param "-t", Param fs

Added a comment
diff --git a/doc/forum/Using_propellor_for_continers_only/comment_2_42b45a126cfdf1dfc370b166c8042690._comment b/doc/forum/Using_propellor_for_continers_only/comment_2_42b45a126cfdf1dfc370b166c8042690._comment
new file mode 100644
index 0000000..45cd3e0
--- /dev/null
+++ b/doc/forum/Using_propellor_for_continers_only/comment_2_42b45a126cfdf1dfc370b166c8042690._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="bardur.arantsson"
+ avatar="http://cdn.libravatar.org/avatar/a0be0039b44d33262b7ae650a0803ad5"
+ subject="comment 2"
+ date="2017-04-06T02:14:58Z"
+ content="""
+I'll try that this weekend, thanks!
+"""]]

Added a comment
diff --git a/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap/comment_4_b1769231a633ad2b978ee4c9fa90591c._comment b/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap/comment_4_b1769231a633ad2b978ee4c9fa90591c._comment
new file mode 100644
index 0000000..ca04f94
--- /dev/null
+++ b/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap/comment_4_b1769231a633ad2b978ee4c9fa90591c._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="db48x@80bd751a72d5a80737e2f875342cf845629c7202"
+ nickname="db48x"
+ avatar="http://cdn.libravatar.org/avatar/ad2688127feb555a92154b16d8eeb5d3"
+ subject="comment 4"
+ date="2017-04-05T06:39:49Z"
+ content="""
+I took a stab at implementing this. It compiles, but I've not tested it yet as I need to get some sleep; consider it a work in progress. Looks right to me though.
+"""]]

comment
diff --git a/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap/comment_3_f48a6191c56bed41eda55436f0aa3e9c._comment b/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap/comment_3_f48a6191c56bed41eda55436f0aa3e9c._comment
new file mode 100644
index 0000000..95c6955
--- /dev/null
+++ b/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap/comment_3_f48a6191c56bed41eda55436f0aa3e9c._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2017-04-05T03:08:30Z"
+ content="""
+I like the idea of composing smaller properties to build the current
+property, and add flexability.
+
+Renaming the existing `fstabbed` would probably be too much bother.
+(Also, I think I picked that name because it kind of hints that the
+existing fstab does not come out alive.)
+
+(The swapspace package is great if you can eat the now tiny overhead of a
+swap file compared to a swap partition.)
+"""]]

Added a comment
diff --git a/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap/comment_2_773fc1441dd06e9dd41508bd800298eb._comment b/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap/comment_2_773fc1441dd06e9dd41508bd800298eb._comment
new file mode 100644
index 0000000..62cabc0
--- /dev/null
+++ b/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap/comment_2_773fc1441dd06e9dd41508bd800298eb._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="db48x@80bd751a72d5a80737e2f875342cf845629c7202"
+ nickname="db48x"
+ avatar="http://cdn.libravatar.org/avatar/ad2688127feb555a92154b16d8eeb5d3"
+ subject="comment 2"
+ date="2017-04-05T02:48:08Z"
+ content="""
+Yes, perhaps if it took an Option FilePath (am I saying this correctly in Haskellese?) it would be nicer.
+
+I don't mind much how it's structured; this was just the smallest obvious change, since it was failing to mount it. Perhaps breaking it up into smaller, more primitive, pieces would help. Fstab.mounted could = Fstab.fstabbed `onChange` Fstab.mounted, for instance, and then I could write Fstab.fstabbed `onChange` Swap.swapEnabled (oh, but Fstab.fstabbed already exists; I'm not using it because it replaces the whole file, which seems like an odd thing to do. Maybe call it Fstab.listed instead?).
+
+Also, for maximum irony I was just perusing your most recent dozen commits or so, and saw you enable Apt.serviceInstalledRunning \"swapspace\" on one of your machines. That's amazing; I had no idea it existed! I am re-evaluating all of my life choices now.
+"""]]

Added a comment
diff --git a/doc/forum/Git.cloned_deletes_harmless_empty_directory/comment_2_289f157f129511242d93beae76fd03a3._comment b/doc/forum/Git.cloned_deletes_harmless_empty_directory/comment_2_289f157f129511242d93beae76fd03a3._comment
new file mode 100644
index 0000000..1a8c144
--- /dev/null
+++ b/doc/forum/Git.cloned_deletes_harmless_empty_directory/comment_2_289f157f129511242d93beae76fd03a3._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="db48x@80bd751a72d5a80737e2f875342cf845629c7202"
+ nickname="db48x"
+ avatar="http://cdn.libravatar.org/avatar/ad2688127feb555a92154b16d8eeb5d3"
+ subject="comment 2"
+ date="2017-04-05T02:37:44Z"
+ content="""
+Yea, I guess that's a fair point about the other cases.
+
+It just seems inelegant to go back over all the files and fix up their permissions, when it could just have been set right to begin with.
+"""]]

comments
diff --git a/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap/comment_1_8ab6b313c80486f8f87a5e13e830bfa9._comment b/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap/comment_1_8ab6b313c80486f8f87a5e13e830bfa9._comment
new file mode 100644
index 0000000..4a144df
--- /dev/null
+++ b/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap/comment_1_8ab6b313c80486f8f87a5e13e830bfa9._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2017-04-05T02:17:00Z"
+ content="""
+This idea kind of makes sense, because swap partitions in /etc/fstab
+get swaponed at boot.
+
+But, the implementation doesn't take the types into account. The `mounted`
+property takes a FilePath for the mountpoint, but for swap that
+needs to be "none", which is not really a file-path. Also, the `fstabbed`
+property has a separate `SwapPartition` type, so making `mount` support
+swap partitions without using that type feels wrong.
+
+It might be simpler all round to treat swap partitions being able to
+be specified in /etc/fstab as a historical accident, which it kind of
+is (increasingly so, since eg systemd has other ways to accomplish
+that), and instead of shoehorning this into the `mounted` property,
+add a new `swaponed` property.
+"""]]
diff --git a/doc/forum/Git.cloned_deletes_harmless_empty_directory/comment_1_7cd0521c6d071b25852f8355f4f61f94._comment b/doc/forum/Git.cloned_deletes_harmless_empty_directory/comment_1_7cd0521c6d071b25852f8355f4f61f94._comment
new file mode 100644
index 0000000..91b403b
--- /dev/null
+++ b/doc/forum/Git.cloned_deletes_harmless_empty_directory/comment_1_7cd0521c6d071b25852f8355f4f61f94._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2017-04-05T02:22:54Z"
+ content="""
+I am not entirely happy with this patch, because it seems that if
+Git.cloned took care to preserve permissions in this case, it could be
+argued that it should also preserve permissions when the directory already
+exists but has the wrong content. Or equally well argued that it should not
+preserve permissions, which might be a leftover from some past unwanted
+state.
+
+Is that really the best way to do it? You could instead say:
+
+	Git.cloned user repo dir Nothing
+		`onChange` recursiveSetGID user dir
+
+And then you just have to write a recursiveSetGID which would be a
+generally useful property.
+"""]]

diff --git a/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap.mdwn b/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap.mdwn
new file mode 100644
index 0000000..61cd10c
--- /dev/null
+++ b/doc/forum/Fstab.mounted_could_call_swapon_when_activating_swap.mdwn
@@ -0,0 +1,3 @@
+The mount command won't work when activating a swap partition/file, so we should call swapon instead.
+
+https://github.com/ArchiveTeam/glowing-computing-machine/tree/fstab-swap

diff --git a/doc/forum/Git.cloned_deletes_harmless_empty_directory.mdwn b/doc/forum/Git.cloned_deletes_harmless_empty_directory.mdwn
new file mode 100644
index 0000000..ce3c192
--- /dev/null
+++ b/doc/forum/Git.cloned_deletes_harmless_empty_directory.mdwn
@@ -0,0 +1,3 @@
+In my case I have carefully set up the directory that I'm going to clone into with the correct group ownership and setgid permission, so that the cloned files will also have the correct ownership. This change just checks to see if the directory actually has anything in it before it deletes it.
+
+https://github.com/ArchiveTeam/glowing-computing-machine/tree/git-in-emtpy-directory

bug report
diff --git a/doc/todo/initial_spin_compile_failure_recovery.mdwn b/doc/todo/initial_spin_compile_failure_recovery.mdwn
new file mode 100644
index 0000000..423b279
--- /dev/null
+++ b/doc/todo/initial_spin_compile_failure_recovery.mdwn
@@ -0,0 +1,5 @@
+When initial propellor --spin host fails to compile propellor
+perhaps due to a ghc compatability bug, spinning again doesn't fix the
+problem. IIRC /usr/local/propellor has a git repo set up, but no remote
+set, and so the subsequent spin doesn't update it, since propellor is not
+running there to receive a git push into the repo. --[[Joey]]

response
diff --git a/doc/forum/Using_propellor_for_continers_only/comment_1_95e8b7103f248d93570fecb6b8999996._comment b/doc/forum/Using_propellor_for_continers_only/comment_1_95e8b7103f248d93570fecb6b8999996._comment
new file mode 100644
index 0000000..dc6cc61
--- /dev/null
+++ b/doc/forum/Using_propellor_for_continers_only/comment_1_95e8b7103f248d93570fecb6b8999996._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2017-03-29T19:09:37Z"
+ content="""
+Sounds like you may want to write a program that uses propellor as a
+library. `Propellor.Engine.mainProperties` is a reasonable
+entry point, just pass it a Host that has the properties you want
+to run.
+
+For example:
+
+	import Propellor
+	import Propellor.Engine
+	import Propellor.Property.DiskImage
+
+	main :: IO ()
+	main = mainProperties $ host "whatever" $ props
+		& imageBuilt "/some/disk.img" ...
+"""]]

diff --git a/doc/forum/Using_propellor_for_continers_only.mdwn b/doc/forum/Using_propellor_for_continers_only.mdwn
index c2b8673..faf0795 100644
--- a/doc/forum/Using_propellor_for_continers_only.mdwn
+++ b/doc/forum/Using_propellor_for_continers_only.mdwn
@@ -2,4 +2,4 @@ Hi,
 
 I was wondering: Is it possible to use propellor to generate images only without actually managing any hosts per-se? I couldn't find any documentation on that.
 
-Ideally, I'd also be able to use it directly from a sandbox so that I wouldn't have to even "pollute" the GHC/Cabal "global" (user home dir) database on the development machine. I see that there's support for having the config.hs stored in a different directory than ~/.propellor, but I haven't managed to get it working when I use a sandbox in e.g. ~/foo with the config.hs stored in the same directory. Perhaps that's just a bug? If it's supposed to work I can provide detailed error messages, etc.
+Ideally, I'd also be able to use it directly from a sandbox so that I wouldn't have to even "pollute" the GHC/Cabal "global" (user home dir) database on the development machine. I see that there's support for having the config.hs stored in a different directory than ~/.propellor, but I haven't managed to get it working when I use a sandbox in e.g. ~/foo with the config.hs stored in the same directory. Perhaps that's just a bug? If it's supposed to work I can provide detailed error messages, etc. **EDIT:** I'd also like to manage the git repository myself -- is that possible?

diff --git a/doc/forum/Using_propellor_for_continers_only.mdwn b/doc/forum/Using_propellor_for_continers_only.mdwn
new file mode 100644
index 0000000..c2b8673
--- /dev/null
+++ b/doc/forum/Using_propellor_for_continers_only.mdwn
@@ -0,0 +1,5 @@
+Hi,
+
+I was wondering: Is it possible to use propellor to generate images only without actually managing any hosts per-se? I couldn't find any documentation on that.
+
+Ideally, I'd also be able to use it directly from a sandbox so that I wouldn't have to even "pollute" the GHC/Cabal "global" (user home dir) database on the development machine. I see that there's support for having the config.hs stored in a different directory than ~/.propellor, but I haven't managed to get it working when I use a sandbox in e.g. ~/foo with the config.hs stored in the same directory. Perhaps that's just a bug? If it's supposed to work I can provide detailed error messages, etc.

todo
diff --git a/doc/todo/property_to_install_propellor.mdwn b/doc/todo/property_to_install_propellor.mdwn
new file mode 100644
index 0000000..25db819
--- /dev/null
+++ b/doc/todo/property_to_install_propellor.mdwn
@@ -0,0 +1,14 @@
+This seems redundant, since propellor must be running to ensure such a
+Property, but a Property to install propellor is useful when eg, creating a
+disk image that itself will need to run propellor. --[[Joey]]
+
+Should support:
+
+* Cloning the git repo propellor is running in. (Using eg `hostChroot`)
+* Cloning some other git repo.
+* Installing the precompiled propellor binary.
+* Installing the propellor haskell library using cabal/stack/apt.
+
+Much of this is already implemented, in non-Property form, in
+Propellor.Bootstrap, but will need adjustments for this new context.
+--[[Joey]]

response
diff --git a/doc/forum/Manage_multiple_different_projects_with_propellor/comment_1_dbad48163b2efd6434ea7c37a72dfd30._comment b/doc/forum/Manage_multiple_different_projects_with_propellor/comment_1_dbad48163b2efd6434ea7c37a72dfd30._comment
new file mode 100644
index 0000000..7513cc0
--- /dev/null
+++ b/doc/forum/Manage_multiple_different_projects_with_propellor/comment_1_dbad48163b2efd6434ea7c37a72dfd30._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2017-03-24T18:14:14Z"
+ content="""
+There did not used to be a good way to do that, but since propellor 3.2.3,
+when you run eg "propellor --spin host", it first checks to see if there is
+a `./config.hs` file, and if so, uses it instead of the user-global
+`~/.propellor/config.hs`.
+
+So, just make different git repos for the different projects with propellor
+`config.hs` files in them, and `cd` into the one you want to run before running
+propellor.
+"""]]

add news item for propellor 4.0.2
diff --git a/doc/news/version_4.0.1.mdwn b/doc/news/version_4.0.1.mdwn
deleted file mode 100644
index e870a51..0000000
--- a/doc/news/version_4.0.1.mdwn
+++ /dev/null
@@ -1,6 +0,0 @@
-propellor 4.0.1 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Fix build with pre-AMP ghc.
-   * Tor: Restart daemon after installing private key.
-   * Tor.named, Tor.torPrivKey: Include the new ed25519 public/private key
-     pair in addition to the old secret\_id\_key."""]]
\ No newline at end of file
diff --git a/doc/news/version_4.0.2.mdwn b/doc/news/version_4.0.2.mdwn
new file mode 100644
index 0000000..b955c57
--- /dev/null
+++ b/doc/news/version_4.0.2.mdwn
@@ -0,0 +1,12 @@
+propellor 4.0.2 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Apt.mirror can be used to set the preferred apt mirror of a host,
+     overriding the default CDN. This info is used by
+     Apt.stdSourcesList and Sbuild.builtFor.
+     Thanks, Sean Whitton.
+   * Property.Partition: Update kpartx output parser, as its output format
+     changed around version 0.6. Both output formats are supported now.
+   * Fix bug when using setContainerProps with a chroot that prevented
+     properties added to a chroot that way from being seen when propellor
+     was running inside the chroot. This affected disk image creation, and
+     possibly other things that use chroots."""]]
\ No newline at end of file

fix diskimage finalization bug
* Fix bug when using setContainerProps with a chroot that prevented
properties added to a chroot that way from being seen when propellor
was running inside the chroot. This affected disk image creation, and
possibly other things that use chroots.
The problem was, propagateChrootInfo was being passed the initial
version of the Chroot, but then the Chroot got more properties
added, and so those were not recorded in the _chroot info.
Fix was simply to make InfoPropagator be passed the Chroot as an
additional parameter, so Chroot.provisioned' can pass in the final
Chroot to it.
diff --git a/debian/changelog b/debian/changelog
index 9e6ffb6..11c9922 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -6,6 +6,10 @@ propellor (4.0.2) UNRELEASED; urgency=medium
     Thanks, Sean Whitton.
   * Property.Partition: Update kpartx output parser, as its output format
     changed around version 0.6. Both output formats are supported now.
+  * Fix bug when using setContainerProps with a chroot that prevented
+    properties added to a chroot that way from being seen when propellor
+    was running inside the chroot. This affected disk image creation, and
+    possibly other things that use chroots.
    
  -- Joey Hess <id@joeyh.name>  Sun, 19 Mar 2017 16:37:27 -0400
 
diff --git a/doc/todo/bug_in_diskimage_finalization.mdwn b/doc/todo/bug_in_diskimage_finalization.mdwn
index 288e96f..3dc9c43 100644
--- a/doc/todo/bug_in_diskimage_finalization.mdwn
+++ b/doc/todo/bug_in_diskimage_finalization.mdwn
@@ -9,3 +9,5 @@ ensure.
 
 I have not yet been able to determine what broke it -- I'm sure it used to
 work. --[[Joey]]
+
+> Figured it out, fixed [[done]] --[[Joey]]
diff --git a/src/Propellor/Property/Chroot.hs b/src/Propellor/Property/Chroot.hs
index 920a46d..7738d97 100644
--- a/src/Propellor/Property/Chroot.hs
+++ b/src/Propellor/Property/Chroot.hs
@@ -46,7 +46,9 @@ data Chroot where
 instance IsContainer Chroot where
 	containerProperties (Chroot _ _ _ h) = containerProperties h
 	containerInfo (Chroot _ _ _ h) = containerInfo h
-	setContainerProperties (Chroot loc b p h) ps = Chroot loc b p (setContainerProperties h ps)
+	setContainerProperties (Chroot loc b p h) ps =
+		let h' = setContainerProperties h ps
+		in Chroot loc b p h'
 
 chrootSystem :: Chroot -> Maybe System
 chrootSystem = fromInfoVal . fromInfo . containerInfo
@@ -118,7 +120,7 @@ debootstrapped conf = bootstrapped (Debootstrapped conf)
 bootstrapped :: ChrootBootstrapper b => b -> FilePath -> Props metatypes -> Chroot
 bootstrapped bootstrapper location ps = c
   where
-	c = Chroot location bootstrapper (propagateChrootInfo c) (host location ps)
+	c = Chroot location bootstrapper propagateChrootInfo (host location ps)
 
 -- | Ensures that the chroot exists and is provisioned according to its
 -- properties.
@@ -134,7 +136,7 @@ provisioned'
 	-> Bool
 	-> RevertableProperty (HasInfo + Linux) Linux
 provisioned' c@(Chroot loc bootstrapper infopropigator _) systemdonly =
-	(infopropigator normalContainerInfo $ setup `describe` chrootDesc c "exists")
+	(infopropigator c normalContainerInfo $ setup `describe` chrootDesc c "exists")
 		<!>
 	(teardown `describe` chrootDesc c "removed")
   where
@@ -153,9 +155,9 @@ provisioned' c@(Chroot loc bootstrapper infopropigator _) systemdonly =
 		property ("removed " ++ loc) $
 			makeChange (removeChroot loc)
 
-type InfoPropagator = (PropagateInfo -> Bool) -> Property Linux -> Property (HasInfo + Linux)
+type InfoPropagator = Chroot -> (PropagateInfo -> Bool) -> Property Linux -> Property (HasInfo + Linux)
 
-propagateChrootInfo :: Chroot -> InfoPropagator
+propagateChrootInfo :: InfoPropagator
 propagateChrootInfo c@(Chroot location _ _ _) pinfo p =
 	propagateContainer location c pinfo $
 		p `setInfoProperty` chrootInfo c
@@ -302,12 +304,12 @@ hostChroot :: ChrootBootstrapper bootstrapper => Host -> bootstrapper -> FilePat
 hostChroot h bootstrapper d = chroot
   where
 	chroot = Chroot d bootstrapper pinfo h
-	pinfo = propagateHostChrootInfo h chroot
+	pinfo = propagateHostChrootInfo h
 
 -- This is different than propagateChrootInfo in that Info using
 -- HostContext is not made to use the name of the chroot as its context,
 -- but instead uses the hostname of the Host.
-propagateHostChrootInfo :: Host -> Chroot -> InfoPropagator
+propagateHostChrootInfo :: Host -> InfoPropagator
 propagateHostChrootInfo h c pinfo p =
 	propagateContainer (hostName h) c pinfo $
 		p `setInfoProperty` chrootInfo c
diff --git a/src/Propellor/Property/DiskImage.hs b/src/Propellor/Property/DiskImage.hs
index 06d0694..90b7010 100644
--- a/src/Propellor/Property/DiskImage.hs
+++ b/src/Propellor/Property/DiskImage.hs
@@ -140,7 +140,7 @@ imageBuilt' rebuild img mkchroot tabletype final partspec =
 			& cachesCleaned
 	-- Only propagate privdata Info from this chroot, nothing else.
 	propprivdataonly (Chroot.Chroot d b ip h) =
-		Chroot.Chroot d b (const $ ip onlyPrivData) h
+		Chroot.Chroot d b (\c _ -> ip c onlyPrivData) h
 
 -- | This property is automatically added to the chroot when building a
 -- disk image. It cleans any caches of information that can be omitted;
diff --git a/src/Propellor/Property/Systemd.hs b/src/Propellor/Property/Systemd.hs
index 8f9c3be..7c40bd1 100644
--- a/src/Propellor/Property/Systemd.hs
+++ b/src/Propellor/Property/Systemd.hs
@@ -281,7 +281,7 @@ nspawned c@(Container name (Chroot.Chroot loc builder _ _) h) =
 			<!>
 		doNothing
 
-	chroot = Chroot.Chroot loc builder (Chroot.propagateChrootInfo chroot) h
+	chroot = Chroot.Chroot loc builder Chroot.propagateChrootInfo h
 
 -- | Sets up the service file for the container, and then starts
 -- it running.

diff --git a/doc/forum/Manage_multiple_different_projects_with_propellor.mdwn b/doc/forum/Manage_multiple_different_projects_with_propellor.mdwn
new file mode 100644
index 0000000..bcba383
--- /dev/null
+++ b/doc/forum/Manage_multiple_different_projects_with_propellor.mdwn
@@ -0,0 +1,7 @@
+Hi there,
+
+I've been tasked with investigating propellor as an alternative to Ansible. I'm a little bit confused about how one might go about managing a *single* project's hosts with propellor, without infecting the global propellor config. It seems that everything is concerned with the ~/.propellor repository. However, I don't want project A's hosts to know about project B's and vice versa. I'm sure I'm overlooking something obvious!
+
+Thanks very much!
+
+Mitchell

bug report
diff --git a/doc/todo/bug_in_diskimage_finalization.mdwn b/doc/todo/bug_in_diskimage_finalization.mdwn
new file mode 100644
index 0000000..288e96f
--- /dev/null
+++ b/doc/todo/bug_in_diskimage_finalization.mdwn
@@ -0,0 +1,11 @@
+DiskImage.imageBuilt has broken and no longer runs the finalization
+properties that get added to the chroot. This includes installing grub, and
+Chroot.noServices etc.
+
+Seems that the `_chroot` info that gets propigated from imageBuilt is
+for the chroot before those properties are added to it. Then when chaining
+into the chroot, `_chroot` info is examined to find the properties to
+ensure.
+
+I have not yet been able to determine what broke it -- I'm sure it used to
+work. --[[Joey]]

Apt.mirror can be used to set the preferred apt mirror of a host, overriding the default CDN.
This info is used by Apt.stdSourcesList and Sbuild.builtFor.
Thanks, Sean Whitton.
diff --git a/debian/changelog b/debian/changelog
index dd950ec..ed0e242 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+propellor (4.0.2) UNRELEASED; urgency=medium
+
+  * Apt.mirror can be used to set the preferred apt mirror of a host,
+    overriding the default CDN. This info is used by 
+    Apt.stdSourcesList and Sbuild.builtFor.
+    Thanks, Sean Whitton.
+
+ -- Joey Hess <id@joeyh.name>  Sun, 19 Mar 2017 16:37:27 -0400
+
 propellor (4.0.1) unstable; urgency=medium
 
   * Fix build with pre-AMP ghc.
diff --git a/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror.mdwn b/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror.mdwn
index e3702ab..4cd7638 100644
--- a/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror.mdwn
+++ b/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror.mdwn
@@ -1,3 +1,5 @@
 It would be good to have an info property, say `Apt.mirror`, which sets a host's preferred apt mirror.  Then all properties in `Propellor.Property.Apt` would use this mirror when generating sources lists, falling back to the `deb.debian.org` default.  The value of `Apt.mirror` could be an apt cache on the LAN, or a mirror that is known to be better than the Debian CDN from where the host is located. --[[spwhitton|user/spwhitton]]
 
 [[!tag user/spwhitton]]
+
+> [[merged|done]] thank you! --[[Joey]]
diff --git a/src/Propellor/Property/Apt.hs b/src/Propellor/Property/Apt.hs
index 8f4678d..686ddb6 100644
--- a/src/Propellor/Property/Apt.hs
+++ b/src/Propellor/Property/Apt.hs
@@ -105,8 +105,9 @@ securityUpdates suite
 		in [l, srcLine l]
 	| otherwise = []
 
--- | Makes sources.list have a standard content using the Debian mirror CDN,
--- with the Debian suite configured by the os.
+-- | Makes sources.list have a standard content using the Debian mirror CDN
+-- (or other host specified using the `mirror` property), with the
+-- Debian suite configured by the os.
 stdSourcesList :: Property Debian
 stdSourcesList = withOS "standard sources.list" $ \w o -> case o of
 	(Just (System (Debian _ suite) _)) ->

add news item for propellor 4.0.1
diff --git a/doc/news/version_4.0.0.mdwn b/doc/news/version_4.0.0.mdwn
deleted file mode 100644
index bb62b4a..0000000
--- a/doc/news/version_4.0.0.mdwn
+++ /dev/null
@@ -1,30 +0,0 @@
-propellor 4.0.0 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Added Monoid instances for Property and RevertableProperty.
-   * Removed applyToList. Instead, use mconcat. (API change)
-     If you had:  applyToList accountFor [User "joey", User "root"]
-     use instead: mconcat (map accountFor [User "joey", User "root"])
-   * Makefile: Removed "run" target which was default target.
-     "make" now only builds propellor, does not run it.
-     Note that propellor 1.0.0 and earlier relied on this target for
-     the Cron.runPropellor property's cronjob to work, so upgrading
-     directly from 1.0.0 to 4.0.0 would break that cron job.
-   * Remove make from propellor's dependency list; it's not used by
-     propellor any longer.
-   * Implemented hostChroot, as originally seen in my slides at
-     Linux.Conf.Au 2017 in January. Now that it's not vaporware, it allows
-     one Host to build a disk image that has all the properties of another
-     Host.
-   * DiskImage building properties used to propagate DNS info out from
-     the chroot used to build the disk image to the Host. That is no longer
-     done, since that chroot only exists as a side effect of the disk image
-     creation and servers will not be running in it.
-   * The IsInfo types class's propagateInfo function changed to use a
-     PropagateInfo data type. (API change)
-   * The action used to satisfy a property changed to Maybe (Propellor Result).
-     When it is Nothing, propellor knows it can skip displaying the
-     description of that property. This is mostly useful in the
-     implementation of mempty. (API change)
-   * The doNothing property is now simply mempty. The name was retained
-     because it can be clearer than mempty in some contexts.
-   * Added Apache.confEnabled."""]]
\ No newline at end of file
diff --git a/doc/news/version_4.0.1.mdwn b/doc/news/version_4.0.1.mdwn
new file mode 100644
index 0000000..e870a51
--- /dev/null
+++ b/doc/news/version_4.0.1.mdwn
@@ -0,0 +1,6 @@
+propellor 4.0.1 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Fix build with pre-AMP ghc.
+   * Tor: Restart daemon after installing private key.
+   * Tor.named, Tor.torPrivKey: Include the new ed25519 public/private key
+     pair in addition to the old secret\_id\_key."""]]
\ No newline at end of file

Added a comment: merge request
diff --git a/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror/comment_2_2c2c4817a4259acbc1a63bac2e3fb2e3._comment b/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror/comment_2_2c2c4817a4259acbc1a63bac2e3fb2e3._comment
new file mode 100644
index 0000000..b79ba1c
--- /dev/null
+++ b/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror/comment_2_2c2c4817a4259acbc1a63bac2e3fb2e3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ avatar="http://cdn.libravatar.org/avatar/9c3f08f80e67733fd506c353239569eb"
+ subject="merge request"
+ date="2017-03-19T18:42:20Z"
+ content="""
+Please see branch `apt-mirror` of repo `https://git.spwhitton.name/propellor` for an implementation of this.
+"""]]

take ownership of todo item
diff --git a/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror.mdwn b/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror.mdwn
index 355d53b..e3702ab 100644
--- a/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror.mdwn
+++ b/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror.mdwn
@@ -1 +1,3 @@
 It would be good to have an info property, say `Apt.mirror`, which sets a host's preferred apt mirror.  Then all properties in `Propellor.Property.Apt` would use this mirror when generating sources lists, falling back to the `deb.debian.org` default.  The value of `Apt.mirror` could be an apt cache on the LAN, or a mirror that is known to be better than the Debian CDN from where the host is located. --[[spwhitton|user/spwhitton]]
+
+[[!tag user/spwhitton]]

add news item for propellor 4.0.0
diff --git a/doc/news/version_4.0.0.mdwn b/doc/news/version_4.0.0.mdwn
new file mode 100644
index 0000000..bb62b4a
--- /dev/null
+++ b/doc/news/version_4.0.0.mdwn
@@ -0,0 +1,30 @@
+propellor 4.0.0 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Added Monoid instances for Property and RevertableProperty.
+   * Removed applyToList. Instead, use mconcat. (API change)
+     If you had:  applyToList accountFor [User "joey", User "root"]
+     use instead: mconcat (map accountFor [User "joey", User "root"])
+   * Makefile: Removed "run" target which was default target.
+     "make" now only builds propellor, does not run it.
+     Note that propellor 1.0.0 and earlier relied on this target for
+     the Cron.runPropellor property's cronjob to work, so upgrading
+     directly from 1.0.0 to 4.0.0 would break that cron job.
+   * Remove make from propellor's dependency list; it's not used by
+     propellor any longer.
+   * Implemented hostChroot, as originally seen in my slides at
+     Linux.Conf.Au 2017 in January. Now that it's not vaporware, it allows
+     one Host to build a disk image that has all the properties of another
+     Host.
+   * DiskImage building properties used to propagate DNS info out from
+     the chroot used to build the disk image to the Host. That is no longer
+     done, since that chroot only exists as a side effect of the disk image
+     creation and servers will not be running in it.
+   * The IsInfo types class's propagateInfo function changed to use a
+     PropagateInfo data type. (API change)
+   * The action used to satisfy a property changed to Maybe (Propellor Result).
+     When it is Nothing, propellor knows it can skip displaying the
+     description of that property. This is mostly useful in the
+     implementation of mempty. (API change)
+   * The doNothing property is now simply mempty. The name was retained
+     because it can be clearer than mempty in some contexts.
+   * Added Apache.confEnabled."""]]
\ No newline at end of file

done
diff --git a/doc/todo/hostChroot.mdwn b/doc/todo/hostChroot.mdwn
index eccfd64..6a4df9c 100644
--- a/doc/todo/hostChroot.mdwn
+++ b/doc/todo/hostChroot.mdwn
@@ -5,3 +5,5 @@ properties to it. --[[Joey]]
 
 Would need to make privdata use the context of the input Host. And would
 need to propigate privdata info, but not other info. --[[Joey]]
+
+> [[done]] --[[Joey]]

update
diff --git a/doc/README.mdwn b/doc/README.mdwn
index 31d222c..ea622b3 100644
--- a/doc/README.mdwn
+++ b/doc/README.mdwn
@@ -12,8 +12,8 @@ repository to each host it manages, in a
 [components](http://propellor.branchable.com/components/)
 for details.
 
-Properties are defined using Haskell. Edit `~/.propellor/config.hs`
-to get started. There is fairly complete 
+Properties are defined using Haskell in the file `~/.propellor/config.hs`.
+There is fairly complete 
 [API documentation](http://hackage.haskell.org/package/propellor/),
 which includes many built-in Properties for dealing with
 [Apt](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Apt.html)
diff --git a/doc/download.mdwn b/doc/download.mdwn
new file mode 100644
index 0000000..6fe1ca3
--- /dev/null
+++ b/doc/download.mdwn
@@ -0,0 +1,5 @@
+Propellor's source code and some example configs are in a git repository:
+
+`git clone git://propellor.branchable.com/propellor`
+
+See the [[README]] for details on installing and configuring propellor.
diff --git a/doc/index.mdwn b/doc/index.mdwn
index 52c2302..1e3af9d 100644
--- a/doc/index.mdwn
+++ b/doc/index.mdwn
@@ -1,7 +1,7 @@
 [[!meta title="propellor: deploying properties to hosts with haskell"]]
 
 [[!sidebar content="""
-[[Install]]  
+[[Download]]  
 [API documentation](http://hackage.haskell.org/package/propellor)  
 [[Other Documentation|documentation]]
 [Sample config file](http://git.joeyh.name/?p=propellor.git;a=blob;f=joeyconfig.hs)  
diff --git a/doc/install.mdwn b/doc/install.mdwn
deleted file mode 100644
index 8db966f..0000000
--- a/doc/install.mdwn
+++ /dev/null
@@ -1,3 +0,0 @@
-`git clone git://propellor.branchable.com/propellor`  
-
-Propellor is also available in Debian.

add news item for propellor 3.4.1
diff --git a/doc/news/version_3.2.2.mdwn b/doc/news/version_3.2.2.mdwn
deleted file mode 100644
index 19acc9f..0000000
--- a/doc/news/version_3.2.2.mdwn
+++ /dev/null
@@ -1,5 +0,0 @@
-propellor 3.2.2 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Added Linode.serialGrub property.
-   * Clean up build warnings about redundant constraints when built with ghc 8.0.
-   * Added Group.hasUser property. Thanks, Daniel Brooks"""]]
\ No newline at end of file
diff --git a/doc/news/version_3.4.1.mdwn b/doc/news/version_3.4.1.mdwn
new file mode 100644
index 0000000..51d9c2a
--- /dev/null
+++ b/doc/news/version_3.4.1.mdwn
@@ -0,0 +1,3 @@
+propellor 3.4.1 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Fixed https url to propellor git repository."""]]
\ No newline at end of file

add news item for propellor 3.4.0
diff --git a/doc/news/version_3.2.1.mdwn b/doc/news/version_3.2.1.mdwn
deleted file mode 100644
index 214ef42..0000000
--- a/doc/news/version_3.2.1.mdwn
+++ /dev/null
@@ -1,5 +0,0 @@
-propellor 3.2.1 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Simplify Debootstrap.sourceInstall since #770217 was fixed.
-   * Debootstap.installed: Fix inverted logic that made this never install
-     debootstrap. Thanks, mithrandi."""]]
\ No newline at end of file
diff --git a/doc/news/version_3.4.0.mdwn b/doc/news/version_3.4.0.mdwn
new file mode 100644
index 0000000..d38716e
--- /dev/null
+++ b/doc/news/version_3.4.0.mdwn
@@ -0,0 +1,14 @@
+propellor 3.4.0 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Added ConfigurableValue type class, for values that can be used in a
+     config file, or to otherwise configure a program.
+   * The val function converts such values to String.
+   * Removed fromPort and fromIPAddr (use val instead). (API change)
+   * Removed several Show instances that were only used for generating
+     configuration, replacing with ConfigurableValue instances. (API change)
+   * The github mirror of propellor's git repository has been removed,
+     since github's terms of service has started imposing unwanted licensing
+     requirements.
+   * propellor --init: The option to clone propellor's git repository
+     used to use the github mirror, and has been changed to use a different
+     mirror."""]]
\ No newline at end of file

github mirror of propellor is gone
* The github mirror of propellor's git repository has been removed,
since github's terms of service has started imposing unwanted licensing
requirements.
* propellor --init: The option to clone propellor's git repository
used to use the github mirror, and has been changed to use a different
mirror.
diff --git a/debian/changelog b/debian/changelog
index f965a58..4763281 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -6,6 +6,12 @@ propellor (3.4.0) UNRELEASED; urgency=medium
   * Removed fromPort and fromIPAddr (use val instead). (API change)
   * Removed several Show instances that were only used for generating
     configuration, replacing with ConfigurableValue instances. (API change)
+  * The github mirror of propellor's git repository has been removed,
+    since github's terms of service has started imposing unwanted licensing
+    requirements.
+  * propellor --init: The option to clone propellor's git repository
+    used to use the github mirror, and has been changed to use a different
+    mirror.
 
  -- Joey Hess <id@joeyh.name>  Sun, 26 Feb 2017 15:15:33 -0400
 
diff --git a/doc/install.mdwn b/doc/install.mdwn
index f64519a..8db966f 100644
--- a/doc/install.mdwn
+++ b/doc/install.mdwn
@@ -1,4 +1,3 @@
 `git clone git://propellor.branchable.com/propellor`  
-Or get it [from github](https://github.com/joeyh/propellor).
 
-Propellor is recently available in Debian.
+Propellor is also available in Debian.
diff --git a/src/Propellor/DotDir.hs b/src/Propellor/DotDir.hs
index 417abcf..f5c20d3 100644
--- a/src/Propellor/DotDir.hs
+++ b/src/Propellor/DotDir.hs
@@ -47,10 +47,10 @@ disthead = distdir </> "head"
 upstreambranch :: String
 upstreambranch = "upstream/master"
 
--- Using the github mirror of the main propellor repo because
+-- Using the joeyh.name mirror of the main propellor repo because
 -- it is accessible over https for better security.
 netrepo :: String
-netrepo = "https://github.com/joeyh/propellor.git"
+netrepo = "https://git.joeyh.name/propellor.git"
 
 dotPropellor :: IO FilePath
 dotPropellor = do

gogogo
diff --git a/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror/comment_1_ac66a33d71092261a745378c82959e69._comment b/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror/comment_1_ac66a33d71092261a745378c82959e69._comment
new file mode 100644
index 0000000..3734d98
--- /dev/null
+++ b/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror/comment_1_ac66a33d71092261a745378c82959e69._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2017-02-21T03:07:28Z"
+ content="""
+Very good idea. Happy to merge such a patch.
+"""]]

clarify todo
diff --git a/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror.mdwn b/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror.mdwn
index 42aa850..355d53b 100644
--- a/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror.mdwn
+++ b/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror.mdwn
@@ -1 +1 @@
-It would be good to have an info property, say `Apt.mirror`, which sets a host's preferred apt mirror.  Then all properties in `Propellor.Property.Apt` would use this mirror when generating sources lists.  The value of `Apt.mirror` could be an apt cache on the LAN, or a mirror that is known to be better than the Debian CDN, due to where the host is located. --[[spwhitton|user/spwhitton]]
+It would be good to have an info property, say `Apt.mirror`, which sets a host's preferred apt mirror.  Then all properties in `Propellor.Property.Apt` would use this mirror when generating sources lists, falling back to the `deb.debian.org` default.  The value of `Apt.mirror` could be an apt cache on the LAN, or a mirror that is known to be better than the Debian CDN from where the host is located. --[[spwhitton|user/spwhitton]]

create user page in correct place
diff --git a/doc/user/spwhitton.mdwn b/doc/user/spwhitton.mdwn
new file mode 100644
index 0000000..f5f92fa
--- /dev/null
+++ b/doc/user/spwhitton.mdwn
@@ -0,0 +1 @@
+Maintainer of propellor's Debian package, and several modules.

removed
diff --git a/doc/todo/user/spwhitton.mdwn b/doc/todo/user/spwhitton.mdwn
deleted file mode 100644
index 74810d5..0000000
--- a/doc/todo/user/spwhitton.mdwn
+++ /dev/null
@@ -1 +0,0 @@
-Maintainer of the Debian package of propellor.  Also maintainer of some of propellor's modules.

post todo: apt mirror info property
diff --git a/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror.mdwn b/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror.mdwn
new file mode 100644
index 0000000..42aa850
--- /dev/null
+++ b/doc/todo/Info_property_to_select_host__39__s_preferred_Apt_mirror.mdwn
@@ -0,0 +1 @@
+It would be good to have an info property, say `Apt.mirror`, which sets a host's preferred apt mirror.  Then all properties in `Propellor.Property.Apt` would use this mirror when generating sources lists.  The value of `Apt.mirror` could be an apt cache on the LAN, or a mirror that is known to be better than the Debian CDN, due to where the host is located. --[[spwhitton|user/spwhitton]]

create user page
diff --git a/doc/todo/user/spwhitton.mdwn b/doc/todo/user/spwhitton.mdwn
new file mode 100644
index 0000000..74810d5
--- /dev/null
+++ b/doc/todo/user/spwhitton.mdwn
@@ -0,0 +1 @@
+Maintainer of the Debian package of propellor.  Also maintainer of some of propellor's modules.

add news item for propellor 3.3.1
diff --git a/doc/news/version_3.2.0.mdwn b/doc/news/version_3.2.0.mdwn
deleted file mode 100644
index bef06b1..0000000
--- a/doc/news/version_3.2.0.mdwn
+++ /dev/null
@@ -1,17 +0,0 @@
-propellor 3.2.0 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
- * [ Sean Whitton ]
-   * Using ccache with Sbuild.built &amp; Sbuild.builtFor is now toggleable: these
-     properties now take a parameter of type Sbuild.UseCcache.  (API Change)
-   * Sbuild.piupartsConf: no longer takes an Apt.Url. (API Change)
-   * Sbuild.piupartsConf &amp; Sbuild.piupartsConfFor: does nothing if corresponding
-     schroot not built.
-     Previously, these properties built the schroot if it was missing.
-   * Sbuild.built &amp; Sbuild.piupartsConf: add an additional alias to sid chroots.
-     This is for compatibility with `dgit sbuild`.
-   * Further improvements to Sbuild.hs haddock.
- * [ Joey Hess ]
-   * Tor.hiddenService: Converted port parameter from Int to Port. (API change)
-   * Tor.hiddenServiceAvailable: The hidden service hostname file may not
-     be available immedaitely after configuring tor; avoid ugly error in
-     this case."""]]
\ No newline at end of file
diff --git a/doc/news/version_3.3.1.mdwn b/doc/news/version_3.3.1.mdwn
new file mode 100644
index 0000000..84ab72f
--- /dev/null
+++ b/doc/news/version_3.3.1.mdwn
@@ -0,0 +1,8 @@
+propellor 3.3.1 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Apt: Removed the mirrors.kernel.org line from stdSourcesList etc.
+     The mirror CDN has a new implementation that should avoid the problems
+     with httpredir that made an extra mirror sometimes be needed.
+   * Switch Debian CDN address to deb.debian.org.
+   * Tor.hiddenService: Fix bug in torrc's HiddenServicePort configuration.
+     Thanks, Félix Sipma"""]]
\ No newline at end of file

Revert "removed"
This reverts commit da400e7af20bf418c13de4456822303d91af83a3.
No idea why this comment was removed. Going to assume it was an accident
unless it happens again..
diff --git a/doc/todo/Arch_Linux_Port/comment_3_d917de766dfe7fded7317d7614d1467f._comment b/doc/todo/Arch_Linux_Port/comment_3_d917de766dfe7fded7317d7614d1467f._comment
new file mode 100644
index 0000000..27ef807
--- /dev/null
+++ b/doc/todo/Arch_Linux_Port/comment_3_d917de766dfe7fded7317d7614d1467f._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2017-02-04T20:55:02Z"
+ content="""
+> Instead,  I changed some properties in DiskImage from Linux to
+> DebianLike.  Is it the correct way to do it?
+
+Looking at it, kpartx is DebianLike-specific, so imageBuiltFrom which uses it
+should be too. The only reason it wasn't marked as DebianLike already and
+was type Linux is because Linux used to be the same as DebianLike and so
+the type checker didn't see a difference. No longer, thanks to your patch.
+
+So, it makes complete sense that you have to change this. You're paying
+the price of blazing the trail of the first non-DebianLike Linux distro in
+Propellor..
+
+---
+
+Looks like your [[!commit 25f6871e1dda3de252fbc6c8ac6962eb0cd9311a]]
+dealt with all my review suggestions. And so, I've merged it.
+
+Unless you have anything else that needs to be done, I'll release
+propellor soon with the added Arch Linux support. Thank you very much!
+"""]]

removed
diff --git a/doc/todo/Arch_Linux_Port/comment_3_d917de766dfe7fded7317d7614d1467f._comment b/doc/todo/Arch_Linux_Port/comment_3_d917de766dfe7fded7317d7614d1467f._comment
deleted file mode 100644
index 27ef807..0000000
--- a/doc/todo/Arch_Linux_Port/comment_3_d917de766dfe7fded7317d7614d1467f._comment
+++ /dev/null
@@ -1,25 +0,0 @@
-[[!comment format=mdwn
- username="joey"
- subject="""comment 3"""
- date="2017-02-04T20:55:02Z"
- content="""
-> Instead,  I changed some properties in DiskImage from Linux to
-> DebianLike.  Is it the correct way to do it?
-
-Looking at it, kpartx is DebianLike-specific, so imageBuiltFrom which uses it
-should be too. The only reason it wasn't marked as DebianLike already and
-was type Linux is because Linux used to be the same as DebianLike and so
-the type checker didn't see a difference. No longer, thanks to your patch.
-
-So, it makes complete sense that you have to change this. You're paying
-the price of blazing the trail of the first non-DebianLike Linux distro in
-Propellor..
-
----
-
-Looks like your [[!commit 25f6871e1dda3de252fbc6c8ac6962eb0cd9311a]]
-dealt with all my review suggestions. And so, I've merged it.
-
-Unless you have anything else that needs to be done, I'll release
-propellor soon with the added Arch Linux support. Thank you very much!
-"""]]

Remove additional space in url. Was not cloneable by copy&paste.
diff --git a/doc/install.mdwn b/doc/install.mdwn
index ad87ced..f64519a 100644
--- a/doc/install.mdwn
+++ b/doc/install.mdwn
@@ -1,4 +1,4 @@
-`git clone git://propellor.branchable.com/ propellor`  
+`git clone git://propellor.branchable.com/propellor`  
 Or get it [from github](https://github.com/joeyh/propellor).
 
 Propellor is recently available in Debian.

add news item for propellor 3.3.0
diff --git a/doc/news/version_3.1.2.mdwn b/doc/news/version_3.1.2.mdwn
deleted file mode 100644
index b54b396..0000000
--- a/doc/news/version_3.1.2.mdwn
+++ /dev/null
@@ -1,22 +0,0 @@
-propellor 3.1.2 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
- * [ Joey Hess ]
-   * Ssh.knownHost: Bug fix: Only fix up the owner of the known\_hosts
-     file after it exists.
- * [ Sean Whitton ]
-   * Sbuild.keypairInsecurelyGenerated: Improved to be more robust.
-   * Pass --allow-unrelated-histories to git merge when run with git 2.9 or
-     newer. This fixes the /usr/bin/propellor wrapper with this version of git.
-   * Sbuild.built &amp; Sbuild.builtFor no longer require Sbuild.keypairGenerated.
-     Transition guide: If you are using sbuild 0.70.0 or newer, you should
-     `rm -r /var/lib/sbuild/apt-keys`.  Otherwise, you should add either
-     Sbuild.keypairGenerated or Sbuild.keypairInsecurelyGenerated to your host.
-   * Sbuild haddock improvements:
-     - State that we don't support squeeze and Buntish older than trusty.
-       This is due to our enhancements, such as eatmydata.
-     - State that you need sbuild 0.70.0 or newer to build for stretch.
-       This is due to gpg2 hitting Debian stretch.
-     - Explain when a keygen is required.
-     - Update sample ~/.sbuildrc for sbuild 0.71.0.
-     - Add hint for customising chroots with propellor.
-     - Update example usage of System type."""]]
\ No newline at end of file
diff --git a/doc/news/version_3.3.0.mdwn b/doc/news/version_3.3.0.mdwn
new file mode 100644
index 0000000..19bd566
--- /dev/null
+++ b/doc/news/version_3.3.0.mdwn
@@ -0,0 +1,26 @@
+propellor 3.3.0 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Arch Linux is now supported by Propellor!
+     Thanks to Zihao Wang for this port.
+   * Added Propellor.Property.Pacman for Arch's package manager.
+     Maintained by Zihao Wang.
+   * The types of some properties changed; eg from Property DebianLike
+     to Property (DebianLike + ArchLinux). Also, DebianLike and Linux
+     are no longer type synonyms; propellor now knows that Linux includes
+     ArchLinux. This could require updates to code, so is a minor API change.
+   * GHC's fileSystemEncoding is used for all String IO, to avoid
+     encoding-related crashes in eg, Propellor.Property.File.
+   * Add --build option to simply build config.hs.
+   * More informative usage message. Thanks, Daniel Brooks
+   * Tor.hiddenService' added to support multiple ports.
+     Thanks, Félix Sipma.
+   * Apt.noPDiffs added.
+     Thanks, Sean Whitton.
+   * stack.yaml: Compile with GHC 8.0.1 against lts-7.16.
+     Thanks, Andrew Cowie.
+   * Added Propellor.Property.File.configFileName and related functions
+     to generate good filenames for config directories.
+   * Added Apt.suiteAvailablePinned, Apt.pinnedTo.
+     Thanks, Sean Whitton.
+   * Added File.containsBlock
+     Thanks, Sean Whitton."""]]
\ No newline at end of file

link to lwn article
diff --git a/doc/news/Linux.Conf.Au.presentation.mdwn b/doc/news/Linux.Conf.Au.presentation.mdwn
index 0041955..5418097 100644
--- a/doc/news/Linux.Conf.Au.presentation.mdwn
+++ b/doc/news/Linux.Conf.Au.presentation.mdwn
@@ -2,3 +2,4 @@
 
 [video](http://mirror.linux.org.au/pub/linux.conf.au/2017/Type_driven_configuration_management_with_Propellor.webm)
 
+Also see this writeup in [Linux Weekly News](https://lwn.net/Articles/713653/)

Added a comment
diff --git a/doc/todo/Arch_Linux_Port/comment_4_924c73c0ab6fb39c9b25ae51facf6bb6._comment b/doc/todo/Arch_Linux_Port/comment_4_924c73c0ab6fb39c9b25ae51facf6bb6._comment
new file mode 100644
index 0000000..f69e2c8
--- /dev/null
+++ b/doc/todo/Arch_Linux_Port/comment_4_924c73c0ab6fb39c9b25ae51facf6bb6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="wzhd"
+ avatar="http://cdn.libravatar.org/avatar/d5a499b7c476ca9960cc8dccdf455bae"
+ subject="comment 4"
+ date="2017-02-05T00:59:18Z"
+ content="""
+That's great! Thank you so much!
+"""]]

close
diff --git a/doc/todo/modify_Apt.pinnedTo_to_pin_a_package_to_multiple_suites_with_different_priorities.mdwn b/doc/todo/modify_Apt.pinnedTo_to_pin_a_package_to_multiple_suites_with_different_priorities.mdwn
index 047324c..02be4ad 100644
--- a/doc/todo/modify_Apt.pinnedTo_to_pin_a_package_to_multiple_suites_with_different_priorities.mdwn
+++ b/doc/todo/modify_Apt.pinnedTo_to_pin_a_package_to_multiple_suites_with_different_priorities.mdwn
@@ -3,3 +3,5 @@ Please consider merging the `pin` branch of `https://git.spwhitton.name/propello
 I've modified `Apt.pinnedTo` so that it can pin an `AptPrefPackage` to multiple suites with different pin priorities.  I've included a sample use-case in the function's haddock.
 
 --spwhitton
+
+> merged, [[done]] --[[Joey]]

mention Arch
diff --git a/doc/Linux.mdwn b/doc/Linux.mdwn
index 00276f6..ca0cfd6 100644
--- a/doc/Linux.mdwn
+++ b/doc/Linux.mdwn
@@ -1,5 +1,6 @@
 Propellor was written to manage Linux systems.
-It supports Debian and Debian-derived distributions.
+It supports Debian and Debian-derived distributions,
+as well as Arch Linux.
 
 Support for other distributions should not be too hard to add.
 Indeed, Propellor has been ported to [[FreeBSD]] now!

arch
diff --git a/doc/forum/Supported_OS/comment_3_f2924708a819b962ba7ed690019601ed._comment b/doc/forum/Supported_OS/comment_3_f2924708a819b962ba7ed690019601ed._comment
new file mode 100644
index 0000000..c03f6cd
--- /dev/null
+++ b/doc/forum/Supported_OS/comment_3_f2924708a819b962ba7ed690019601ed._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""Arch too!"""
+ date="2017-02-04T21:30:26Z"
+ content="""
+Propellor just got support for Arch Linux!
+"""]]

Arch Linux is now supported by Propellor! Thanks to Zihao Wang for this port.
* Arch Linux is now supported by Propellor!
Thanks to Zihao Wang for this port.
* Added Propellor.Property.Pacman for Arch's package manager.
Maintained by Zihao Wang.
* The types of some properties changed; eg from Property DebianLike
to Property (DebianLike + ArchLinux). This could require updates
to code using those properties, so is a minor API change.
diff --git a/debian/changelog b/debian/changelog
index 8136040..3a12ca7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,12 @@
-propellor (3.2.4) UNRELEASED; urgency=medium
-
+propellor (3.3.0) UNRELEASED; urgency=medium
+
+  * Arch Linux is now supported by Propellor!
+    Thanks to Zihao Wang for this port.
+  * Added Propellor.Property.Pacman for Arch's package manager.
+    Maintained by Zihao Wang.
+  * The types of some properties changed; eg from Property DebianLike
+    to Property (DebianLike + ArchLinux). This could require updates
+    to code using those properties, so is a minor API change.
   * GHC's fileSystemEncoding is used for all String IO, to avoid
     encoding-related crashes in eg, Propellor.Property.File.
   * Add --build option to simply build config.hs.
diff --git a/doc/todo/Arch_Linux_Port.mdwn b/doc/todo/Arch_Linux_Port.mdwn
index a899dbb..ac3ee4d 100644
--- a/doc/todo/Arch_Linux_Port.mdwn
+++ b/doc/todo/Arch_Linux_Port.mdwn
@@ -12,3 +12,5 @@ I've made some addtional minor changes to make propellor compile without errors:
 - Rsync.installed and Docker.installed now supports Pacman as well
 
 Hope you enjoy it!
+
+> [[merged|done]]; it was indeed enjoyable. thank you! --[[Joey]]
diff --git a/doc/todo/Arch_Linux_Port/comment_3_d917de766dfe7fded7317d7614d1467f._comment b/doc/todo/Arch_Linux_Port/comment_3_d917de766dfe7fded7317d7614d1467f._comment
new file mode 100644
index 0000000..27ef807
--- /dev/null
+++ b/doc/todo/Arch_Linux_Port/comment_3_d917de766dfe7fded7317d7614d1467f._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2017-02-04T20:55:02Z"
+ content="""
+> Instead,  I changed some properties in DiskImage from Linux to
+> DebianLike.  Is it the correct way to do it?
+
+Looking at it, kpartx is DebianLike-specific, so imageBuiltFrom which uses it
+should be too. The only reason it wasn't marked as DebianLike already and
+was type Linux is because Linux used to be the same as DebianLike and so
+the type checker didn't see a difference. No longer, thanks to your patch.
+
+So, it makes complete sense that you have to change this. You're paying
+the price of blazing the trail of the first non-DebianLike Linux distro in
+Propellor..
+
+---
+
+Looks like your [[!commit 25f6871e1dda3de252fbc6c8ac6962eb0cd9311a]]
+dealt with all my review suggestions. And so, I've merged it.
+
+Unless you have anything else that needs to be done, I'll release
+propellor soon with the added Arch Linux support. Thank you very much!
+"""]]
diff --git a/propellor.cabal b/propellor.cabal
index 1b5c46d..a33b982 100644
--- a/propellor.cabal
+++ b/propellor.cabal
@@ -1,5 +1,5 @@
 Name: propellor
-Version: 3.2.3
+Version: 3.3.0
 Cabal-Version: >= 1.8
 License: BSD2
 Maintainer: Joey Hess <id@joeyh.name>
@@ -128,6 +128,7 @@ Library
     Propellor.Property.Obnam
     Propellor.Property.OpenId
     Propellor.Property.OS
+    Propellor.Property.Pacman
     Propellor.Property.Parted
     Propellor.Property.Partition
     Propellor.Property.Postfix

submit merge request
diff --git a/doc/todo/modify_Apt.pinnedTo_to_pin_a_package_to_multiple_suites_with_different_priorities.mdwn b/doc/todo/modify_Apt.pinnedTo_to_pin_a_package_to_multiple_suites_with_different_priorities.mdwn
new file mode 100644
index 0000000..047324c
--- /dev/null
+++ b/doc/todo/modify_Apt.pinnedTo_to_pin_a_package_to_multiple_suites_with_different_priorities.mdwn
@@ -0,0 +1,5 @@
+Please consider merging the `pin` branch of `https://git.spwhitton.name/propellor` (again).
+
+I've modified `Apt.pinnedTo` so that it can pin an `AptPrefPackage` to multiple suites with different pin priorities.  I've included a sample use-case in the function's haddock.
+
+--spwhitton

Added a comment
diff --git a/doc/todo/Arch_Linux_Port/comment_2_cc4623c156a0d12c88461bc5deec07cd._comment b/doc/todo/Arch_Linux_Port/comment_2_cc4623c156a0d12c88461bc5deec07cd._comment
new file mode 100644
index 0000000..dc6e3eb
--- /dev/null
+++ b/doc/todo/Arch_Linux_Port/comment_2_cc4623c156a0d12c88461bc5deec07cd._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="wzhd"
+ avatar="http://cdn.libravatar.org/avatar/d5a499b7c476ca9960cc8dccdf455bae"
+ subject="comment 2"
+ date="2017-02-04T01:53:49Z"
+ content="""
+Thanks!
+
+
+I didn't find the right way to do it;  `pickOS` is so much easier than `withOS` !
+
+
+`Propellor.Property.Partition` was modified to get rid of some compiling errors in DiskImage and didn't support anything new. So I removed the changes.
+
+
+Instead,  I changed some properties in DiskImage from Linux to DebianLike.  Is it the correct way to do it?
+
+"""]]

response
diff --git a/doc/forum/Inherited_Variables.../comment_5_6fbd29f568ec8b97be47874e2aac57a3._comment b/doc/forum/Inherited_Variables.../comment_5_6fbd29f568ec8b97be47874e2aac57a3._comment
new file mode 100644
index 0000000..16819bd
--- /dev/null
+++ b/doc/forum/Inherited_Variables.../comment_5_6fbd29f568ec8b97be47874e2aac57a3._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 5"""
+ date="2017-02-03T19:32:58Z"
+ content="""
+What you're looking for is not a regexp, but Haskell's [pattern
+matching](https://www.haskell.org/tutorial/patterns.html).
+
+For example:
+
+	myproperty :: Property Debian
+	myproperty = withOS "some desc here" $ \w o -> case o of
+		-- Pattern match on the OS, to get the Debian stable release
+		(Just (System (Debian _kernel (Stable release)) _arch)) ->
+			ensureProperty w $ Apt.setSourcesListD (sourcesLines release) "mysources"
+		_ -> unsupportedOS
+
+	sourcesLines :: Release -> [Line]
+	sourcesLines release = undefined
+"""]]
diff --git a/src/Propellor/Property.hs b/src/Propellor/Property.hs
index 0614533..7860a3d 100644
--- a/src/Propellor/Property.hs
+++ b/src/Propellor/Property.hs
@@ -308,8 +308,8 @@ pickOS a b = c `addChildren` [toChildProperty a, toChildProperty b]
 --
 -- > myproperty :: Property Debian
 -- > myproperty = withOS "foo installed" $ \w o -> case o of
--- > 	(Just (System (Debian (Stable release)) arch)) -> ensureProperty w ...
--- > 	(Just (System (Debian suite) arch)) -> ensureProperty w ...
+-- > 	(Just (System (Debian kernel (Stable release)) arch)) -> ensureProperty w ...
+-- > 	(Just (System (Debian kernel suite) arch)) -> ensureProperty w ...
 -- >	_ -> unsupportedOS'
 --
 -- Note that the operating system specifics may not be declared for all hosts,

Added Apt.suiteAvailablePinned, Apt.pinnedTo. Thanks, Sean Whitton.
* Added Apt.suiteAvailablePinned, Apt.pinnedTo.
Thanks, Sean Whitton.
* Added File.containsBlock
Thanks, Sean Whitton.
diff --git a/debian/changelog b/debian/changelog
index 30af1b8..8136040 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -12,6 +12,10 @@ propellor (3.2.4) UNRELEASED; urgency=medium
     Thanks, Andrew Cowie.
   * Added Propellor.Property.File.configFileName and related functions
     to generate good filenames for config directories.
+  * Added Apt.suiteAvailablePinned, Apt.pinnedTo.
+    Thanks, Sean Whitton.
+  * Added File.containsBlock
+    Thanks, Sean Whitton.
 
  -- Joey Hess <id@joeyh.name>  Sat, 24 Dec 2016 15:06:36 -0400
 
diff --git a/doc/todo/new_apt_pinning_properties.mdwn b/doc/todo/new_apt_pinning_properties.mdwn
index d32bcbb..8687b58 100644
--- a/doc/todo/new_apt_pinning_properties.mdwn
+++ b/doc/todo/new_apt_pinning_properties.mdwn
@@ -6,3 +6,5 @@ My branch `pin` of repo `https://git.spwhitton.name/propellor` adds
 - a haddock for `File.containsLines`
 
 There is one TODO in a comment that relates to propellor's algebraic data types.  I'd be grateful for help with that.  --spwhitton
+
+> merged, thanks. [[done]] --[[Joey]]

review
diff --git a/doc/todo/Arch_Linux_Port/comment_1_8e39dc177e21e9e20c1b74b59b9926d2._comment b/doc/todo/Arch_Linux_Port/comment_1_8e39dc177e21e9e20c1b74b59b9926d2._comment
new file mode 100644
index 0000000..11869a2
--- /dev/null
+++ b/doc/todo/Arch_Linux_Port/comment_1_8e39dc177e21e9e20c1b74b59b9926d2._comment
@@ -0,0 +1,28 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2017-02-03T19:14:41Z"
+ content="""
+Wow, nice work!
+
+Seems that Propellor.Property.Partition.formatted' is still a DebianLike
+property really, since it only supports using apt to install the mkfs
+programs. It will fail at runtime on Arch. So, I think best to keep it
+DebianLike until that's dealt with -- and then the type will be 
+`DebianLike + ArchLinux` rather than `LinuxLike`
+
+Same for Propellor.Property.Partition.kpartx.
+
+Several properties that were changed from DebianLike to Linux really
+only support DebianLike and ArchLinux, not all linux distros, so their
+types ought to be `DebianLike + ArchLinux`. This includes Docker.installed,
+Parted.installed, Rsync.installed.
+
+A nicer way to inplement those multi-distro `installed` properties is like
+this:
+
+	installed :: Property (Debian + ArchLinux)
+	installed = Apt.installed ["foo"] `pickOS` Pacman.installed ["foo"]
+
+Make those changes and I will merge it.
+"""]]

Arch Linux Port
diff --git a/doc/todo/Arch_Linux_Port.mdwn b/doc/todo/Arch_Linux_Port.mdwn
new file mode 100644
index 0000000..a899dbb
--- /dev/null
+++ b/doc/todo/Arch_Linux_Port.mdwn
@@ -0,0 +1,14 @@
+Hi all, I'm an Arch Linux user and I've been learning Haskell and working on an Arch Liux Port in the last several months. Here's my [GitHub fork](https://github.com/wzhd/propellor/tree/archlinux), and the branch is called archlinux.
+
+Currently, I've added types, modified Bootstrap.hs, and added a Property for the package manager Pacman. I've been using it for a while and it seems to be working.
+
+I've made some addtional minor changes to make propellor compile without errors:
+
+- User.nuked now has type Property Linux
+- OS.cleanInstallOnce now has type Property DebianLike, because one of its dependencies, User.shadowConfig only supports DebianLike
+- tightenTargets is added to Reboot.toDistroKernel to get the expeted type
+- pattern for Arch Linux is added to Debootstrap.extractSuite to silence warning "non-exhaustive pattern match"
+- several properties in Parted and Partition are converted to Property Linux
+- Rsync.installed and Docker.installed now supports Pacman as well
+
+Hope you enjoy it!

Added a comment
diff --git a/doc/todo/new_apt_pinning_properties/comment_4_add83ed58963e944ccd705a50e8b5a47._comment b/doc/todo/new_apt_pinning_properties/comment_4_add83ed58963e944ccd705a50e8b5a47._comment
new file mode 100644
index 0000000..9688672
--- /dev/null
+++ b/doc/todo/new_apt_pinning_properties/comment_4_add83ed58963e944ccd705a50e8b5a47._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ avatar="http://cdn.libravatar.org/avatar/9c3f08f80e67733fd506c353239569eb"
+ subject="comment 4"
+ date="2017-02-03T04:07:58Z"
+ content="""
+> Yes please add a new type alias for String (or an ADT) if Package is not appropriate.
+
+Propellor won't be parsing any of the regexp or globs, so I've added a new type alias rather than an ADT.
+
+> Nice surprise that tightenTargets works on RevertableProperty at all. Since it does, you should be able to tighten one side, revert, tighten the other side, and re-revert. Or, deconstruct the RevertableProperty, tighten both sides individually, and reconstruct it.
+
+I don't understand what you're getting at with the first of these suggestions.
+
+In any case, now that I'm not using `File.containsBlock`, it's easy to just apply `tightenTargets` to each side.
+
+> I've added a Propellor.Property.File.configFileName that should be suitable for your purposes, and others..
+
+Very nice :)  I've updated my branch to use this.  I haven't removed `File.containsBlock`, since it might be useful in the future, but you could of course revert the relevant commit.
+"""]]

Added a comment
diff --git a/doc/forum/Inherited_Variables.../comment_4_5bf7b1f69b48b4d9c516d424e4438208._comment b/doc/forum/Inherited_Variables.../comment_4_5bf7b1f69b48b4d9c516d424e4438208._comment
new file mode 100644
index 0000000..3b691b2
--- /dev/null
+++ b/doc/forum/Inherited_Variables.../comment_4_5bf7b1f69b48b4d9c516d424e4438208._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="craige@a46118dff5bc0fad85259759970d8b4b9fc377d7"
+ nickname="craige"
+ avatar="http://cdn.libravatar.org/avatar/6d2207226de755da46aa2fdff9af70b2"
+ subject="comment 4"
+ date="2017-02-03T00:04:05Z"
+ content="""
+Ugh, sorry to ask again but I'm specifically stuck trying to extract the Debian suite only from this. Is this stored as a specific value I can draw on? I've been wading through the source and added in a swag of trial and error with no luck.
+
+I can see the suite listed in the output 
+
+    Just (System (Debian Linux (Stable \"jessie\"))
+
+but I was wondering if there was a method to pull out just the suite code name (ie: \"jessie\") that did not involve a regex looking for it amongst that output. 
+
+The goal is to query Info so that a suite name can be added to a sources list.
+
+If I have to regex, that's OK, I just didn't want to go down that path if there was a smarted way.
+
+Thanks Joey :-)
+"""]]

response
diff --git a/doc/todo/new_apt_pinning_properties/comment_3_58d323602f293471ce3d2d9b4d271130._comment b/doc/todo/new_apt_pinning_properties/comment_3_58d323602f293471ce3d2d9b4d271130._comment
new file mode 100644
index 0000000..b0ff271
--- /dev/null
+++ b/doc/todo/new_apt_pinning_properties/comment_3_58d323602f293471ce3d2d9b4d271130._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2017-02-02T18:45:01Z"
+ content="""
+That example with reverting one property overriding another property
+is a general problem propellor has with conflicting properties. 
+Normally I don't much worry about it, but I agree an accidental mass
+upgrade is a good reason to avoid that problem here.
+
+Yes please add a new type alias for String (or an ADT) 
+if Package is not appropriate.
+
+I had misunderstood which function the TODO was for..
+
+Nice surprise that tightenTargets works on RevertableProperty at all.
+Since it does, you should be able to tighten one side, revert, tighten the
+other side, and re-revert. Or, deconstruct the RevertableProperty, 
+tighten both sides individually, and reconstruct it.
+
+I've added a Propellor.Property.File.configFileName that 
+should be suitable for your purposes, and others..
+"""]]

Added a comment: reply to review
diff --git a/doc/todo/new_apt_pinning_properties/comment_2_c82f7e83f3fcc7648222d9dbf90e5ddd._comment b/doc/todo/new_apt_pinning_properties/comment_2_c82f7e83f3fcc7648222d9dbf90e5ddd._comment
new file mode 100644
index 0000000..4fd7c82
--- /dev/null
+++ b/doc/todo/new_apt_pinning_properties/comment_2_c82f7e83f3fcc7648222d9dbf90e5ddd._comment
@@ -0,0 +1,66 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ avatar="http://cdn.libravatar.org/avatar/9c3f08f80e67733fd506c353239569eb"
+ subject="reply to review"
+ date="2017-02-02T17:40:11Z"
+ content="""
+Thank you for your feedback, Joey.
+
+> I wonder if it would be better to separate `suiteAvailablePinned`
+> into `suiteAvailable` and `suitePinned`? The latter could require
+> the former.
+
+I see how this could be useful, in particular if you want to make a
+suite like Debian experimental available, which won't cause any packages
+to be automatically upgraded.
+
+However, it makes it less convenient, and perhaps dangerous, to revert a
+pinned suite.  For example, suppose on my Debian testing system I have
+`Apt.suitePinned Unstable 100`.  If I revert this property, it will
+remove the pin but not remove the source.  Then my system might get
+mass-upgraded to sid if I'm not careful.
+
+We couldn't have the revert of `Apt.suitePinned` remove the source
+because then if I have both `& Apt.suiteAvailable Unstable` and `!
+Apt.suitePinned Unstable 100`, the second property would cancel out the
+first, which doesn't make sense.
+
+On balance, I think it's best to keep the current property.  A property
+adding sources to apt.sources.d should probably force the user to pick a
+pin value, to avoid any unexpected upgrades.
+
+> `pinnedTo` should probably be DebianLike not UnixLike.
+
+This was my 'TODO'.  (Since the property takes a `DebianSuite`, I think
+it should be `Debian` not `DebianLike`.)
+
+I tried applying `tightenTargets` to `pinnedTo`, but that only seems to
+affect one half of the revertable property.  Do I need to implement a
+new tightening function?
+
+> And its `[String]` parameter ought to be `[Package]`.
+
+I don't think so.  The parameter to `pinnedTo` can be a wildcard
+expression or a regex (per `apt_preferences(5)`).  Neither of these are
+accepted by other existing properties that take `[Package]`, such as
+`Apt.installed`.  I could add a new type alias, if you prefer.
+
+> Is `File.containsBlock` necessary? Seems that if you care about
+> ordering of blocks in the file, you generally should use
+> `File.hasContent` to specify the full content. Rather than using
+> /etc/apt/preferences.d/10propellor.pref for multiple properties,
+> you could use a separate file for each `pinnedTo'` with the parameters
+> encoded in the filename.
+
+This was what I tried on my first attempt, but it gets very complicated
+if the user passes a wildcard expression or a regex instead of a package
+name.  I would need to convert that wildcard expression or regex to a
+cross-platform filename, and the conversion would need to be isomorphic
+to avoid any clashes.  The `File.containsBlock` seems more sane than
+that.
+
+> As to the TODO, I tried adding this: [...]
+
+I don't understand how `robustly` is relevant to my TODO -- please see
+above.
+"""]]

comment
diff --git a/doc/forum/Docker.hs_will_Break_in_Stretch/comment_1_8a4f16ae6d04b9d4bedb437ef333562b._comment b/doc/forum/Docker.hs_will_Break_in_Stretch/comment_1_8a4f16ae6d04b9d4bedb437ef333562b._comment
new file mode 100644
index 0000000..949f8d0
--- /dev/null
+++ b/doc/forum/Docker.hs_will_Break_in_Stretch/comment_1_8a4f16ae6d04b9d4bedb437ef333562b._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2017-02-02T17:28:49Z"
+ content="""
+Apparently the Debian way to install docker will be from backports.
+<https://bugs.debian.org/cgi-bin/bugreport.cgi?att=3;bug=781554;msg=9>
+
+Note that I'm no longer using any docker Properties myself, so
+propellor users who are will need to send patches..
+"""]]

diff --git a/doc/forum/Docker.hs_will_Break_in_Stretch.mdwn b/doc/forum/Docker.hs_will_Break_in_Stretch.mdwn
new file mode 100644
index 0000000..c89c995
--- /dev/null
+++ b/doc/forum/Docker.hs_will_Break_in_Stretch.mdwn
@@ -0,0 +1,16 @@
+G'day Joey!
+
+I'm in the process of deploying Docker infrastructure via Propellor on both Jessie and Stretch and I've come to discover that Docker.io did not make it into Stretch:
+
+* [docker.io REMOVED from testing](https://packages.qa.debian.org/d/docker.io/news/20161012T163916Z.html)
+* [docker.io - Linux container runtime](https://tracker.debian.org/pkg/docker.io)
+* [Excuse for docker.io](https://qa.debian.org/excuses.php?package=docker.io)
+
+So the below from Docker.hs will fail beyond Jessie:
+
+    installed :: Property DebianLike
+    installed = Apt.installed ["docker.io"]
+
+Before I embarked on my own path to re-implement the above (probably based on [How to install Docker engine on Debian 9 Stretch Linux](https://linuxconfig.org/how-to-install-docker-engine-on-debian-9-stretch-linux)), I thought I'd see what you thought might be the way to resolve this, so that my work could be contributed upstream (if suitable).
+
+Thanks!

comment
diff --git a/doc/todo/new_apt_pinning_properties/comment_1_fd9e6775868eaa8d6aee49d06944ef0c._comment b/doc/todo/new_apt_pinning_properties/comment_1_fd9e6775868eaa8d6aee49d06944ef0c._comment
new file mode 100644
index 0000000..4800608
--- /dev/null
+++ b/doc/todo/new_apt_pinning_properties/comment_1_fd9e6775868eaa8d6aee49d06944ef0c._comment
@@ -0,0 +1,38 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2017-02-01T20:00:47Z"
+ content="""
+I wonder if it would be better to separate `suiteAvailablePinned`
+into `suiteAvailable` and `suitePinned`? The latter could require
+the former.
+
+`pinnedTo` should probably be DebianLike not UnixLike.
+And its `[String]` parameter ought to be `[Package]`.
+
+Is `File.containsBlock` necessary? Seems that if you care about
+ordering of blocks in the file, you generally should use
+`File.hasContent` to specify the full content. Rather than using
+/etc/apt/preferences.d/10propellor.pref for multiple properties,
+you could use a separate file for each `pinnedTo'` with the parameters
+encoded in the filename.
+
+As to the TODO, I tried adding this:
+
+	robustly' :: RevertableProperty DebianLike DebianLike -> RevertableProperty DebianLike DebianLike
+	robustly' p = p `fallback` (update `before` p)
+
+And the compiler tells me it's wrong because `update` is not revertable.
+But of course, there's no need to revert apt-get update, so this compiles:
+
+	robustly' :: RevertableProperty DebianLike DebianLike -> RevertableProperty DebianLike DebianLike
+	robustly' p = p `fallback` ((update <!> (doNothing :: Property DebianLike)) `before` p)
+
+Cleaning it up left an an exersise for the reader. Might be possible
+to combine `robustly` and `robustly'` into a single function, but I'm
+not able to see how immediately.
+
+However.. Seems to me that whatever you wanted to use `robustly` with to
+spur that TODO, you could just apply it to the first Property of the
+RevertableProperty, and not to the second one?
+"""]]

submit branch
diff --git a/doc/todo/new_apt_pinning_properties.mdwn b/doc/todo/new_apt_pinning_properties.mdwn
new file mode 100644
index 0000000..d32bcbb
--- /dev/null
+++ b/doc/todo/new_apt_pinning_properties.mdwn
@@ -0,0 +1,8 @@
+My branch `pin` of repo `https://git.spwhitton.name/propellor` adds
+
+- `Apt.suiteAvailablePinned`
+- `Apt.pinnedTo`
+- `File.containsBlock`
+- a haddock for `File.containsLines`
+
+There is one TODO in a comment that relates to propellor's algebraic data types.  I'd be grateful for help with that.  --spwhitton

Added a comment: Thanks!
diff --git a/doc/forum/Inherited_Variables.../comment_3_acf78fa9f732f070bf73c2ab601464ee._comment b/doc/forum/Inherited_Variables.../comment_3_acf78fa9f732f070bf73c2ab601464ee._comment
new file mode 100644
index 0000000..fcdf923
--- /dev/null
+++ b/doc/forum/Inherited_Variables.../comment_3_acf78fa9f732f070bf73c2ab601464ee._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="craige"
+ avatar="http://cdn.libravatar.org/avatar/64ac5816ea3a51347d1f699022d1fdc1"
+ subject="Thanks!"
+ date="2017-01-27T21:54:45Z"
+ content="""
+Thanks Joey. I think that's exactly what I need. Very helpful :-)
+"""]]

example
diff --git a/doc/forum/Inherited_Variables.../comment_2_988319ed6de46eff2eac0d5ef36382f9._comment b/doc/forum/Inherited_Variables.../comment_2_988319ed6de46eff2eac0d5ef36382f9._comment
new file mode 100644
index 0000000..676f41a
--- /dev/null
+++ b/doc/forum/Inherited_Variables.../comment_2_988319ed6de46eff2eac0d5ef36382f9._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2017-01-26T06:50:39Z"
+ content="""
+A worked example:
+
+	server :: Property Debian
+	server = property' "some description" $ \w -> do
+		os <- getOS
+		hostname <- asks hostName
+		ensureProperty w $
+			File.hasContent "/etc/apt/sources.list.d/matrix.list"
+				(genSourcesList os hostname)
+"""]]
diff --git a/src/Propellor/Property/.Sbuild.hs.swp b/src/Propellor/Property/.Sbuild.hs.swp
new file mode 100644
index 0000000..a361c43
Binary files /dev/null and b/src/Propellor/Property/.Sbuild.hs.swp differ

response
diff --git a/doc/forum/Inherited_Variables.../comment_1_082e5d5b8e25335bc90577abcfef1d21._comment b/doc/forum/Inherited_Variables.../comment_1_082e5d5b8e25335bc90577abcfef1d21._comment
new file mode 100644
index 0000000..e4b3239
--- /dev/null
+++ b/doc/forum/Inherited_Variables.../comment_1_082e5d5b8e25335bc90577abcfef1d21._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2017-01-26T06:39:35Z"
+ content="""
+This is where propellor's `Info` system comes in. `Propellor.Info.getOS`
+can be run to get the OS info.
+
+It's also possible to add new properties that add new values with custom
+types to `Info`.
+
+The hostname is not currently stored in `Info`, but it probably should be;
+that would be a good simplification. Currently there's a 
+separate way to get the hostname: `asks hostName` (run in the Propellor monad)
+"""]]

diff --git a/doc/forum/Inherited_Variables....mdwn b/doc/forum/Inherited_Variables....mdwn
new file mode 100644
index 0000000..1535ec7
--- /dev/null
+++ b/doc/forum/Inherited_Variables....mdwn
@@ -0,0 +1,26 @@
+I've got a server defined in config.hs as follows:
+
+    myserver :: Host
+    myserver = host "myserver.mydomain" $ props
+        & standardSystem (Stable "jessie") X86_64 [ "Welcome to myserver!" ]
+
+I'm writing a module (to deploy Matrix, FWIW) which has a section like this:
+
+    sources :: Property Debian
+    sources = File.hasContent "/etc/apt/sources.list.d/matrix.list"
+                [ "# Deployed by Propellor"
+                , ""
+                , "deb http://matrix.org/packages/debian/ jessie main"
+                ] `onChange` Apt.update
+
+What I would like to be able to do, for example, is pull "jessie" from the standardSystem line into the sources function.
+
+The host name is another I'd like to be able to pull in, so that I can abstract as much as possible and wind up with a line that looks not unlike this:
+
+    & Matrix.server 
+
+Instead of
+
+    & Matrix.server hostname jessie
+
+Am I barking up the wrong tree and should I just embrace the latter?

diff --git a/doc/user/craige.mdwn b/doc/user/craige.mdwn
new file mode 100644
index 0000000..775e2fb
--- /dev/null
+++ b/doc/user/craige.mdwn
@@ -0,0 +1 @@
+It's been said I was the fourth user :-)

Added a comment: Fixed!
diff --git a/doc/forum/Modules_with_Multiple_cmdProperty_causing_build_failures/comment_2_5afe0f200d7139499ef4b01ea6445206._comment b/doc/forum/Modules_with_Multiple_cmdProperty_causing_build_failures/comment_2_5afe0f200d7139499ef4b01ea6445206._comment
new file mode 100644
index 0000000..00f7711
--- /dev/null
+++ b/doc/forum/Modules_with_Multiple_cmdProperty_causing_build_failures/comment_2_5afe0f200d7139499ef4b01ea6445206._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="craige@a46118dff5bc0fad85259759970d8b4b9fc377d7"
+ nickname="craige"
+ avatar="http://cdn.libravatar.org/avatar/6d2207226de755da46aa2fdff9af70b2"
+ subject="Fixed!"
+ date="2017-01-26T05:54:22Z"
+ content="""
+The original suggestions did fix my problems. 
+
+Apologies for the late response.
+"""]]

add
diff --git a/doc/news/Linux.Conf.Au.presentation.mdwn b/doc/news/Linux.Conf.Au.presentation.mdwn
new file mode 100644
index 0000000..0041955
--- /dev/null
+++ b/doc/news/Linux.Conf.Au.presentation.mdwn
@@ -0,0 +1,4 @@
+<video controls src="http://mirror.linux.org.au/pub/linux.conf.au/2017/Type_driven_configuration_management_with_Propellor.webm"></video>
+
+[video](http://mirror.linux.org.au/pub/linux.conf.au/2017/Type_driven_configuration_management_with_Propellor.webm)
+

update
diff --git a/doc/todo/hostChroot.mdwn b/doc/todo/hostChroot.mdwn
index 55fa689..eccfd64 100644
--- a/doc/todo/hostChroot.mdwn
+++ b/doc/todo/hostChroot.mdwn
@@ -2,3 +2,6 @@ Would be useful to have a `hostChroot :: Host -> Chroot`.
 
 For a Debian host, this would use debootstrapped and pass all the Host's
 properties to it. --[[Joey]] 
+
+Would need to make privdata use the context of the input Host. And would
+need to propigate privdata info, but not other info. --[[Joey]]

too
diff --git a/doc/todo/hostChroot.mdwn b/doc/todo/hostChroot.mdwn
new file mode 100644
index 0000000..55fa689
--- /dev/null
+++ b/doc/todo/hostChroot.mdwn
@@ -0,0 +1,4 @@
+Would be useful to have a `hostChroot :: Host -> Chroot`.
+
+For a Debian host, this would use debootstrapped and pass all the Host's
+properties to it. --[[Joey]] 

add missing props to Host definitions
diff --git a/doc/haskell_newbie.mdwn b/doc/haskell_newbie.mdwn
index d6e339e..dc3c54a 100644
--- a/doc/haskell_newbie.mdwn
+++ b/doc/haskell_newbie.mdwn
@@ -47,12 +47,12 @@ Finally, you need to define the configuration for each host in the list:
 
 [[!format haskell """
 mylaptop :: Host
-mylaptop = host "mylaptop.example.com"
+mylaptop = host "mylaptop.example.com" $ props
 	& osDebian Unstable X86_64
 	& Apt.stdSourcesList
 
 myserver :: Host
-myserver = host "server.example.com"
+myserver = host "server.example.com" $ props
 	& osDebian (Stable "jessie") X86_64
 	& Apt.stdSourcesList
 	& Apt.installed ["ssh"]

Added a comment
diff --git a/doc/todo/Merging_from___47__usr__47__src__47__propellor_broken_now_CHANGELOG_not_a_symlink/comment_2_61463030200038542d293149754d36ed._comment b/doc/todo/Merging_from___47__usr__47__src__47__propellor_broken_now_CHANGELOG_not_a_symlink/comment_2_61463030200038542d293149754d36ed._comment
new file mode 100644
index 0000000..b1b4a03
--- /dev/null
+++ b/doc/todo/Merging_from___47__usr__47__src__47__propellor_broken_now_CHANGELOG_not_a_symlink/comment_2_61463030200038542d293149754d36ed._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ avatar="http://cdn.libravatar.org/avatar/9c3f08f80e67733fd506c353239569eb"
+ subject="comment 2"
+ date="2017-01-03T09:07:18Z"
+ content="""
+Thanks for looking at this.  Yes, it's probably the type-change.  There is surely some way to instruct git to DTRT.
+"""]]

comment
diff --git a/doc/todo/Merging_from___47__usr__47__src__47__propellor_broken_now_CHANGELOG_not_a_symlink/comment_1_62b47d7c0530c2988b7e6e998878b920._comment b/doc/todo/Merging_from___47__usr__47__src__47__propellor_broken_now_CHANGELOG_not_a_symlink/comment_1_62b47d7c0530c2988b7e6e998878b920._comment
new file mode 100644
index 0000000..886c253
--- /dev/null
+++ b/doc/todo/Merging_from___47__usr__47__src__47__propellor_broken_now_CHANGELOG_not_a_symlink/comment_1_62b47d7c0530c2988b7e6e998878b920._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2017-01-01T21:29:52Z"
+ content="""
+I have reverted that change for now.
+
+I don't think the /usr/src/propellor/ merge has anything specific to do
+with the changelog, so there is probably a general case where that merge
+fails to work. I guess it involves a file's type changing.
+"""]]

report bug
diff --git a/doc/todo/Merging_from___47__usr__47__src__47__propellor_broken_now_CHANGELOG_not_a_symlink.mdwn b/doc/todo/Merging_from___47__usr__47__src__47__propellor_broken_now_CHANGELOG_not_a_symlink.mdwn
new file mode 100644
index 0000000..bfba854
--- /dev/null
+++ b/doc/todo/Merging_from___47__usr__47__src__47__propellor_broken_now_CHANGELOG_not_a_symlink.mdwn
@@ -0,0 +1,36 @@
+In Joey's master branch, `CHANGELOG` is a real file, whereas previously it was a symlink.  This breaks the `/usr/src/propellor` newer version check.
+
+Steps to reproduce:
+
+1. Install propellor 3.2.3 or older with apt on Debian or Ubuntu
+2. `propellor --init` and select option `A`
+3. Prepare a pseudorelease: merge Joey's master branch into [my Debian packaging branch](https://git.spwhitton.name/?p=propellor.git;a=shortlog;h=refs/heads/debian), `dch -v3.2.3+gitYYYYMMDD.fffffff`, `dpkg-buildpackage -uc -b`, `debi -u`
+4. `propellor --spin`
+
+I haven't yet tried reproducing this by building a `.deb` from Joey's master branch, rather than my packaging branch.  If the problem does not appear using a `.deb` from Joey's master branch, this is an internal Debian problem, rather than an upstream bug.  However, perhaps Joey can immediately see a solution.
+
+Sample output:
+
+    Auto-merging src/wrapper.hs
+    Auto-merging src/Utility/UserInfo.hs
+    Auto-merging src/Utility/SystemDirectory.hs
+    Auto-merging src/Utility/Misc.hs
+    Auto-merging src/Utility/FileSystemEncoding.hs
+    Auto-merging src/Utility/Exception.hs
+    Auto-merging src/Propellor/Types/CmdLine.hs
+    Auto-merging src/Propellor/Shim.hs
+    Auto-merging src/Propellor/Property/Gpg.hs
+    Auto-merging src/Propellor/Property/Debootstrap.hs
+    Auto-merging src/Propellor/Property.hs
+    Auto-merging src/Propellor/PrivData.hs
+    Auto-merging src/Propellor/Gpg.hs
+    Auto-merging src/Propellor/CmdLine.hs
+    Auto-merging debian/changelog
+    Auto-merging CHANGELOG
+    CONFLICT (add/add): Merge conflict in CHANGELOG
+    Automatic merge failed; fix conflicts and then commit the result.
+    propellor: Failed to run git ["merge","c590ddd8e2fa87baa409b6c29501d4473555ecfb","-s","recursive","-Xtheirs","--quiet","-m","merging upstream version","--allow-unrelated-histories"]
+    CallStack (from HasCallStack):
+      error, called at src/Propellor/DotDir.hs:425:17 in main:Propellor.DotDir
+
+--spwhitton

More informative usage message. Thanks, Daniel Brooks
diff --git a/CHANGELOG b/CHANGELOG
index f41c556..eef6c1d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,6 +3,7 @@ propellor (3.2.4) UNRELEASED; urgency=medium
   * GHC's fileSystemEncoding is used for all String IO, to avoid
     encoding-related crashes in eg, Propellor.Property.File.
   * Add --build option to simply build config.hs.
+  * More informative usage message. Thanks, Daniel Brooks
 
  -- Joey Hess <id@joeyh.name>  Sat, 24 Dec 2016 15:06:36 -0400
 
diff --git a/doc/todo/usage__47__help_text_improvements.mdwn b/doc/todo/usage__47__help_text_improvements.mdwn
index 8ffca2c..80fffb3 100644
--- a/doc/todo/usage__47__help_text_improvements.mdwn
+++ b/doc/todo/usage__47__help_text_improvements.mdwn
@@ -1 +1,3 @@
 I started out looking at how to make usage.mdwn into a man page, but that's a little more work than I wanted to do tonight. Instead, I added more information to the usage message. Commit is fa0e8d83 on iabak:~db48x/propellor if you want it.
+
+> merged [[done]] tnx --[[Joey]] 

Added a comment
diff --git a/doc/todo/usage__47__help_text_improvements/comment_2_d531a45851cdef87a8f7b8182b3d04ce._comment b/doc/todo/usage__47__help_text_improvements/comment_2_d531a45851cdef87a8f7b8182b3d04ce._comment
new file mode 100644
index 0000000..62cf1fe
--- /dev/null
+++ b/doc/todo/usage__47__help_text_improvements/comment_2_d531a45851cdef87a8f7b8182b3d04ce._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="db48x"
+ avatar="http://cdn.libravatar.org/avatar/ad2688127feb555a92154b16d8eeb5d3"
+ subject="comment 2"
+ date="2016-12-27T06:12:52Z"
+ content="""
+/me facepalms; of course it can. I guess I saw the 'git commit' in the install target and disregarded the rest.
+
+I removed the tabs from the usage. It's a lot longer, but I suppose it gets the job done.
+
+
+"""]]

comment
diff --git a/doc/todo/usage__47__help_text_improvements/comment_1_66878945cdb57d06849337262d939701._comment b/doc/todo/usage__47__help_text_improvements/comment_1_66878945cdb57d06849337262d939701._comment
new file mode 100644
index 0000000..f30eae4
--- /dev/null
+++ b/doc/todo/usage__47__help_text_improvements/comment_1_66878945cdb57d06849337262d939701._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2016-12-27T02:46:19Z"
+ content="""
+I don't like the use of tabs in that; it may be that with some terminal
+with an unusual tab stop, the things don't align.
+
+It would probably be simplest to put the description in the line under the
+option.
+
+BTW, the Makefile can build propellor.1 out of usage.mdwn
+"""]]

diff --git a/doc/todo/usage__47__help_text_improvements.mdwn b/doc/todo/usage__47__help_text_improvements.mdwn
new file mode 100644
index 0000000..8ffca2c
--- /dev/null
+++ b/doc/todo/usage__47__help_text_improvements.mdwn
@@ -0,0 +1 @@
+I started out looking at how to make usage.mdwn into a man page, but that's a little more work than I wanted to do tonight. Instead, I added more information to the usage message. Commit is fa0e8d83 on iabak:~db48x/propellor if you want it.

Added a comment: aha
diff --git a/doc/todo/Are_--check_and_--build_on_the_way_in_or_on_the_way_out__63__/comment_2_b4910f50225a8b763566126861faea11._comment b/doc/todo/Are_--check_and_--build_on_the_way_in_or_on_the_way_out__63__/comment_2_b4910f50225a8b763566126861faea11._comment
new file mode 100644
index 0000000..0c59448
--- /dev/null
+++ b/doc/todo/Are_--check_and_--build_on_the_way_in_or_on_the_way_out__63__/comment_2_b4910f50225a8b763566126861faea11._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="db48x"
+ avatar="http://cdn.libravatar.org/avatar/ad2688127feb555a92154b16d8eeb5d3"
+ subject="aha"
+ date="2016-12-26T21:23:03Z"
+ content="""
+Thanks!
+"""]]

comment and close
diff --git a/doc/todo/Are_--check_and_--build_on_the_way_in_or_on_the_way_out__63__.mdwn b/doc/todo/Are_--check_and_--build_on_the_way_in_or_on_the_way_out__63__.mdwn
index fdba057..52b3b99 100644
--- a/doc/todo/Are_--check_and_--build_on_the_way_in_or_on_the_way_out__63__.mdwn
+++ b/doc/todo/Are_--check_and_--build_on_the_way_in_or_on_the_way_out__63__.mdwn
@@ -1 +1,3 @@
 I've managed to do a few useful things with propellor, but it feels a bit rough around the edges to me. It looked at first like the --check and --build options would be useful for checking that my configs would at least compile, but it turns out that --build doesn't even exist and --check just returns without doing anything. Should they just be removed, or do they need more work to finish them?
+
+[[done]]
diff --git a/doc/todo/Are_--check_and_--build_on_the_way_in_or_on_the_way_out__63__/comment_1_7c2b2447254ad44ee1316b47eac130df._comment b/doc/todo/Are_--check_and_--build_on_the_way_in_or_on_the_way_out__63__/comment_1_7c2b2447254ad44ee1316b47eac130df._comment
new file mode 100644
index 0000000..392f0f1
--- /dev/null
+++ b/doc/todo/Are_--check_and_--build_on_the_way_in_or_on_the_way_out__63__/comment_1_7c2b2447254ad44ee1316b47eac130df._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2016-12-26T15:55:36Z"
+ content="""
+--check does just what it's supposed to do. This is used during bootstrap
+to notice if the propellor binary has gotten broken by changes to eg system
+libraries.
+
+--build seems to have been added without being implemented.  But it does
+seem  useful to have a way to simply build propellor so implemented it now.
+"""]]

Added --build option, which makes propellor simply build itself.
diff --git a/debian/changelog b/debian/changelog
index cb313e2..765f44c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+propellor (3.2.4) UNRELEASED; urgency=medium
+
+  * Added --build option, which makes propellor simply build itself.
+
+ -- Joey Hess <id@joeyh.name>  Mon, 26 Dec 2016 12:03:19 -0400
+
 propellor (3.2.3) unstable; urgency=medium
 
   * Improve extraction of gpg secret key id list, to work with gpg 2.1.
diff --git a/doc/usage.mdwn b/doc/usage.mdwn
index fc1f839..3d32538 100644
--- a/doc/usage.mdwn
+++ b/doc/usage.mdwn
@@ -55,6 +55,14 @@ and configured in haskell.
   The hostname given to --spin can be a short name, which is
   then looked up in the DNS to find the FQDN.
 
+* propellor --build
+
+  Causes propellor to build itself, checking that your config.hs, etc are
+  valid.
+
+  You do not need to run this as a separate step; propellor automatically
+  builds itself when using things like --spin.
+
 * propellor --add-key keyid
 
   Adds a gpg key, which is used to encrypt the privdata.
diff --git a/src/Propellor/CmdLine.hs b/src/Propellor/CmdLine.hs
index 448abf6..7840cc3 100644
--- a/src/Propellor/CmdLine.hs
+++ b/src/Propellor/CmdLine.hs
@@ -26,6 +26,7 @@ usage h = hPutStrLn h $ unlines
 	, "  propellor --init"
 	, "  propellor"
 	, "  propellor --spin targethost [--via relayhost]"
+	, "  propellor --build"
 	, "  propellor --add-key keyid"
 	, "  propellor --rm-key keyid"
 	, "  propellor --list-fields"
@@ -53,6 +54,7 @@ processCmdLine = go =<< getArgs
 			<$> mapM hostname (reverse hs)
 			<*> pure (Just r)
 		_ -> Spin <$> mapM hostname ps <*> pure Nothing
+	go ("--build":[]) = return Build
 	go ("--add-key":k:[]) = return $ AddKey k
 	go ("--rm-key":k:[]) = return $ RmKey k
 	go ("--set":f:c:[]) = withprivfield f c Set
@@ -101,6 +103,7 @@ defaultMain hostlist = withConcurrentOutput $ do
   where
 	go cr (Serialized cmdline) = go cr cmdline
 	go _ Check = return ()
+	go cr Build = buildFirst Nothing cr Build $ return ()
 	go _ (Set field context) = setPrivData field context
 	go _ (Unset field context) = unsetPrivData field context
 	go _ (UnsetUnused) = unsetPrivDataUnused hostlist
diff --git a/src/Propellor/Types/CmdLine.hs b/src/Propellor/Types/CmdLine.hs
index 558c6e8..d712a45 100644
--- a/src/Propellor/Types/CmdLine.hs
+++ b/src/Propellor/Types/CmdLine.hs
@@ -28,4 +28,5 @@ data CmdLine
 	| ChrootChain HostName FilePath Bool Bool
 	| GitPush Fd Fd
 	| Check
+	| Build
 	deriving (Read, Show, Eq)

get usage and man page back in sync
Remove --build which is no longer present.
Order the list of options the same.
Document --rm-key in man page.
diff --git a/doc/usage.mdwn b/doc/usage.mdwn
index fec346a..fc1f839 100644
--- a/doc/usage.mdwn
+++ b/doc/usage.mdwn
@@ -66,6 +66,10 @@ and configured in haskell.
   using this key. Propellor requires signed commits when pulling from
   a central git repository.
 
+* propellor --rm-key keyid
+
+  Stops encrypting the privdata to a gpg key.
+
 * propellor --list-fields
 
   Lists all privdata fields that are used by your propellor configuration.
diff --git a/src/Propellor/CmdLine.hs b/src/Propellor/CmdLine.hs
index fc25610..448abf6 100644
--- a/src/Propellor/CmdLine.hs
+++ b/src/Propellor/CmdLine.hs
@@ -25,19 +25,18 @@ usage h = hPutStrLn h $ unlines
 	[ "Usage:"
 	, "  propellor --init"
 	, "  propellor"
-	, "  propellor hostname"
 	, "  propellor --spin targethost [--via relayhost]"
 	, "  propellor --add-key keyid"
 	, "  propellor --rm-key keyid"
 	, "  propellor --list-fields"
-	, "  propellor --dump field context"
-	, "  propellor --edit field context"
 	, "  propellor --set field context"
 	, "  propellor --unset field context"
 	, "  propellor --unset-unused"
+	, "  propellor --dump field context"
+	, "  propellor --edit field context"
 	, "  propellor --merge"
-	, "  propellor --build"
 	, "  propellor --check"
+	, "  propellor hostname"
 	]
 
 usageError :: [String] -> IO a

moderately confused
diff --git a/doc/todo/Are_--check_and_--build_on_the_way_in_or_on_the_way_out__63__.mdwn b/doc/todo/Are_--check_and_--build_on_the_way_in_or_on_the_way_out__63__.mdwn
new file mode 100644
index 0000000..fdba057
--- /dev/null
+++ b/doc/todo/Are_--check_and_--build_on_the_way_in_or_on_the_way_out__63__.mdwn
@@ -0,0 +1 @@
+I've managed to do a few useful things with propellor, but it feels a bit rough around the edges to me. It looked at first like the --check and --build options would be useful for checking that my configs would at least compile, but it turns out that --build doesn't even exist and --check just returns without doing anything. Should they just be removed, or do they need more work to finish them?

Added a comment: Cache gpg passphrase.
diff --git a/doc/forum/propellor_and_gpg2/comment_1_4b732110f59f78f73fdfb745bdd9c0dd._comment b/doc/forum/propellor_and_gpg2/comment_1_4b732110f59f78f73fdfb745bdd9c0dd._comment
new file mode 100644
index 0000000..66c4cff
--- /dev/null
+++ b/doc/forum/propellor_and_gpg2/comment_1_4b732110f59f78f73fdfb745bdd9c0dd._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="anselmi@0a9758305bef5e058dd0263fa20a27b334b482c7"
+ nickname="anselmi"
+ avatar="http://cdn.libravatar.org/avatar/65b723eb35eb4e3b05fffafd3e13e0fd"
+ subject="Cache gpg passphrase."
+ date="2016-12-22T17:23:58Z"
+ content="""
+The bottom line on this is that gpg2 (via the agent and pinentry) doesn't prompt correctly when run from git. It does when run directly.
+
+One fix is to set GPG_TTY before running propellor: `export GPG_TTY=$(tty)` or some such.
+
+Anything else that caches the pass phrase in the agent works too since that removes the need to prompt.
+"""]]

typo
diff --git a/doc/todo/Add_MonadBaseControl_instance_to_Propellor/comment_3_45413e6e811c34edc38a6ff70ca7c208._comment b/doc/todo/Add_MonadBaseControl_instance_to_Propellor/comment_3_45413e6e811c34edc38a6ff70ca7c208._comment
index 58106f6..74a5c8b 100644
--- a/doc/todo/Add_MonadBaseControl_instance_to_Propellor/comment_3_45413e6e811c34edc38a6ff70ca7c208._comment
+++ b/doc/todo/Add_MonadBaseControl_instance_to_Propellor/comment_3_45413e6e811c34edc38a6ff70ca7c208._comment
@@ -25,16 +25,17 @@ Writers and/or two States, that need to be merged somehow. I don't see
 anything in the library that lets it do an intelligent merge. (For example,
 it could notice that [EndAction] is a monoid and mappend the two values.)
 
-So, I think when it says it's arestoring the monadic effects, it means it's
+So, I think when it says it's a restoring the monadic effects, it means it's
 *discarding* any changes that might have been made to the Writer or State.
 
-Is this a large problem for propellor? Maybe not. EndActions rarely need to
+Is this a large problem for Propellor? Maybe not. EndActions rarely need to
 be added, and in fact only one property in all of Propellor currently adds
-an EndAction.
+an EndAction. But this could change; Propellor could get state in its
+monad. What then?
 
 Now, I actually dealt with this problem in the
 Propellor.Property.Concurrent module. The code there threads the Writer
-values through the concurrent actions and merges them at the end. If
+v alues through the concurrent actions and merges them at the end. If
 MonadBaseControl provides a more principled way to do that, which lets
 lifted-async also be used safely, then that part of propellor could perhaps
 be changed to use it.