From f5d95a92a209d91b0e574c27d58260c6088ff33d Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Wed, 3 Apr 2019 13:05:04 -0700 Subject: add Cron.jobDropped Signed-off-by: Sean Whitton --- src/Propellor/Property/Cron.hs | 70 ++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 20 deletions(-) (limited to 'src/Propellor/Property/Cron.hs') diff --git a/src/Propellor/Property/Cron.hs b/src/Propellor/Property/Cron.hs index 0271b0b3..737c144f 100644 --- a/src/Propellor/Property/Cron.hs +++ b/src/Propellor/Property/Cron.hs @@ -1,4 +1,10 @@ -module Propellor.Property.Cron where +module Propellor.Property.Cron ( + Times(..), + job, + niceJob, + jobDropped, + Propellor.Property.Cron.runPropellor +) where import Propellor.Base import qualified Propellor.Property.File as File @@ -30,7 +36,7 @@ job :: Desc -> Times -> User -> FilePath -> String -> Property DebianLike job desc times (User u) cddir command = combineProperties ("cronned " ++ desc) $ props & Apt.serviceInstalledRunning "cron" & Apt.installed ["util-linux", "moreutils"] - & cronjobfile `File.hasContent` + & (cronjobfile desc times) `File.hasContent` [ case times of Times _ -> "" _ -> "#!/bin/sh\nset -e" @@ -40,37 +46,40 @@ job desc times (User u) cddir command = combineProperties ("cronned " ++ desc) $ , "PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin" , "" , case times of - Times t -> t ++ "\t" ++ u ++ "\tchronic " ++ shellEscape scriptfile + Times t -> t ++ "\t" ++ u ++ "\tchronic " + ++ shellEscape (scriptfile desc) _ -> case u of - "root" -> "chronic " ++ shellEscape scriptfile - _ -> "chronic su " ++ u ++ " -c " ++ shellEscape scriptfile + "root" -> "chronic " ++ shellEscape (scriptfile desc) + _ -> "chronic su " ++ u ++ " -c " + ++ shellEscape (scriptfile desc) ] & case times of Times _ -> doNothing - _ -> cronjobfile `File.mode` combineModes (readModes ++ executeModes) + _ -> (cronjobfile desc times) + `File.mode` combineModes (readModes ++ executeModes) -- Use a separate script because it makes the cron job name -- prettier in emails, and also allows running the job manually. - & scriptfile `File.hasContent` + & (scriptfile desc) `File.hasContent` [ "#!/bin/sh" , "# Generated by propellor" , "set -e" - , "flock -n " ++ shellEscape cronjobfile + , "flock -n " ++ shellEscape (cronjobfile desc times) ++ " sh -c " ++ shellEscape cmdline ] - & scriptfile `File.mode` combineModes (readModes ++ executeModes) + & (scriptfile desc) `File.mode` combineModes (readModes ++ executeModes) where cmdline = "cd " ++ cddir ++ " && ( " ++ command ++ " )" - cronjobfile = "/etc" cronjobdir name - cronjobdir = case times of - Times _ -> "cron.d" - Daily -> "cron.daily" - Weekly -> "cron.weekly" - Monthly -> "cron.monthly" - scriptfile = "/usr/local/bin/" ++ name ++ "_cronjob" - name = map sanitize desc - sanitize c - | isAlphaNum c = c - | otherwise = '_' + +-- | Removes a cron job created by 'job' or 'niceJob', as identified by the +-- 'Desc' passed to those properties when the cronjob was set up +-- +-- Those properties are not revertable because simply removing a cronjob does +-- not undo the changes it might have made to the system, i.e., 'jobDropped' is +-- not in the general case a reversion of 'job' or 'niceJob' +jobDropped :: Desc -> Times -> Property UnixLike +jobDropped desc times = combineProperties ("uncronned " ++ desc) $ props + & File.notPresent (scriptfile desc) + & File.notPresent (cronjobfile desc times) -- | Installs a cron job, and runs it niced and ioniced. niceJob :: Desc -> Times -> User -> FilePath -> String -> Property DebianLike @@ -84,3 +93,24 @@ runPropellor times = withOS "propellor cron job" $ \w o -> do ensureProperty w $ niceJob "propellor" times (User "root") localdir (bootstrapPropellorCommand bootstrapper o ++ "; ./propellor") + +-- Utility functions + +cronjobname :: Desc -> String +cronjobname d = map sanitize d + where + sanitize c + | isAlphaNum c = c + | otherwise = '_' + +scriptfile :: Desc -> FilePath +scriptfile d = "/usr/local/bin/" ++ (cronjobname d) ++ "_cronjob" + +cronjobfile :: Desc -> Times -> FilePath +cronjobfile d times = "/etc" cronjobdir (cronjobname d) + where + cronjobdir = case times of + Times _ -> "cron.d" + Daily -> "cron.daily" + Weekly -> "cron.weekly" + Monthly -> "cron.monthly" -- cgit v1.2.3