Merge branch 'joeyconfig'
This commit is contained in:
commit
9e9d0f1d41
|
@ -4,13 +4,15 @@ module Propellor.Exception where
|
||||||
|
|
||||||
import qualified "MonadCatchIO-transformers" Control.Monad.CatchIO as M
|
import qualified "MonadCatchIO-transformers" Control.Monad.CatchIO as M
|
||||||
import Control.Exception
|
import Control.Exception
|
||||||
import Control.Applicative
|
|
||||||
|
|
||||||
import Propellor.Types
|
import Propellor.Types
|
||||||
|
import Propellor.Message
|
||||||
|
|
||||||
-- | Catches IO exceptions and returns FailedChange.
|
-- | Catches IO exceptions and returns FailedChange.
|
||||||
catchPropellor :: Propellor Result -> Propellor Result
|
catchPropellor :: Propellor Result -> Propellor Result
|
||||||
catchPropellor a = either (\_ -> FailedChange) id <$> tryPropellor a
|
catchPropellor a = either err return =<< tryPropellor a
|
||||||
|
where
|
||||||
|
err e = warningMessage (show e) >> return FailedChange
|
||||||
|
|
||||||
tryPropellor :: Propellor a -> Propellor (Either IOException a)
|
tryPropellor :: Propellor a -> Propellor (Either IOException a)
|
||||||
tryPropellor = M.try
|
tryPropellor = M.try
|
||||||
|
|
|
@ -22,6 +22,9 @@ import Utility.Tmp
|
||||||
import Utility.SafeCommand
|
import Utility.SafeCommand
|
||||||
import Utility.Misc
|
import Utility.Misc
|
||||||
|
|
||||||
|
-- | When the specified PrivDataField is available on the host Propellor
|
||||||
|
-- is provisioning, it provies the data to the action. Otherwise, it prints
|
||||||
|
-- a message to help the user make the necessary private data available.
|
||||||
withPrivData :: PrivDataField -> (String -> Propellor Result) -> Propellor Result
|
withPrivData :: PrivDataField -> (String -> Propellor Result) -> Propellor Result
|
||||||
withPrivData field a = maybe missing a =<< liftIO (getPrivData field)
|
withPrivData field a = maybe missing a =<< liftIO (getPrivData field)
|
||||||
where
|
where
|
||||||
|
|
|
@ -105,6 +105,7 @@ host :: HostName -> Host
|
||||||
host hn = Host [] (\_ -> newAttr hn)
|
host hn = Host [] (\_ -> newAttr hn)
|
||||||
|
|
||||||
-- | Adds a property to a Host
|
-- | Adds a property to a Host
|
||||||
|
--
|
||||||
-- Can add Properties, RevertableProperties, and AttrProperties
|
-- Can add Properties, RevertableProperties, and AttrProperties
|
||||||
(&) :: IsProp p => Host -> p -> Host
|
(&) :: IsProp p => Host -> p -> Host
|
||||||
(Host ps as) & p = Host (ps ++ [toProp p]) (getAttr p . as)
|
(Host ps as) & p = Host (ps ++ [toProp p]) (getAttr p . as)
|
||||||
|
|
|
@ -61,7 +61,7 @@ setLastChecked time desc = do
|
||||||
readLastChecked :: IO (M.Map Desc LocalTime)
|
readLastChecked :: IO (M.Map Desc LocalTime)
|
||||||
readLastChecked = fromMaybe M.empty <$> catchDefaultIO Nothing go
|
readLastChecked = fromMaybe M.empty <$> catchDefaultIO Nothing go
|
||||||
where
|
where
|
||||||
go = readish <$> readFile lastCheckedFile
|
go = readish <$> readFileStrict lastCheckedFile
|
||||||
|
|
||||||
writeLastChecked :: M.Map Desc LocalTime -> IO ()
|
writeLastChecked :: M.Map Desc LocalTime -> IO ()
|
||||||
writeLastChecked = writeFile lastCheckedFile . show
|
writeLastChecked = writeFile lastCheckedFile . show
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{- scheduled activities
|
{- scheduled activities
|
||||||
-
|
-
|
||||||
- Copyright 2013 Joey Hess <joey@kitenet.net>
|
- Copyright 2013-2014 Joey Hess <joey@kitenet.net>
|
||||||
-
|
-
|
||||||
- Licensed under the GNU GPL version 3 or higher.
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
@ -14,6 +14,7 @@ module Utility.Scheduled (
|
||||||
MonthDay,
|
MonthDay,
|
||||||
YearDay,
|
YearDay,
|
||||||
nextTime,
|
nextTime,
|
||||||
|
calcNextTime,
|
||||||
startTime,
|
startTime,
|
||||||
fromSchedule,
|
fromSchedule,
|
||||||
fromScheduledTime,
|
fromScheduledTime,
|
||||||
|
@ -22,7 +23,8 @@ module Utility.Scheduled (
|
||||||
toRecurrance,
|
toRecurrance,
|
||||||
toSchedule,
|
toSchedule,
|
||||||
parseSchedule,
|
parseSchedule,
|
||||||
prop_schedule_roundtrips
|
prop_schedule_roundtrips,
|
||||||
|
prop_past_sane,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Utility.Data
|
import Utility.Data
|
||||||
|
@ -66,8 +68,8 @@ data ScheduledTime
|
||||||
type Hour = Int
|
type Hour = Int
|
||||||
type Minute = Int
|
type Minute = Int
|
||||||
|
|
||||||
{- Next time a Schedule should take effect. The NextTimeWindow is used
|
-- | Next time a Schedule should take effect. The NextTimeWindow is used
|
||||||
- when a Schedule is allowed to start at some point within the window. -}
|
-- when a Schedule is allowed to start at some point within the window.
|
||||||
data NextTime
|
data NextTime
|
||||||
= NextTimeExactly LocalTime
|
= NextTimeExactly LocalTime
|
||||||
| NextTimeWindow LocalTime LocalTime
|
| NextTimeWindow LocalTime LocalTime
|
||||||
|
@ -83,10 +85,10 @@ nextTime schedule lasttime = do
|
||||||
tz <- getTimeZone now
|
tz <- getTimeZone now
|
||||||
return $ calcNextTime schedule lasttime $ utcToLocalTime tz now
|
return $ calcNextTime schedule lasttime $ utcToLocalTime tz now
|
||||||
|
|
||||||
{- Calculate the next time that fits a Schedule, based on the
|
-- | Calculate the next time that fits a Schedule, based on the
|
||||||
- last time it occurred, and the current time. -}
|
-- last time it occurred, and the current time.
|
||||||
calcNextTime :: Schedule -> Maybe LocalTime -> LocalTime -> Maybe NextTime
|
calcNextTime :: Schedule -> Maybe LocalTime -> LocalTime -> Maybe NextTime
|
||||||
calcNextTime (Schedule recurrance scheduledtime) lasttime currenttime
|
calcNextTime schedule@(Schedule recurrance scheduledtime) lasttime currenttime
|
||||||
| scheduledtime == AnyTime = do
|
| scheduledtime == AnyTime = do
|
||||||
next <- findfromtoday True
|
next <- findfromtoday True
|
||||||
return $ case next of
|
return $ case next of
|
||||||
|
@ -97,10 +99,10 @@ calcNextTime (Schedule recurrance scheduledtime) lasttime currenttime
|
||||||
findfromtoday anytime = findfrom recurrance afterday today
|
findfromtoday anytime = findfrom recurrance afterday today
|
||||||
where
|
where
|
||||||
today = localDay currenttime
|
today = localDay currenttime
|
||||||
afterday = sameaslastday || toolatetoday
|
afterday = sameaslastrun || toolatetoday
|
||||||
toolatetoday = not anytime && localTimeOfDay currenttime >= nexttime
|
toolatetoday = not anytime && localTimeOfDay currenttime >= nexttime
|
||||||
sameaslastday = lastday == Just today
|
sameaslastrun = lastrun == Just today
|
||||||
lastday = localDay <$> lasttime
|
lastrun = localDay <$> lasttime
|
||||||
nexttime = case scheduledtime of
|
nexttime = case scheduledtime of
|
||||||
AnyTime -> TimeOfDay 0 0 0
|
AnyTime -> TimeOfDay 0 0 0
|
||||||
SpecificTime h m -> TimeOfDay h m 0
|
SpecificTime h m -> TimeOfDay h m 0
|
||||||
|
@ -108,68 +110,84 @@ calcNextTime (Schedule recurrance scheduledtime) lasttime currenttime
|
||||||
window startd endd = NextTimeWindow
|
window startd endd = NextTimeWindow
|
||||||
(LocalTime startd nexttime)
|
(LocalTime startd nexttime)
|
||||||
(LocalTime endd (TimeOfDay 23 59 0))
|
(LocalTime endd (TimeOfDay 23 59 0))
|
||||||
findfrom r afterday day = case r of
|
findfrom r afterday candidate
|
||||||
|
| ynum candidate > (ynum (localDay currenttime)) + 100 =
|
||||||
|
-- avoid possible infinite recusion
|
||||||
|
error $ "bug: calcNextTime did not find a time within 100 years to run " ++
|
||||||
|
show (schedule, lasttime, currenttime)
|
||||||
|
| otherwise = findfromChecked r afterday candidate
|
||||||
|
findfromChecked r afterday candidate = case r of
|
||||||
Daily
|
Daily
|
||||||
| afterday -> Just $ exactly $ addDays 1 day
|
| afterday -> Just $ exactly $ addDays 1 candidate
|
||||||
| otherwise -> Just $ exactly day
|
| otherwise -> Just $ exactly candidate
|
||||||
Weekly Nothing
|
Weekly Nothing
|
||||||
| afterday -> skip 1
|
| afterday -> skip 1
|
||||||
| otherwise -> case (wday <$> lastday, wday day) of
|
| otherwise -> case (wday <$> lastrun, wday candidate) of
|
||||||
(Nothing, _) -> Just $ window day (addDays 6 day)
|
(Nothing, _) -> Just $ window candidate (addDays 6 candidate)
|
||||||
(Just old, curr)
|
(Just old, curr)
|
||||||
| old == curr -> Just $ window day (addDays 6 day)
|
| old == curr -> Just $ window candidate (addDays 6 candidate)
|
||||||
| otherwise -> skip 1
|
| otherwise -> skip 1
|
||||||
Monthly Nothing
|
Monthly Nothing
|
||||||
| afterday -> skip 1
|
| afterday -> skip 1
|
||||||
| maybe True (\old -> mnum day > mday old && mday day >= (mday old `mod` minmday)) lastday ->
|
| maybe True (candidate `oneMonthPast`) lastrun ->
|
||||||
-- Window only covers current month,
|
Just $ window candidate (endOfMonth candidate)
|
||||||
-- in case there is a Divisible requirement.
|
|
||||||
Just $ window day (endOfMonth day)
|
|
||||||
| otherwise -> skip 1
|
| otherwise -> skip 1
|
||||||
Yearly Nothing
|
Yearly Nothing
|
||||||
| afterday -> skip 1
|
| afterday -> skip 1
|
||||||
| maybe True (\old -> ynum day > ynum old && yday day >= (yday old `mod` minyday)) lastday ->
|
| maybe True (candidate `oneYearPast`) lastrun ->
|
||||||
Just $ window day (endOfYear day)
|
Just $ window candidate (endOfYear candidate)
|
||||||
| otherwise -> skip 1
|
| otherwise -> skip 1
|
||||||
Weekly (Just w)
|
Weekly (Just w)
|
||||||
| w < 0 || w > maxwday -> Nothing
|
| w < 0 || w > maxwday -> Nothing
|
||||||
| w == wday day -> if afterday
|
| w == wday candidate -> if afterday
|
||||||
then Just $ exactly $ addDays 7 day
|
then Just $ exactly $ addDays 7 candidate
|
||||||
else Just $ exactly day
|
else Just $ exactly candidate
|
||||||
| otherwise -> Just $ exactly $
|
| otherwise -> Just $ exactly $
|
||||||
addDays (fromIntegral $ (w - wday day) `mod` 7) day
|
addDays (fromIntegral $ (w - wday candidate) `mod` 7) candidate
|
||||||
Monthly (Just m)
|
Monthly (Just m)
|
||||||
| m < 0 || m > maxmday -> Nothing
|
| m < 0 || m > maxmday -> Nothing
|
||||||
-- TODO can be done more efficiently than recursing
|
-- TODO can be done more efficiently than recursing
|
||||||
| m == mday day -> if afterday
|
| m == mday candidate -> if afterday
|
||||||
then skip 1
|
then skip 1
|
||||||
else Just $ exactly day
|
else Just $ exactly candidate
|
||||||
| otherwise -> skip 1
|
| otherwise -> skip 1
|
||||||
Yearly (Just y)
|
Yearly (Just y)
|
||||||
| y < 0 || y > maxyday -> Nothing
|
| y < 0 || y > maxyday -> Nothing
|
||||||
| y == yday day -> if afterday
|
| y == yday candidate -> if afterday
|
||||||
then skip 365
|
then skip 365
|
||||||
else Just $ exactly day
|
else Just $ exactly candidate
|
||||||
| otherwise -> skip 1
|
| otherwise -> skip 1
|
||||||
Divisible n r'@Daily -> handlediv n r' yday (Just maxyday)
|
Divisible n r'@Daily -> handlediv n r' yday (Just maxyday)
|
||||||
Divisible n r'@(Weekly _) -> handlediv n r' wnum (Just maxwnum)
|
Divisible n r'@(Weekly _) -> handlediv n r' wnum (Just maxwnum)
|
||||||
Divisible n r'@(Monthly _) -> handlediv n r' mnum (Just maxmnum)
|
Divisible n r'@(Monthly _) -> handlediv n r' mnum (Just maxmnum)
|
||||||
Divisible n r'@(Yearly _) -> handlediv n r' ynum Nothing
|
Divisible n r'@(Yearly _) -> handlediv n r' ynum Nothing
|
||||||
Divisible _ r'@(Divisible _ _) -> findfrom r' afterday day
|
Divisible _ r'@(Divisible _ _) -> findfrom r' afterday candidate
|
||||||
where
|
where
|
||||||
skip n = findfrom r False (addDays n day)
|
skip n = findfrom r False (addDays n candidate)
|
||||||
handlediv n r' getval mmax
|
handlediv n r' getval mmax
|
||||||
| n > 0 && maybe True (n <=) mmax =
|
| n > 0 && maybe True (n <=) mmax =
|
||||||
findfromwhere r' (divisible n . getval) afterday day
|
findfromwhere r' (divisible n . getval) afterday candidate
|
||||||
| otherwise = Nothing
|
| otherwise = Nothing
|
||||||
findfromwhere r p afterday day
|
findfromwhere r p afterday candidate
|
||||||
| maybe True (p . getday) next = next
|
| maybe True (p . getday) next = next
|
||||||
| otherwise = maybe Nothing (findfromwhere r p True . getday) next
|
| otherwise = maybe Nothing (findfromwhere r p True . getday) next
|
||||||
where
|
where
|
||||||
next = findfrom r afterday day
|
next = findfrom r afterday candidate
|
||||||
getday = localDay . startTime
|
getday = localDay . startTime
|
||||||
divisible n v = v `rem` n == 0
|
divisible n v = v `rem` n == 0
|
||||||
|
|
||||||
|
-- Check if the new Day occurs one month or more past the old Day.
|
||||||
|
oneMonthPast :: Day -> Day -> Bool
|
||||||
|
new `oneMonthPast` old = fromGregorian y (m+1) d <= new
|
||||||
|
where
|
||||||
|
(y,m,d) = toGregorian old
|
||||||
|
|
||||||
|
-- Check if the new Day occurs one year or more past the old Day.
|
||||||
|
oneYearPast :: Day -> Day -> Bool
|
||||||
|
new `oneYearPast` old = fromGregorian (y+1) m d <= new
|
||||||
|
where
|
||||||
|
(y,m,d) = toGregorian old
|
||||||
|
|
||||||
endOfMonth :: Day -> Day
|
endOfMonth :: Day -> Day
|
||||||
endOfMonth day =
|
endOfMonth day =
|
||||||
let (y,m,_d) = toGregorian day
|
let (y,m,_d) = toGregorian day
|
||||||
|
@ -194,17 +212,13 @@ yday = snd . toOrdinalDate
|
||||||
ynum :: Day -> Int
|
ynum :: Day -> Int
|
||||||
ynum = fromIntegral . fst . toOrdinalDate
|
ynum = fromIntegral . fst . toOrdinalDate
|
||||||
|
|
||||||
{- Calendar max and mins. -}
|
-- Calendar max values.
|
||||||
maxyday :: Int
|
maxyday :: Int
|
||||||
maxyday = 366 -- with leap days
|
maxyday = 366 -- with leap days
|
||||||
minyday :: Int
|
|
||||||
minyday = 365
|
|
||||||
maxwnum :: Int
|
maxwnum :: Int
|
||||||
maxwnum = 53 -- some years have more than 52
|
maxwnum = 53 -- some years have more than 52
|
||||||
maxmday :: Int
|
maxmday :: Int
|
||||||
maxmday = 31
|
maxmday = 31
|
||||||
minmday :: Int
|
|
||||||
minmday = 28
|
|
||||||
maxmnum :: Int
|
maxmnum :: Int
|
||||||
maxmnum = 12
|
maxmnum = 12
|
||||||
maxwday :: Int
|
maxwday :: Int
|
||||||
|
@ -356,3 +370,27 @@ instance Arbitrary Recurrance where
|
||||||
|
|
||||||
prop_schedule_roundtrips :: Schedule -> Bool
|
prop_schedule_roundtrips :: Schedule -> Bool
|
||||||
prop_schedule_roundtrips s = toSchedule (fromSchedule s) == Just s
|
prop_schedule_roundtrips s = toSchedule (fromSchedule s) == Just s
|
||||||
|
|
||||||
|
prop_past_sane :: Bool
|
||||||
|
prop_past_sane = and
|
||||||
|
[ all (checksout oneMonthPast) (mplus1 ++ yplus1)
|
||||||
|
, all (not . (checksout oneMonthPast)) (map swap (mplus1 ++ yplus1))
|
||||||
|
, all (checksout oneYearPast) yplus1
|
||||||
|
, all (not . (checksout oneYearPast)) (map swap yplus1)
|
||||||
|
]
|
||||||
|
where
|
||||||
|
mplus1 = -- new date old date, 1+ months before it
|
||||||
|
[ (fromGregorian 2014 01 15, fromGregorian 2013 12 15)
|
||||||
|
, (fromGregorian 2014 01 15, fromGregorian 2013 02 15)
|
||||||
|
, (fromGregorian 2014 02 15, fromGregorian 2013 01 15)
|
||||||
|
, (fromGregorian 2014 03 01, fromGregorian 2013 01 15)
|
||||||
|
, (fromGregorian 2014 03 01, fromGregorian 2013 12 15)
|
||||||
|
, (fromGregorian 2015 01 01, fromGregorian 2010 01 01)
|
||||||
|
]
|
||||||
|
yplus1 = -- new date old date, 1+ years before it
|
||||||
|
[ (fromGregorian 2014 01 15, fromGregorian 2012 01 16)
|
||||||
|
, (fromGregorian 2014 01 15, fromGregorian 2013 01 14)
|
||||||
|
, (fromGregorian 2022 12 31, fromGregorian 2000 01 01)
|
||||||
|
]
|
||||||
|
checksout cmp (new, old) = new `cmp` old
|
||||||
|
swap (a,b) = (b,a)
|
||||||
|
|
|
@ -71,7 +71,7 @@ hosts =
|
||||||
& Apt.buildDep ["git-annex"] `period` Daily
|
& Apt.buildDep ["git-annex"] `period` Daily
|
||||||
& Git.daemonRunning "/srv/git"
|
& Git.daemonRunning "/srv/git"
|
||||||
& File.ownerGroup "/srv/git" "joey" "joey"
|
& File.ownerGroup "/srv/git" "joey" "joey"
|
||||||
-- git repos restore (how?)
|
-- git repos restore (how?) (also make backups!)
|
||||||
-- family annex needs family members to have accounts,
|
-- family annex needs family members to have accounts,
|
||||||
-- ssh host key etc.. finesse?
|
-- ssh host key etc.. finesse?
|
||||||
-- (also should upgrade git-annex-shell for it..)
|
-- (also should upgrade git-annex-shell for it..)
|
||||||
|
@ -80,9 +80,13 @@ hosts =
|
||||||
-- gitweb
|
-- gitweb
|
||||||
-- downloads.kitenet.net setup (including ssh key to turtle)
|
-- downloads.kitenet.net setup (including ssh key to turtle)
|
||||||
|
|
||||||
--------------------------------------------------------------------
|
--' __|II| ,.
|
||||||
-- Docker Containers ----------------------------------- \o/ -----
|
---- __|II|II|__ ( \_,/\
|
||||||
--------------------------------------------------------------------
|
-----'\o/-'-.-'-.-'-.- __|II|II|II|II|___/ __/ -'-.-'-.-'-.-'-.-'-
|
||||||
|
--------------------- | [Docker] / ----------------------
|
||||||
|
--------------------- : / -----------------------
|
||||||
|
---------------------- \____, o ,' ------------------------
|
||||||
|
----------------------- '--,___________,' -------------------------
|
||||||
|
|
||||||
-- Simple web server, publishing the outside host's /var/www
|
-- Simple web server, publishing the outside host's /var/www
|
||||||
, standardContainer "webserver" Stable "amd64"
|
, standardContainer "webserver" Stable "amd64"
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
propellor (0.3.1) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
|
* Merge scheduler bug fix from git-annex.
|
||||||
|
|
||||||
|
-- Joey Hess <joeyh@debian.org> Fri, 11 Apr 2014 15:00:11 -0400
|
||||||
|
|
||||||
propellor (0.3.0) unstable; urgency=medium
|
propellor (0.3.0) unstable; urgency=medium
|
||||||
|
|
||||||
* ipv6to4: Ensure interface is brought up automatically on boot.
|
* ipv6to4: Ensure interface is brought up automatically on boot.
|
||||||
|
|
Loading…
Reference in New Issue