2022-01-19 17:06:31 +00:00
|
|
|
{- git-annex v9 -> v10 upgrade support
|
|
|
|
-
|
|
|
|
- Copyright 2022 Joey Hess <id@joeyh.name>
|
|
|
|
-
|
|
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
|
|
|
-}
|
|
|
|
|
|
|
|
module Upgrade.V9 where
|
|
|
|
|
|
|
|
import Annex.Common
|
2022-01-20 15:49:56 +00:00
|
|
|
import qualified Annex
|
2022-01-19 17:06:31 +00:00
|
|
|
import Types.Upgrade
|
|
|
|
import Annex.Content
|
|
|
|
import Annex.Perms
|
2022-01-20 15:33:14 +00:00
|
|
|
import Annex.LockFile
|
|
|
|
import Annex.Version
|
2022-01-19 17:06:31 +00:00
|
|
|
import Git.ConfigTypes
|
|
|
|
import Types.RepoVersion
|
2022-01-19 19:51:04 +00:00
|
|
|
import Logs.Upgrade
|
|
|
|
import Utility.Daemon
|
|
|
|
|
|
|
|
import Data.Time.Clock.POSIX
|
2022-01-19 17:06:31 +00:00
|
|
|
|
|
|
|
upgrade :: Bool -> Annex UpgradeResult
|
2022-01-19 19:51:04 +00:00
|
|
|
upgrade automatic
|
2022-01-20 15:49:56 +00:00
|
|
|
| automatic = ifM oldprocessesdanger
|
|
|
|
( return UpgradeDeferred
|
|
|
|
, performUpgrade automatic
|
|
|
|
)
|
2022-06-28 19:28:14 +00:00
|
|
|
| otherwise = ifM (oldprocessesdanger <&&> (not <$> Annex.getRead Annex.force))
|
2022-01-21 17:15:32 +00:00
|
|
|
( do
|
|
|
|
warning $ unlines unsafeupgrade
|
|
|
|
return UpgradeDeferred
|
2022-01-20 15:49:56 +00:00
|
|
|
, performUpgrade automatic
|
|
|
|
)
|
2022-01-19 19:51:04 +00:00
|
|
|
where
|
2022-01-20 15:49:56 +00:00
|
|
|
{- Wait until a year after the v9 upgrade, 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. -}
|
|
|
|
oldprocessesdanger = timeOfUpgrade (RepoVersion 9) >>= \case
|
|
|
|
Just t -> do
|
|
|
|
now <- liftIO getPOSIXTime
|
2022-07-25 19:56:33 +00:00
|
|
|
if now < t + 365*24*60*60
|
2022-01-20 15:49:56 +00:00
|
|
|
then return True
|
2022-07-25 19:56:33 +00:00
|
|
|
else assistantrunning
|
2022-09-26 16:55:51 +00:00
|
|
|
-- Initialized at v9, so no old process danger exists.
|
|
|
|
Nothing -> pure False
|
2022-01-20 15:49:56 +00:00
|
|
|
|
2022-01-20 15:33:14 +00:00
|
|
|
{- Skip upgrade when git-annex assistant (or watch) is running,
|
|
|
|
- because these are long-running daemons that could conceivably
|
|
|
|
- run for an entire year and so predate the v9 upgrade. -}
|
2022-01-20 15:49:56 +00:00
|
|
|
assistantrunning = do
|
2022-01-19 19:51:04 +00:00
|
|
|
pidfile <- fromRepo gitAnnexPidFile
|
2022-01-20 15:49:56 +00:00
|
|
|
isJust <$> liftIO (checkDaemon (fromRawFilePath pidfile))
|
|
|
|
|
|
|
|
unsafeupgrade =
|
|
|
|
[ "Not upgrading from v9 to v10, because there may be git-annex"
|
|
|
|
, "processes running that predate the v9 upgrade. Upgrading with"
|
|
|
|
, "such processes running could lead to data loss. This upgrade"
|
|
|
|
, "will be deferred until one year after the v9 upgrade to make"
|
|
|
|
, "sure there are no such old processes running."
|
|
|
|
, "(Use --force to upgrade immediately.)"
|
|
|
|
]
|
2022-01-19 19:51:04 +00:00
|
|
|
|
|
|
|
performUpgrade :: Bool -> Annex UpgradeResult
|
|
|
|
performUpgrade automatic = do
|
2022-01-19 17:06:31 +00:00
|
|
|
unless automatic $
|
|
|
|
showAction "v9 to v10"
|
2022-01-20 15:33:14 +00:00
|
|
|
|
|
|
|
{- Take a lock to ensure that there are no other git-annex
|
|
|
|
- processes running that are using the old content locking method. -}
|
2022-08-11 20:57:44 +00:00
|
|
|
lck <- fromRepo gitAnnexContentLockLock
|
|
|
|
withExclusiveLock lck $ do
|
2022-01-20 15:33:14 +00:00
|
|
|
{- When core.sharedRepository is set, object files
|
|
|
|
- used to have their write bits set. That can now be
|
|
|
|
- removed, if the user the upgrade is running as has
|
|
|
|
- permission to remove it.
|
|
|
|
- (Otherwise, a later fsck will fix up the permissions.) -}
|
|
|
|
withShared $ \sr -> case sr of
|
|
|
|
GroupShared -> removewrite sr
|
|
|
|
AllShared -> removewrite sr
|
|
|
|
_ -> return ()
|
2022-01-19 17:06:31 +00:00
|
|
|
|
2022-01-20 15:33:14 +00:00
|
|
|
{- Set the new version while still holding the lock,
|
|
|
|
- so that any other process waiting for the lock will
|
|
|
|
- be able to detect that the upgrade happened. -}
|
|
|
|
setVersion newver
|
2022-01-19 17:06:31 +00:00
|
|
|
|
2022-01-20 15:33:14 +00:00
|
|
|
return UpgradeSuccess
|
2022-01-19 17:06:31 +00:00
|
|
|
where
|
2022-01-20 15:33:14 +00:00
|
|
|
newver = RepoVersion 10
|
2022-01-19 17:06:31 +00:00
|
|
|
|
|
|
|
removewrite sr = do
|
|
|
|
ks <- listKeys InAnnex
|
|
|
|
forM_ ks $ \k -> do
|
|
|
|
obj <- calcRepo (gitAnnexLocation k)
|
|
|
|
keystatus <- getKeyStatus k
|
|
|
|
case keystatus of
|
|
|
|
KeyPresent -> void $ tryIO $
|
2022-01-20 15:33:14 +00:00
|
|
|
freezeContent'' sr obj (Just newver)
|
2022-01-19 17:06:31 +00:00
|
|
|
KeyUnlockedThin -> return ()
|
|
|
|
KeyLockedThin -> return ()
|
|
|
|
KeyMissing -> return ()
|