]> dgit.raspbian.org Git - git-annex.git/commitdiff
add upgrade.log
authorJoey Hess <joeyh@joeyh.name>
Wed, 19 Jan 2022 19:51:04 +0000 (15:51 -0400)
committerJoey Hess <joeyh@joeyh.name>
Wed, 19 Jan 2022 19:52:29 +0000 (15:52 -0400)
The upgrade from V9 uses this to avoid an automatic upgrade until 1 year
after the V9 update. It can also be used in future such situations.

Sponsored-by: Dartmouth College's Datalad project
Annex/Locations.hs
Logs/Upgrade.hs [new file with mode: 0644]
Upgrade.hs
Upgrade/V8.hs
Upgrade/V9.hs
git-annex.cabal

index e611e0adcb1410d4bfb11bb432a493696055d23a..f782efb9272fe0df574c7a722e31e15e776ff7f7 100644 (file)
@@ -1,6 +1,6 @@
 {- git-annex file locations
  -
- - Copyright 2010-2021 Joey Hess <id@joeyh.name>
+ - Copyright 2010-2022 Joey Hess <id@joeyh.name>
  -
  - Licensed under the GNU AGPL version 3 or higher.
  -}
@@ -44,6 +44,8 @@ module Annex.Locations (
        gitAnnexFsckDbDirOld,
        gitAnnexFsckDbLock,
        gitAnnexFsckResultsLog,
+       gitAnnexUpgradeLog,
+       gitAnnexUpgradeLock,
        gitAnnexSmudgeLog,
        gitAnnexSmudgeLock,
        gitAnnexMoveLog,
@@ -345,6 +347,13 @@ gitAnnexFsckResultsLog :: UUID -> Git.Repo -> RawFilePath
 gitAnnexFsckResultsLog u r = 
        gitAnnexDir r P.</> "fsckresults" P.</> fromUUID u
 
+{- .git/annex/upgrade.log is used to record repository version upgrades. -}
+gitAnnexUpgradeLog :: Git.Repo -> RawFilePath
+gitAnnexUpgradeLog r = gitAnnexDir r P.</> "upgrade.log"
+
+gitAnnexUpgradeLock :: Git.Repo -> RawFilePath
+gitAnnexUpgradeLock r = gitAnnexDir r P.</> "upgrade.lck"
+
 {- .git/annex/smudge.log is used to log smudges worktree files that need to
  - be updated. -}
 gitAnnexSmudgeLog :: Git.Repo -> RawFilePath
diff --git a/Logs/Upgrade.hs b/Logs/Upgrade.hs
new file mode 100644 (file)
index 0000000..62974f6
--- /dev/null
@@ -0,0 +1,52 @@
+{- git-annex upgrade log
+ -
+ - This file is stored locally in .git/annex/, not in the git-annex branch.
+ -
+ - The format: "version timestamp"
+ -
+ - Copyright 2022 Joey Hess <id@joeyh.name>
+ -
+ - Licensed under the GNU AGPL version 3 or higher.
+ -}
+
+module Logs.Upgrade (
+       writeUpgradeLog,
+       readUpgradeLog,
+       timeOfUpgrade,
+) where
+
+import Annex.Common
+import Utility.TimeStamp
+import Logs.File
+import Types.RepoVersion
+
+import Data.Time.Clock.POSIX
+
+writeUpgradeLog :: RepoVersion -> POSIXTime-> Annex ()
+writeUpgradeLog v t = do
+       logfile <- fromRepo gitAnnexUpgradeLog
+       appendLogFile logfile gitAnnexUpgradeLock $ encodeBL $
+               show (fromRepoVersion v) ++ " " ++ show t
+
+readUpgradeLog :: Annex [(RepoVersion, POSIXTime)]
+readUpgradeLog = do
+       logfile <- fromRawFilePath <$> fromRepo gitAnnexUpgradeLog
+       ifM (liftIO $ doesFileExist logfile)
+               ( mapMaybe parse . lines
+                       <$> liftIO (readFileStrict logfile)
+               , return []
+               )
+  where
+       parse line = case (readish sint, parsePOSIXTime ts) of
+               (Just v, Just t) -> Just (RepoVersion v, t)
+               _ -> Nothing
+         where
+               (sint, ts) = separate (== ' ') line
+
+timeOfUpgrade :: RepoVersion -> Annex (Maybe POSIXTime)
+timeOfUpgrade want = do
+       l <- readUpgradeLog
+       return $ case filter (\(v, _) -> v == want) l of
+               [] -> Nothing
+               l' -> Just (minimum (map snd l'))
+
index c8a7c7a74898588310a26fef731826d38d95f23d..6704000f38ff84785d23cd359b9a9083b69cc401 100644 (file)
@@ -17,6 +17,7 @@ import Config
 import Annex.Path
 import Annex.Version
 import Types.RepoVersion
+import Logs.Upgrade
 #ifndef mingw32_HOST_OS
 import qualified Upgrade.V0
 import qualified Upgrade.V1
@@ -31,6 +32,7 @@ import qualified Upgrade.V8
 import qualified Upgrade.V9
 
 import qualified Data.Map as M
+import Data.Time.Clock.POSIX
 
 checkUpgrade :: RepoVersion -> Annex ()
 checkUpgrade = maybe noop giveup <=< needsUpgrade
@@ -85,7 +87,7 @@ upgrade automatic destversion = do
 
        postupgrade newversion = ifM upgradingRemote
                ( reloadConfig
-               , maybe noop setVersion newversion
+               , maybe noop upgradedto newversion
                )
 
 #ifndef mingw32_HOST_OS
@@ -120,5 +122,9 @@ upgrade automatic destversion = do
                                _ -> (False, Nothing)
                        )
 
+       upgradedto v = do
+               setVersion v
+               writeUpgradeLog v =<< liftIO getPOSIXTime
+
 upgradingRemote :: Annex Bool
 upgradingRemote = isJust <$> fromRepo Git.remoteName
index 41cf31513159b98c9f9c1a18ae569878b9f561ae..0f3280689d1c5457b3d99e6038460202ec8c8944 100644 (file)
@@ -13,20 +13,7 @@ import Utility.Daemon
 
 upgrade :: Bool -> Annex UpgradeResult
 upgrade automatic = do
-       -- Skip running when git-annex assistant (or watch) is running,
-       -- because these are long-running daemons that could conceivably
-       -- run for an entire year, and so still be running when the v10
-       -- upgrade happens. If the assistant then tried to drop a file
-       -- after the v10 upgrade, it would use the wrong content file
-       -- locking, which could lead to data loss. The remotedaemon does
-       -- not drop content, so will not block the upgrade.
-       pidfile <- fromRepo gitAnnexPidFile
-       liftIO (checkDaemon (fromRawFilePath pidfile)) >>= \case
-               Just _pid
-                       | automatic -> return UpgradeDeferred
-                       | otherwise -> giveup "Cannot upgrade to v9 when git-annex assistant or watch daemon is running."
-               Nothing -> do
-                       unless automatic $
-                               showAction "v8 to v9"
+       unless automatic $
+               showAction "v8 to v9"
 
-                       return UpgradeSuccess
+       return UpgradeSuccess
index 6208e5e0fdfd78c1d378b62b453f62dcaa905f86..43822ebbd9cadfaf012b30ca89de351b99cd30e3 100644 (file)
@@ -13,9 +13,41 @@ import Annex.Content
 import Annex.Perms
 import Git.ConfigTypes
 import Types.RepoVersion
+import Logs.Upgrade
+import Utility.Daemon
+
+import Data.Time.Clock.POSIX
 
 upgrade :: Bool -> Annex UpgradeResult
-upgrade automatic = do
+upgrade automatic
+       | automatic = do
+               -- For automatic upgrade, wait until a year after the v9
+               -- upgrade. This is to give time for any old processes
+               -- that were running before the v9 upgrade to finish.
+               -- Such old processes lock content using the old method,
+               -- and it is not safe for such to still be running after
+               -- this upgrade.
+               timeOfUpgrade (RepoVersion 9) >>= \case
+                       Nothing -> performUpgrade automatic
+                       Just t -> do
+                               now <- liftIO getPOSIXTime
+                               if now - 365*24*60*60 > t
+                                       then return UpgradeDeferred
+                                       else checkassistantrunning $
+                                               performUpgrade automatic
+       | otherwise = performUpgrade automatic
+  where
+       -- Skip upgrade when git-annex assistant (or watch) is running,
+       -- because these are long-running daemons that could conceivably
+       -- run for an entire year.
+       checkassistantrunning a = do
+               pidfile <- fromRepo gitAnnexPidFile
+               liftIO (checkDaemon (fromRawFilePath pidfile)) >>= \case
+                       Just _pid -> return UpgradeDeferred
+                       Nothing -> a
+
+performUpgrade :: Bool -> Annex UpgradeResult
+performUpgrade automatic = do
        unless automatic $
                showAction "v9 to v10"
 
index 9aa5b5033c5c049731eca3ec5556679919e47899..5b2f51386d328296f0f05933fd9ba43ddda44730 100644 (file)
@@ -943,6 +943,7 @@ Executable git-annex
     Logs.UUID
     Logs.UUIDBased
     Logs.Unused
+    Logs.Upgrade
     Logs.View
     Logs.Web
     Messages