From 3555bf9d270336bc8f9075446da1c114af1c0478 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Mon, 10 Aug 2020 22:54:19 +0200 Subject: Borg: handle old borg versions and issue a warning if no archive is found The --last and --glob-archive options need borg version 1.1. Stop using these options and do the filtering in haskell. This had the side benefit of having better checkpoint filtering. Also issue a warning in case no archive is found. --- src/Propellor/Property/Borg.hs | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/Propellor/Property/Borg.hs b/src/Propellor/Property/Borg.hs index 62017704..9fc0eacc 100644 --- a/src/Propellor/Property/Borg.hs +++ b/src/Propellor/Property/Borg.hs @@ -15,11 +15,11 @@ module Propellor.Property.Borg , KeepPolicy (..) ) where -import Propellor.Base hiding (init) +import Propellor.Base hiding (init, last) import Prelude hiding (init) import qualified Propellor.Property.Apt as Apt import qualified Propellor.Property.Cron as Cron -import Data.List (intercalate) +import Data.List (intercalate, isSuffixOf) import Utility.SafeCommand (boolSystem') -- | Parameter to pass to a borg command. @@ -106,16 +106,15 @@ installed = pickOS installdebian aptinstall repoExists :: BorgRepo -> IO Bool repoExists repo = runBorg repo [Param "list", Param (repoLoc repo)] Nothing --- | Get the name of the latest archive, use a trick to ignore checkpoints --- (idea from borgmatic, regular archives usually end with a timestamp). -latestArchive :: BorgRepo -> IO String -latestArchive repo = takeWhile (/= '\n') - <$> readBorg repo listargs +-- | Get the name of the latest archive. +latestArchive :: BorgRepo -> IO (Maybe String) +latestArchive repo = getLatest <$> readBorg repo listargs where + getLatest = maybeLast . filter (not . isSuffixOf ".checkpoint") . lines + maybeLast [] = Nothing + maybeLast ps = Just $ last ps listargs = [ "list" - , "--glob-archive=*[0123456789]" - , "--last=1" , "--short" , repoLoc repo ] @@ -146,19 +145,18 @@ restored dir repo = go `requires` installed go = property (dir ++ " restored by borg") $ ifM (liftIO needsRestore) ( do warningMessage $ dir ++ " is empty/missing; restoring from backup ..." - liftIO restoreLatest + latest <- liftIO (latestArchive repo) + case latest of + Nothing -> do + warningMessage $ "no archive to extract" + return FailedChange + Just l -> liftIO (restore l) , noChange ) needsRestore = isUnpopulated dir - restoreLatest = do - latest <- latestArchive repo - ifM (pure $ not $ null latest) - ( restore latest - , return FailedChange - ) - + restore :: String -> IO Result restore latest = withTmpDirIn (takeDirectory dir) "borg-restore" $ \tmpdir -> do ok <- runBorg repo [ Param "extract" -- cgit v1.2.3