From 605b301429c36a3a9ff9f921f69196c429e70224 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 11 Feb 2018 17:49:18 -0400 Subject: add missing period --- src/Propellor/Property/Atomic.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Propellor/Property/Atomic.hs b/src/Propellor/Property/Atomic.hs index 5db17474..8519048b 100644 --- a/src/Propellor/Property/Atomic.hs +++ b/src/Propellor/Property/Atomic.hs @@ -144,7 +144,7 @@ checkDirLink d rp = liftIO $ do -- Using atomicDirSync in the above example lets git only download -- the changes once, rather than the same changes being downloaded a second -- time to update the other copy of the directory the next time propellor --- runs +-- runs. -- -- Suppose that a web server program is run from the git repository, -- and needs to be restarted after the pull. That restart should be done -- cgit v1.3-2-g0d8e From c5785263996a88dbceee664805714ed5ed16c302 Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Fri, 16 Feb 2018 18:16:21 -0700 Subject: Systemd.machined should install systemd-container on Debian stretch Signed-off-by: Sean Whitton --- src/Propellor/Property/Systemd.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Propellor/Property/Systemd.hs b/src/Propellor/Property/Systemd.hs index 51d1313c..8fa236d2 100644 --- a/src/Propellor/Property/Systemd.hs +++ b/src/Propellor/Property/Systemd.hs @@ -205,8 +205,8 @@ machined = withOS "machined installed" $ \w o -> case o of -- Split into separate debian package since systemd 225. (Just (System (Debian _ suite) _)) - | not (isStable suite) -> ensureProperty w $ - Apt.installed ["systemd-container"] + | not (isStable suite) || suite == (Stable "stretch") -> + ensureProperty w $ Apt.installed ["systemd-container"] _ -> noChange -- | Defines a container with a given machine name, -- cgit v1.3-2-g0d8e From 98dad1f10e92424871f7356469f42481b40256a6 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 19 Feb 2018 11:55:44 -0400 Subject: comment typo --- src/Propellor/DotDir.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Propellor/DotDir.hs b/src/Propellor/DotDir.hs index f62b38f8..17eb095a 100644 --- a/src/Propellor/DotDir.hs +++ b/src/Propellor/DotDir.hs @@ -389,7 +389,7 @@ checkRepoUpToDate = whenM (gitbundleavail <&&> dotpropellorpopulated) $ do -- -- If there's no upstream/master, the user is not using the distrepo, -- so do nothing. And, if there's a remote named "upstream", the user --- must have set that up is not using the distrepo, so do nothing. +-- must have set that up and is not using the distrepo, so do nothing. updateUpstreamMaster :: String -> IO () updateUpstreamMaster newref = unlessM (hasRemote "upstream") $ do changeWorkingDirectory =<< dotPropellor -- cgit v1.3-2-g0d8e From 6f18e665ca8d960a77e437d8edec8f3d14169585 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 19 Feb 2018 12:46:16 -0400 Subject: Warn again about new upstream version when ~/.propellor was cloned from the Debian git bundle using an older version of propellor that set up an upstream remote. This commit was sponsored by Jake Vosloo on Patreon. --- debian/changelog | 8 ++++ ...nt_12_aea497eeecb077659db3f1dfb1e5f289._comment | 20 ++++++++++ src/Propellor/DotDir.hs | 45 +++++++++++++++++----- src/Propellor/Git.hs | 4 ++ 4 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 doc/forum/__42____42___warning:___42____42___Your___126____47__.propellor__47___is_out_of_date../comment_12_aea497eeecb077659db3f1dfb1e5f289._comment (limited to 'src') diff --git a/debian/changelog b/debian/changelog index 3515497b..55ca5a93 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +propellor (5.3.3) UNRELEASED; urgency=medium + + * Warn again about new upstream version when ~/.propellor was cloned from the + Debian git bundle using an older version of propellor that set up an + upstream remote. + + -- Joey Hess Mon, 19 Feb 2018 12:44:24 -0400 + propellor (5.3.2) unstable; urgency=medium * Added Propellor.Property.Atomic, which can make a non-atomic property diff --git a/doc/forum/__42____42___warning:___42____42___Your___126____47__.propellor__47___is_out_of_date../comment_12_aea497eeecb077659db3f1dfb1e5f289._comment b/doc/forum/__42____42___warning:___42____42___Your___126____47__.propellor__47___is_out_of_date../comment_12_aea497eeecb077659db3f1dfb1e5f289._comment new file mode 100644 index 00000000..90d0ba2c --- /dev/null +++ b/doc/forum/__42____42___warning:___42____42___Your___126____47__.propellor__47___is_out_of_date../comment_12_aea497eeecb077659db3f1dfb1e5f289._comment @@ -0,0 +1,20 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 12""" + date="2018-02-19T15:48:21Z" + content=""" +What propellor --init sets up, when you select the clone option +and the Debian package is installed, is no remote +defined, but a remotes/upsteam/master tracking branch. + +So not normally this: + + upstream /usr/src/propellor/propellor.git (fetch) + +Aha! The very first revision of propellor --init +*did* set up an upstream remote pointing at the distrepo. At some point +that changed to the above described behavior. You're bitten by being an +early adopter. + +I've adjusted the logic to handle that case. +"""]] diff --git a/src/Propellor/DotDir.hs b/src/Propellor/DotDir.hs index 17eb095a..39c111f6 100644 --- a/src/Propellor/DotDir.hs +++ b/src/Propellor/DotDir.hs @@ -387,16 +387,17 @@ checkRepoUpToDate = whenM (gitbundleavail <&&> dotpropellorpopulated) $ do -- into the user's repository, as if fetching from a upstream remote, -- yielding a new upstream/master branch. -- --- If there's no upstream/master, the user is not using the distrepo, --- so do nothing. And, if there's a remote named "upstream", the user --- must have set that up and is not using the distrepo, so do nothing. +-- If there's no upstream/master, or the repo is not using the distrepo, +-- do nothing. updateUpstreamMaster :: String -> IO () -updateUpstreamMaster newref = unlessM (hasRemote "upstream") $ do +updateUpstreamMaster newref = do changeWorkingDirectory =<< dotPropellor - go =<< catchMaybeIO getoldrev + v <- getoldrev + case v of + Nothing -> return () + Just oldref -> go oldref where - go Nothing = return () - go (Just oldref) = do + go oldref = do let tmprepo = ".git/propellordisttmp" let cleantmprepo = void $ catchMaybeIO $ removeDirectoryRecursive tmprepo cleantmprepo @@ -421,13 +422,37 @@ updateUpstreamMaster newref = unlessM (hasRemote "upstream") $ do cleantmprepo warnoutofdate True - getoldrev = takeWhile (/= '\n') - <$> readProcess "git" ["show-ref", upstreambranch, "--hash"] - git = run "git" run cmd ps = unlessM (boolSystem cmd (map Param ps)) $ error $ "Failed to run " ++ cmd ++ " " ++ show ps + -- Get ref that the upstreambranch points to, only when + -- the distrepo is being used. + getoldrev = do + mrev <- catchMaybeIO $ takeWhile (/= '\n') + <$> readProcess "git" ["show-ref", upstreambranch, "--hash"] + print mrev + case mrev of + Just _ -> do + -- Normally there will be no upstream + -- remote when the distrepo is used. + -- Older versions of propellor set up + -- an upstream remote pointing at the + -- distrepo. + ifM (hasRemote "upstream") + ( do + v <- remoteUrl "upstream" + print ("remote url", v) + return $ case v of + Just rurl | rurl == distrepo -> mrev + _ -> Nothing + , return mrev + ) + Nothing -> return mrev + +-- And, if there's a remote named "upstream" +-- that does not point at the distrepo, the user must have set that up +-- and is not using the distrepo, so do nothing. warnoutofdate :: Bool -> IO () warnoutofdate havebranch = do warningMessage ("** Your ~/.propellor/ is out of date..") diff --git a/src/Propellor/Git.hs b/src/Propellor/Git.hs index 10b88ddd..c446f67a 100644 --- a/src/Propellor/Git.hs +++ b/src/Propellor/Git.hs @@ -30,6 +30,10 @@ hasRemote remotename = catchDefaultIO False $ do rs <- lines <$> readProcess "git" ["remote"] return $ remotename `elem` rs +remoteUrl :: String -> IO (Maybe String) +remoteUrl remotename = catchDefaultIO Nothing $ headMaybe . lines + <$> readProcess "git" ["config", "remote." ++ remotename ++ ".url"] + hasGitRepo :: IO Bool hasGitRepo = doesFileExist ".git/HEAD" -- cgit v1.3-2-g0d8e From 335b5fba4f86929836c9eb59baa8fbd0d311dcf8 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 19 Feb 2018 12:49:03 -0400 Subject: output warning message atomically Before part went to stderr and part to stdout, and the two parts could be reordered in some cases, particularly when concurrent output caused them to be buffered. This commit was sponsored by Trenton Cronholm on Patreon. --- src/Propellor/DotDir.hs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/Propellor/DotDir.hs b/src/Propellor/DotDir.hs index 39c111f6..be5d614d 100644 --- a/src/Propellor/DotDir.hs +++ b/src/Propellor/DotDir.hs @@ -454,11 +454,12 @@ updateUpstreamMaster newref = do -- that does not point at the distrepo, the user must have set that up -- and is not using the distrepo, so do nothing. warnoutofdate :: Bool -> IO () -warnoutofdate havebranch = do - warningMessage ("** Your ~/.propellor/ is out of date..") - let also s = infoMessage [" " ++ s] - also ("A newer upstream version is available in " ++ distrepo) - if havebranch - then also ("To merge it, run: git merge " ++ upstreambranch) - else also ("To merge it, find the most recent commit in your repository's history that corresponds to an upstream release of propellor, and set refs/remotes/" ++ upstreambranch ++ " to it. Then run propellor again.") - also "" +warnoutofdate havebranch = warningMessage $ unlines + [ "** Your ~/.propellor/ is out of date.." + , indent "A newer upstream version is available in " ++ distrepo + , indent $ if havebranch + then "To merge it, run: git merge " ++ upstreambranch + else "To merge it, find the most recent commit in your repository's history that corresponds to an upstream release of propellor, and set refs/remotes/" ++ upstreambranch ++ " to it. Then run propellor again." + ] + where + indent s = " " ++ s -- cgit v1.3-2-g0d8e From 9d167ac2e64fc3f791ac2695e7a65a70446c80ea Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 19 Feb 2018 12:55:20 -0400 Subject: cleanup debug --- src/Propellor/DotDir.hs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/Propellor/DotDir.hs b/src/Propellor/DotDir.hs index be5d614d..125cec3f 100644 --- a/src/Propellor/DotDir.hs +++ b/src/Propellor/DotDir.hs @@ -392,12 +392,10 @@ checkRepoUpToDate = whenM (gitbundleavail <&&> dotpropellorpopulated) $ do updateUpstreamMaster :: String -> IO () updateUpstreamMaster newref = do changeWorkingDirectory =<< dotPropellor - v <- getoldrev - case v of - Nothing -> return () - Just oldref -> go oldref + go =<< getoldref where - go oldref = do + go Nothing = return () + go (Just oldref) = do let tmprepo = ".git/propellordisttmp" let cleantmprepo = void $ catchMaybeIO $ removeDirectoryRecursive tmprepo cleantmprepo @@ -428,11 +426,10 @@ updateUpstreamMaster newref = do -- Get ref that the upstreambranch points to, only when -- the distrepo is being used. - getoldrev = do - mrev <- catchMaybeIO $ takeWhile (/= '\n') + getoldref = do + mref <- catchMaybeIO $ takeWhile (/= '\n') <$> readProcess "git" ["show-ref", upstreambranch, "--hash"] - print mrev - case mrev of + case mref of Just _ -> do -- Normally there will be no upstream -- remote when the distrepo is used. @@ -442,13 +439,12 @@ updateUpstreamMaster newref = do ifM (hasRemote "upstream") ( do v <- remoteUrl "upstream" - print ("remote url", v) return $ case v of - Just rurl | rurl == distrepo -> mrev + Just rurl | rurl == distrepo -> mref _ -> Nothing - , return mrev + , return mref ) - Nothing -> return mrev + Nothing -> return mref -- And, if there's a remote named "upstream" -- that does not point at the distrepo, the user must have set that up -- cgit v1.3-2-g0d8e From 530d9ff6bea5570d051d07546a128d456b3c5c3b Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 22 Feb 2018 11:41:57 -0400 Subject: Avoid crashing if initial fetch from origin fails when spinning a host. --- debian/changelog | 1 + .../comment_1_be4533d304096f431ac8d35bbf990dab._comment | 13 +++++++++++++ src/Propellor/Git/VerifiedBranch.hs | 11 ++++++++--- 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 doc/forum/--spin_tries_to_pull_from_central_repository__63__/comment_1_be4533d304096f431ac8d35bbf990dab._comment (limited to 'src') diff --git a/debian/changelog b/debian/changelog index 55ca5a93..bc7a4a69 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,7 @@ propellor (5.3.3) UNRELEASED; urgency=medium * Warn again about new upstream version when ~/.propellor was cloned from the Debian git bundle using an older version of propellor that set up an upstream remote. + * Avoid crashing if initial fetch from origin fails when spinning a host. -- Joey Hess Mon, 19 Feb 2018 12:44:24 -0400 diff --git a/doc/forum/--spin_tries_to_pull_from_central_repository__63__/comment_1_be4533d304096f431ac8d35bbf990dab._comment b/doc/forum/--spin_tries_to_pull_from_central_repository__63__/comment_1_be4533d304096f431ac8d35bbf990dab._comment new file mode 100644 index 00000000..e79fabfb --- /dev/null +++ b/doc/forum/--spin_tries_to_pull_from_central_repository__63__/comment_1_be4533d304096f431ac8d35bbf990dab._comment @@ -0,0 +1,13 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2018-02-22T15:34:07Z" + content=""" +--spin has always pushed/pulled from origin, if there is +a central git repository. + +It's an optional thing though, since the update is pushed directly to the +host it spins too. + +I've improved the code to avoid this particular crash.. +"""]] diff --git a/src/Propellor/Git/VerifiedBranch.hs b/src/Propellor/Git/VerifiedBranch.hs index 51fcb573..df607bd2 100644 --- a/src/Propellor/Git/VerifiedBranch.hs +++ b/src/Propellor/Git/VerifiedBranch.hs @@ -30,12 +30,17 @@ verifyOriginBranch originbranch = do -- Returns True if HEAD is changed by fetching and merging from origin. fetchOrigin :: IO Bool fetchOrigin = do + fetched <- actionMessage "Pull from central git repository" $ + boolSystem "git" [Param "fetch"] + if fetched + then mergeOrigin + else return False + +mergeOrigin :: IO Bool +mergeOrigin = do branchref <- getCurrentBranch let originbranch = "origin" branchref - void $ actionMessage "Pull from central git repository" $ - boolSystem "git" [Param "fetch"] - oldsha <- getCurrentGitSha1 branchref keyring <- privDataKeyring -- cgit v1.3-2-g0d8e From 6749014553b13ad148cde450baefb241a98ed771 Mon Sep 17 00:00:00 2001 From: Félix Sipma Date: Fri, 23 Feb 2018 14:11:15 +0100 Subject: add Propellor.Property.Dhparams --- propellor.cabal | 1 + src/Propellor/Property/Dhparams.hs | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/Propellor/Property/Dhparams.hs (limited to 'src') diff --git a/propellor.cabal b/propellor.cabal index d9157eb1..b2ecb3d8 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -103,6 +103,7 @@ Library Propellor.Property.Cron Propellor.Property.DebianMirror Propellor.Property.Debootstrap + Propellor.Property.Dhparams Propellor.Property.DiskImage Propellor.Property.DiskImage.PartSpec Propellor.Property.Dns diff --git a/src/Propellor/Property/Dhparams.hs b/src/Propellor/Property/Dhparams.hs new file mode 100644 index 00000000..2c30cb87 --- /dev/null +++ b/src/Propellor/Property/Dhparams.hs @@ -0,0 +1,26 @@ +-- | Maintainer: Félix Sipma + +module Propellor.Property.Dhparams where + +import Propellor.Base +import qualified Propellor.Property.Apt as Apt +import qualified Propellor.Property.File as File +import Utility.FileMode +import Utility.SafeCommand + + +length' :: Int +length' = 2048 + +file :: FilePath +file = "/etc/ssl/private/dhparams.pem" + +safeDhparams :: Property DebianLike +safeDhparams = propertyList "safe dhparams" $ props + & File.dirExists (takeDirectory file) + & Apt.installed ["openssl"] + & check (not <$> doesFileExist file) (createDhparams file length') + +createDhparams :: FilePath -> Int -> Property UnixLike +createDhparams f l = property ("generate new dhparams: " ++ f) $ liftIO $ withUmask 0o0177 $ withFile f WriteMode $ \h -> + cmdResult <$> boolSystem' "openssl" [Param "dhparam", Param (show l)] (\p -> p { std_out = UseHandle h }) -- cgit v1.3-2-g0d8e From fad7824a13580f505549cc746589c94542bec9cb Mon Sep 17 00:00:00 2001 From: Félix Sipma Date: Fri, 23 Feb 2018 16:33:00 +0100 Subject: rename Dhparams to Openssl --- propellor.cabal | 2 +- src/Propellor/Property/Dhparams.hs | 26 -------------------------- src/Propellor/Property/Openssl.hs | 26 ++++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 27 deletions(-) delete mode 100644 src/Propellor/Property/Dhparams.hs create mode 100644 src/Propellor/Property/Openssl.hs (limited to 'src') diff --git a/propellor.cabal b/propellor.cabal index b2ecb3d8..b22abcba 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -103,7 +103,6 @@ Library Propellor.Property.Cron Propellor.Property.DebianMirror Propellor.Property.Debootstrap - Propellor.Property.Dhparams Propellor.Property.DiskImage Propellor.Property.DiskImage.PartSpec Propellor.Property.Dns @@ -141,6 +140,7 @@ Library Propellor.Property.Nginx Propellor.Property.Obnam Propellor.Property.OpenId + Propellor.Property.Openssl Propellor.Property.OS Propellor.Property.Pacman Propellor.Property.Parted diff --git a/src/Propellor/Property/Dhparams.hs b/src/Propellor/Property/Dhparams.hs deleted file mode 100644 index 2c30cb87..00000000 --- a/src/Propellor/Property/Dhparams.hs +++ /dev/null @@ -1,26 +0,0 @@ --- | Maintainer: Félix Sipma - -module Propellor.Property.Dhparams where - -import Propellor.Base -import qualified Propellor.Property.Apt as Apt -import qualified Propellor.Property.File as File -import Utility.FileMode -import Utility.SafeCommand - - -length' :: Int -length' = 2048 - -file :: FilePath -file = "/etc/ssl/private/dhparams.pem" - -safeDhparams :: Property DebianLike -safeDhparams = propertyList "safe dhparams" $ props - & File.dirExists (takeDirectory file) - & Apt.installed ["openssl"] - & check (not <$> doesFileExist file) (createDhparams file length') - -createDhparams :: FilePath -> Int -> Property UnixLike -createDhparams f l = property ("generate new dhparams: " ++ f) $ liftIO $ withUmask 0o0177 $ withFile f WriteMode $ \h -> - cmdResult <$> boolSystem' "openssl" [Param "dhparam", Param (show l)] (\p -> p { std_out = UseHandle h }) diff --git a/src/Propellor/Property/Openssl.hs b/src/Propellor/Property/Openssl.hs new file mode 100644 index 00000000..eb373e49 --- /dev/null +++ b/src/Propellor/Property/Openssl.hs @@ -0,0 +1,26 @@ +-- | Maintainer: Félix Sipma + +module Propellor.Property.Openssl where + +import Propellor.Base +import qualified Propellor.Property.Apt as Apt +import qualified Propellor.Property.File as File +import Utility.FileMode +import Utility.SafeCommand + + +dhparamsLength :: Int +dhparamsLength = 2048 + +dhparams :: FilePath +dhparams = "/etc/ssl/private/dhparams.pem" + +safeDhparams :: Property DebianLike +safeDhparams = propertyList "safe dhparams" $ props + & File.dirExists (takeDirectory file) + & Apt.installed ["openssl"] + & check (not <$> doesFileExist file) (createDhparams file length') + +createDhparams :: FilePath -> Int -> Property UnixLike +createDhparams f l = property ("generate new dhparams: " ++ f) $ liftIO $ withUmask 0o0177 $ withFile f WriteMode $ \h -> + cmdResult <$> boolSystem' "openssl" [Param "dhparam", Param (show l)] (\p -> p { std_out = UseHandle h }) -- cgit v1.3-2-g0d8e From 788ad7bcff61147dbdde484d8d56ff6aead82659 Mon Sep 17 00:00:00 2001 From: Félix Sipma Date: Fri, 23 Feb 2018 16:33:53 +0100 Subject: add installed property to Openssl --- src/Propellor/Property/Openssl.hs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Propellor/Property/Openssl.hs b/src/Propellor/Property/Openssl.hs index eb373e49..1967301c 100644 --- a/src/Propellor/Property/Openssl.hs +++ b/src/Propellor/Property/Openssl.hs @@ -9,6 +9,9 @@ import Utility.FileMode import Utility.SafeCommand +installed :: Property DebianLike +installed = Apt.installed ["openssl"] + dhparamsLength :: Int dhparamsLength = 2048 @@ -18,7 +21,7 @@ dhparams = "/etc/ssl/private/dhparams.pem" safeDhparams :: Property DebianLike safeDhparams = propertyList "safe dhparams" $ props & File.dirExists (takeDirectory file) - & Apt.installed ["openssl"] + & installed & check (not <$> doesFileExist file) (createDhparams file length') createDhparams :: FilePath -> Int -> Property UnixLike -- cgit v1.3-2-g0d8e From c16bc5a806d0020f608a35185127430b65253981 Mon Sep 17 00:00:00 2001 From: Félix Sipma Date: Sat, 24 Feb 2018 21:31:03 +0100 Subject: Openssl: fix typo --- src/Propellor/Property/Openssl.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Propellor/Property/Openssl.hs b/src/Propellor/Property/Openssl.hs index 1967301c..a91b8195 100644 --- a/src/Propellor/Property/Openssl.hs +++ b/src/Propellor/Property/Openssl.hs @@ -20,9 +20,9 @@ dhparams = "/etc/ssl/private/dhparams.pem" safeDhparams :: Property DebianLike safeDhparams = propertyList "safe dhparams" $ props - & File.dirExists (takeDirectory file) + & File.dirExists (takeDirectory dhparams) & installed - & check (not <$> doesFileExist file) (createDhparams file length') + & check (not <$> doesFileExist dhparams) (createDhparams dhparams dhparamsLength) createDhparams :: FilePath -> Int -> Property UnixLike createDhparams f l = property ("generate new dhparams: " ++ f) $ liftIO $ withUmask 0o0177 $ withFile f WriteMode $ \h -> -- cgit v1.3-2-g0d8e