plumb in LiveUpdate (WIP)
Each command that first checks preferred content (and/or required content) and then does something that can change the sizes of repositories needs to call prepareLiveUpdate, and plumb it through the preferred content check and the location log update. So far, only Command.Drop is done. Many other commands that don't need to do this have been updated to keep working. There may be some calls to NoLiveUpdate in places where that should be done. All will need to be double checked. Not currently in a compilable state.
This commit is contained in:
parent
4885073377
commit
c3d40b9ec3
58 changed files with 363 additions and 247 deletions
5
Annex.hs
5
Annex.hs
|
@ -1,6 +1,6 @@
|
||||||
{- git-annex monad
|
{- git-annex monad
|
||||||
-
|
-
|
||||||
- Copyright 2010-2021 Joey Hess <id@joeyh.name>
|
- Copyright 2010-2024 Joey Hess <id@joeyh.name>
|
||||||
-
|
-
|
||||||
- Licensed under the GNU AGPL version 3 or higher.
|
- Licensed under the GNU AGPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
@ -79,6 +79,7 @@ import Types.RepoSize
|
||||||
import Annex.VectorClock.Utility
|
import Annex.VectorClock.Utility
|
||||||
import Annex.Debug.Utility
|
import Annex.Debug.Utility
|
||||||
import qualified Database.Keys.Handle as Keys
|
import qualified Database.Keys.Handle as Keys
|
||||||
|
import Database.RepoSize.Handle
|
||||||
import Utility.InodeCache
|
import Utility.InodeCache
|
||||||
import Utility.Url
|
import Utility.Url
|
||||||
import Utility.ResourcePool
|
import Utility.ResourcePool
|
||||||
|
@ -225,6 +226,7 @@ data AnnexState = AnnexState
|
||||||
, insmudgecleanfilter :: Bool
|
, insmudgecleanfilter :: Bool
|
||||||
, getvectorclock :: IO CandidateVectorClock
|
, getvectorclock :: IO CandidateVectorClock
|
||||||
, proxyremote :: Maybe (Either ClusterUUID (Types.Remote.RemoteA Annex))
|
, proxyremote :: Maybe (Either ClusterUUID (Types.Remote.RemoteA Annex))
|
||||||
|
, reposizehandle :: Maybe RepoSizeHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
newAnnexState :: GitConfig -> Git.Repo -> IO AnnexState
|
newAnnexState :: GitConfig -> Git.Repo -> IO AnnexState
|
||||||
|
@ -280,6 +282,7 @@ newAnnexState c r = do
|
||||||
, insmudgecleanfilter = False
|
, insmudgecleanfilter = False
|
||||||
, getvectorclock = vc
|
, getvectorclock = vc
|
||||||
, proxyremote = Nothing
|
, proxyremote = Nothing
|
||||||
|
, reposizehandle = Nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
{- Makes an Annex state object for the specified git repo.
|
{- Makes an Annex state object for the specified git repo.
|
||||||
|
|
|
@ -108,7 +108,10 @@ clusterProxySelector clusteruuid protocolversion (Bypass bypass) = do
|
||||||
, proxyPUT = \af k -> do
|
, proxyPUT = \af k -> do
|
||||||
locs <- S.fromList <$> loggedLocations k
|
locs <- S.fromList <$> loggedLocations k
|
||||||
let l = filter (flip S.notMember locs . Remote.uuid . remote) nodes
|
let l = filter (flip S.notMember locs . Remote.uuid . remote) nodes
|
||||||
l' <- filterM (\n -> isPreferredContent (Just (Remote.uuid (remote n))) mempty (Just k) af True) l
|
--- XXX FIXME TODO NoLiveUpdate should not be used
|
||||||
|
-- here. Doing a live update here is exactly why
|
||||||
|
-- live update is needed.
|
||||||
|
l' <- filterM (\n -> isPreferredContent NoLiveUpdate (Just (Remote.uuid (remote n))) mempty (Just k) af True) l
|
||||||
-- PUT to no nodes doesn't work, so fall
|
-- PUT to no nodes doesn't work, so fall
|
||||||
-- back to all nodes.
|
-- back to all nodes.
|
||||||
return $ nonempty [l', l] nodes
|
return $ nonempty [l', l] nodes
|
||||||
|
|
|
@ -11,6 +11,7 @@ import Annex.Locations as X
|
||||||
import Annex.Debug as X (fastDebug, debug)
|
import Annex.Debug as X (fastDebug, debug)
|
||||||
import Messages as X
|
import Messages as X
|
||||||
import Git.Quote as X
|
import Git.Quote as X
|
||||||
|
import Types.RepoSize as X
|
||||||
#ifndef mingw32_HOST_OS
|
#ifndef mingw32_HOST_OS
|
||||||
import System.Posix.IO as X hiding (createPipe, append)
|
import System.Posix.IO as X hiding (createPipe, append)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -788,7 +788,7 @@ moveBad key = do
|
||||||
createAnnexDirectory (parentDir dest)
|
createAnnexDirectory (parentDir dest)
|
||||||
cleanObjectLoc key $
|
cleanObjectLoc key $
|
||||||
liftIO $ moveFile src dest
|
liftIO $ moveFile src dest
|
||||||
logStatus key InfoMissing
|
logStatus NoLiveUpdate key InfoMissing
|
||||||
return dest
|
return dest
|
||||||
|
|
||||||
data KeyLocation = InAnnex | InAnywhere
|
data KeyLocation = InAnnex | InAnywhere
|
||||||
|
|
|
@ -29,9 +29,9 @@ type Reason = String
|
||||||
- required content, and numcopies settings.
|
- required content, and numcopies settings.
|
||||||
-
|
-
|
||||||
- Skips trying to drop from remotes that are appendonly, since those drops
|
- Skips trying to drop from remotes that are appendonly, since those drops
|
||||||
- would presumably fail. Also skips dropping from exporttree/importtree remotes,
|
- would presumably fail. Also skips dropping from exporttree/importtree
|
||||||
- which don't allow dropping individual keys, and from thirdPartyPopulated
|
- remotes, which don't allow dropping individual keys, and from
|
||||||
- remotes.
|
- thirdPartyPopulated remotes.
|
||||||
-
|
-
|
||||||
- The UUIDs are ones where the content is believed to be present.
|
- The UUIDs are ones where the content is believed to be present.
|
||||||
- The Remote list can include other remotes that do not have the content;
|
- The Remote list can include other remotes that do not have the content;
|
||||||
|
@ -92,11 +92,12 @@ handleDropsFrom locs rs reason fromhere key afile si preverified runner = do
|
||||||
dropr fs r n >>= go fs rest
|
dropr fs r n >>= go fs rest
|
||||||
| otherwise = pure n
|
| otherwise = pure n
|
||||||
|
|
||||||
checkdrop fs n u a =
|
checkdrop fs n u a = do
|
||||||
let afs = map (AssociatedFile . Just) fs
|
let afs = map (AssociatedFile . Just) fs
|
||||||
pcc = Command.Drop.PreferredContentChecked True
|
let pcc = Command.Drop.PreferredContentChecked True
|
||||||
in ifM (wantDrop True u (Just key) afile (Just afs))
|
lu <- prepareLiveUpdate u key RemovingKey
|
||||||
( dodrop n u (a pcc)
|
ifM (wantDrop lu True u (Just key) afile (Just afs))
|
||||||
|
( dodrop n u (a lu pcc)
|
||||||
, return n
|
, return n
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -116,12 +117,16 @@ handleDropsFrom locs rs reason fromhere key afile si preverified runner = do
|
||||||
, return n
|
, return n
|
||||||
)
|
)
|
||||||
|
|
||||||
dropl fs n = checkdrop fs n Nothing $ \pcc numcopies mincopies ->
|
dropl fs n = checkdrop fs n Nothing $ \lu pcc numcopies mincopies ->
|
||||||
stopUnless (inAnnex key) $
|
stopUnless (inAnnex key) $
|
||||||
Command.Drop.startLocal pcc afile ai si numcopies mincopies key preverified (Command.Drop.DroppingUnused False)
|
Command.Drop.startLocal lu pcc afile ai si
|
||||||
|
numcopies mincopies key preverified
|
||||||
|
(Command.Drop.DroppingUnused False)
|
||||||
|
|
||||||
dropr fs r n = checkdrop fs n (Just $ Remote.uuid r) $ \pcc numcopies mincopies ->
|
dropr fs r n = checkdrop fs n (Just $ Remote.uuid r) $ \lu pcc numcopies mincopies ->
|
||||||
Command.Drop.startRemote pcc afile ai si numcopies mincopies key (Command.Drop.DroppingUnused False) r
|
Command.Drop.startRemote lu pcc afile ai si
|
||||||
|
numcopies mincopies key
|
||||||
|
(Command.Drop.DroppingUnused False) r
|
||||||
|
|
||||||
ai = mkActionItem (key, afile)
|
ai = mkActionItem (key, afile)
|
||||||
|
|
||||||
|
|
|
@ -53,22 +53,22 @@ import Control.Monad.Writer
|
||||||
|
|
||||||
type GetFileMatcher = RawFilePath -> Annex (FileMatcher Annex)
|
type GetFileMatcher = RawFilePath -> Annex (FileMatcher Annex)
|
||||||
|
|
||||||
checkFileMatcher :: GetFileMatcher -> RawFilePath -> Annex Bool
|
checkFileMatcher :: LiveUpdate -> GetFileMatcher -> RawFilePath -> Annex Bool
|
||||||
checkFileMatcher getmatcher file =
|
checkFileMatcher lu getmatcher file =
|
||||||
checkFileMatcher' getmatcher file (return True)
|
checkFileMatcher' lu getmatcher file (return True)
|
||||||
|
|
||||||
-- | Allows running an action when no matcher is configured for the file.
|
-- | Allows running an action when no matcher is configured for the file.
|
||||||
checkFileMatcher' :: GetFileMatcher -> RawFilePath -> Annex Bool -> Annex Bool
|
checkFileMatcher' :: LiveUpdate -> GetFileMatcher -> RawFilePath -> Annex Bool -> Annex Bool
|
||||||
checkFileMatcher' getmatcher file notconfigured = do
|
checkFileMatcher' lu getmatcher file notconfigured = do
|
||||||
matcher <- getmatcher file
|
matcher <- getmatcher file
|
||||||
checkMatcher matcher Nothing afile S.empty notconfigured d
|
checkMatcher matcher Nothing afile lu S.empty notconfigured d
|
||||||
where
|
where
|
||||||
afile = AssociatedFile (Just file)
|
afile = AssociatedFile (Just file)
|
||||||
-- checkMatcher will never use this, because afile is provided.
|
-- checkMatcher will never use this, because afile is provided.
|
||||||
d = return True
|
d = return True
|
||||||
|
|
||||||
checkMatcher :: FileMatcher Annex -> Maybe Key -> AssociatedFile -> AssumeNotPresent -> Annex Bool -> Annex Bool -> Annex Bool
|
checkMatcher :: FileMatcher Annex -> Maybe Key -> AssociatedFile -> LiveUpdate -> AssumeNotPresent -> Annex Bool -> Annex Bool -> Annex Bool
|
||||||
checkMatcher matcher mkey afile notpresent notconfigured d
|
checkMatcher matcher mkey afile lu notpresent notconfigured d
|
||||||
| isEmpty (fst matcher) = notconfigured
|
| isEmpty (fst matcher) = notconfigured
|
||||||
| otherwise = case (mkey, afile) of
|
| otherwise = case (mkey, afile) of
|
||||||
(_, AssociatedFile (Just file)) ->
|
(_, AssociatedFile (Just file)) ->
|
||||||
|
@ -85,12 +85,12 @@ checkMatcher matcher mkey afile notpresent notconfigured d
|
||||||
in go (MatchingInfo i)
|
in go (MatchingInfo i)
|
||||||
(Nothing, _) -> d
|
(Nothing, _) -> d
|
||||||
where
|
where
|
||||||
go mi = checkMatcher' matcher mi notpresent
|
go mi = checkMatcher' matcher mi lu notpresent
|
||||||
|
|
||||||
checkMatcher' :: FileMatcher Annex -> MatchInfo -> AssumeNotPresent -> Annex Bool
|
checkMatcher' :: FileMatcher Annex -> MatchInfo -> LiveUpdate -> AssumeNotPresent -> Annex Bool
|
||||||
checkMatcher' (matcher, (MatcherDesc matcherdesc)) mi notpresent = do
|
checkMatcher' (matcher, (MatcherDesc matcherdesc)) mi lu notpresent = do
|
||||||
(matches, desc) <- runWriterT $ matchMrun' matcher $ \op ->
|
(matches, desc) <- runWriterT $ matchMrun' matcher $ \op ->
|
||||||
matchAction op notpresent mi
|
matchAction op lu notpresent mi
|
||||||
explain (mkActionItem mi) $ UnquotedString <$>
|
explain (mkActionItem mi) $ UnquotedString <$>
|
||||||
describeMatchResult matchDesc desc
|
describeMatchResult matchDesc desc
|
||||||
((if matches then "matches " else "does not match ") ++ matcherdesc ++ ": ")
|
((if matches then "matches " else "does not match ") ++ matcherdesc ++ ": ")
|
||||||
|
@ -259,9 +259,9 @@ addUnlockedMatcher = AddUnlockedMatcher <$>
|
||||||
matchalways True = return (MOp limitAnything, matcherdesc)
|
matchalways True = return (MOp limitAnything, matcherdesc)
|
||||||
matchalways False = return (MOp limitNothing, matcherdesc)
|
matchalways False = return (MOp limitNothing, matcherdesc)
|
||||||
|
|
||||||
checkAddUnlockedMatcher :: AddUnlockedMatcher -> MatchInfo -> Annex Bool
|
checkAddUnlockedMatcher :: LiveUpdate -> AddUnlockedMatcher -> MatchInfo -> Annex Bool
|
||||||
checkAddUnlockedMatcher (AddUnlockedMatcher matcher) mi =
|
checkAddUnlockedMatcher lu (AddUnlockedMatcher matcher) mi =
|
||||||
checkMatcher' matcher mi S.empty
|
checkMatcher' matcher mi lu S.empty
|
||||||
|
|
||||||
simply :: MatchFiles Annex -> ParseResult (MatchFiles Annex)
|
simply :: MatchFiles Annex -> ParseResult (MatchFiles Annex)
|
||||||
simply = Right . Operation
|
simply = Right . Operation
|
||||||
|
@ -271,8 +271,8 @@ usev a v = Operation <$> a v
|
||||||
|
|
||||||
call :: String -> Either String (Matcher (MatchFiles Annex)) -> ParseResult (MatchFiles Annex)
|
call :: String -> Either String (Matcher (MatchFiles Annex)) -> ParseResult (MatchFiles Annex)
|
||||||
call desc (Right sub) = Right $ Operation $ MatchFiles
|
call desc (Right sub) = Right $ Operation $ MatchFiles
|
||||||
{ matchAction = \notpresent mi ->
|
{ matchAction = \lu notpresent mi ->
|
||||||
matchMrun sub $ \o -> matchAction o notpresent mi
|
matchMrun sub $ \o -> matchAction o lu notpresent mi
|
||||||
, matchNeedsFileName = any matchNeedsFileName sub
|
, matchNeedsFileName = any matchNeedsFileName sub
|
||||||
, matchNeedsFileContent = any matchNeedsFileContent sub
|
, matchNeedsFileContent = any matchNeedsFileContent sub
|
||||||
, matchNeedsKey = any matchNeedsKey sub
|
, matchNeedsKey = any matchNeedsKey sub
|
||||||
|
|
|
@ -191,7 +191,7 @@ recordImportTree remote importtreeconfig imported = do
|
||||||
let updater db moldkey _newkey _ = case moldkey of
|
let updater db moldkey _newkey _ = case moldkey of
|
||||||
Just oldkey | not (isGitShaKey oldkey) ->
|
Just oldkey | not (isGitShaKey oldkey) ->
|
||||||
unlessM (stillpresent db oldkey) $
|
unlessM (stillpresent db oldkey) $
|
||||||
logChange oldkey (Remote.uuid remote) InfoMissing
|
logChange NoLiveUpdate oldkey (Remote.uuid remote) InfoMissing
|
||||||
_ -> noop
|
_ -> noop
|
||||||
-- When the remote is versioned, it still contains keys
|
-- When the remote is versioned, it still contains keys
|
||||||
-- that are not present in the new tree.
|
-- that are not present in the new tree.
|
||||||
|
@ -763,7 +763,7 @@ importKeys remote importtreeconfig importcontent thirdpartypopulated importablec
|
||||||
tryNonAsync (importkey loc cid sz nullMeterUpdate) >>= \case
|
tryNonAsync (importkey loc cid sz nullMeterUpdate) >>= \case
|
||||||
Right (Just k) -> do
|
Right (Just k) -> do
|
||||||
recordcidkeyindb db cid k
|
recordcidkeyindb db cid k
|
||||||
logChange k (Remote.uuid remote) InfoPresent
|
logChange NoLiveUpdate k (Remote.uuid remote) InfoPresent
|
||||||
return $ Just (loc, Right k)
|
return $ Just (loc, Right k)
|
||||||
Right Nothing -> return Nothing
|
Right Nothing -> return Nothing
|
||||||
Left e -> do
|
Left e -> do
|
||||||
|
@ -799,7 +799,7 @@ importKeys remote importtreeconfig importcontent thirdpartypopulated importablec
|
||||||
, providedMimeEncoding = Nothing
|
, providedMimeEncoding = Nothing
|
||||||
, providedLinkType = Nothing
|
, providedLinkType = Nothing
|
||||||
}
|
}
|
||||||
islargefile <- checkMatcher' matcher mi mempty
|
islargefile <- checkMatcher' matcher mi NoLiveUpdate mempty
|
||||||
metered Nothing sz bwlimit $ const $ if islargefile
|
metered Nothing sz bwlimit $ const $ if islargefile
|
||||||
then doimportlarge importkey cidmap loc cid sz f
|
then doimportlarge importkey cidmap loc cid sz f
|
||||||
else doimportsmall cidmap loc cid sz
|
else doimportsmall cidmap loc cid sz
|
||||||
|
@ -823,7 +823,7 @@ importKeys remote importtreeconfig importcontent thirdpartypopulated importablec
|
||||||
Just k -> checkSecureHashes k >>= \case
|
Just k -> checkSecureHashes k >>= \case
|
||||||
Nothing -> do
|
Nothing -> do
|
||||||
recordcidkey cidmap cid k
|
recordcidkey cidmap cid k
|
||||||
logChange k (Remote.uuid remote) InfoPresent
|
logChange NoLiveUpdate k (Remote.uuid remote) InfoPresent
|
||||||
if importcontent
|
if importcontent
|
||||||
then getcontent k
|
then getcontent k
|
||||||
else return (Just (k, True))
|
else return (Just (k, True))
|
||||||
|
@ -839,7 +839,7 @@ importKeys remote importtreeconfig importcontent thirdpartypopulated importablec
|
||||||
(combineMeterUpdate p' p)
|
(combineMeterUpdate p' p)
|
||||||
ok <- moveAnnex k af tmpfile
|
ok <- moveAnnex k af tmpfile
|
||||||
when ok $
|
when ok $
|
||||||
logStatus k InfoPresent
|
logStatus NoLiveUpdate k InfoPresent
|
||||||
return (Just (k, ok))
|
return (Just (k, ok))
|
||||||
checkDiskSpaceToGet k Nothing Nothing $
|
checkDiskSpaceToGet k Nothing Nothing $
|
||||||
notifyTransfer Download af $
|
notifyTransfer Download af $
|
||||||
|
@ -883,8 +883,8 @@ importKeys remote importtreeconfig importcontent thirdpartypopulated importablec
|
||||||
ok <- moveAnnex k af tmpfile
|
ok <- moveAnnex k af tmpfile
|
||||||
when ok $ do
|
when ok $ do
|
||||||
recordcidkey cidmap cid k
|
recordcidkey cidmap cid k
|
||||||
logStatus k InfoPresent
|
logStatus NoLiveUpdate k InfoPresent
|
||||||
logChange k (Remote.uuid remote) InfoPresent
|
logChange NoLiveUpdate k (Remote.uuid remote) InfoPresent
|
||||||
return (Right k, ok)
|
return (Right k, ok)
|
||||||
Just sha -> do
|
Just sha -> do
|
||||||
recordcidkey cidmap cid k
|
recordcidkey cidmap cid k
|
||||||
|
@ -910,7 +910,7 @@ importKeys remote importtreeconfig importcontent thirdpartypopulated importablec
|
||||||
, contentFile = tmpfile
|
, contentFile = tmpfile
|
||||||
, matchKey = Nothing
|
, matchKey = Nothing
|
||||||
}
|
}
|
||||||
islargefile <- checkMatcher' matcher mi mempty
|
islargefile <- checkMatcher' matcher mi NoLiveUpdate mempty
|
||||||
if islargefile
|
if islargefile
|
||||||
then do
|
then do
|
||||||
backend <- chooseBackend f
|
backend <- chooseBackend f
|
||||||
|
@ -1085,7 +1085,7 @@ isKnownImportLocation dbhandle loc = liftIO $
|
||||||
not . null <$> Export.getExportTreeKey dbhandle loc
|
not . null <$> Export.getExportTreeKey dbhandle loc
|
||||||
|
|
||||||
matchesImportLocation :: FileMatcher Annex -> ImportLocation -> Integer -> Annex Bool
|
matchesImportLocation :: FileMatcher Annex -> ImportLocation -> Integer -> Annex Bool
|
||||||
matchesImportLocation matcher loc sz = checkMatcher' matcher mi mempty
|
matchesImportLocation matcher loc sz = checkMatcher' matcher mi NoLiveUpdate mempty
|
||||||
where
|
where
|
||||||
mi = MatchingInfo $ ProvidedInfo
|
mi = MatchingInfo $ ProvidedInfo
|
||||||
{ providedFilePath = Just (fromImportLocation loc)
|
{ providedFilePath = Just (fromImportLocation loc)
|
||||||
|
|
|
@ -288,7 +288,7 @@ cleanOldKeys file newkey = do
|
||||||
(f:_) -> do
|
(f:_) -> do
|
||||||
ic <- withTSDelta (liftIO . genInodeCache f)
|
ic <- withTSDelta (liftIO . genInodeCache f)
|
||||||
void $ linkToAnnex key f ic
|
void $ linkToAnnex key f ic
|
||||||
_ -> logStatus key InfoMissing
|
_ -> logStatus NoLiveUpdate key InfoMissing
|
||||||
|
|
||||||
{- On error, put the file back so it doesn't seem to have vanished.
|
{- On error, put the file back so it doesn't seem to have vanished.
|
||||||
- This can be called before or after the symlink is in place. -}
|
- This can be called before or after the symlink is in place. -}
|
||||||
|
@ -349,7 +349,7 @@ gitAddParams (CheckGitIgnore False) = return [Param "-f"]
|
||||||
addUnlocked :: AddUnlockedMatcher -> MatchInfo -> Bool -> Annex Bool
|
addUnlocked :: AddUnlockedMatcher -> MatchInfo -> Bool -> Annex Bool
|
||||||
addUnlocked matcher mi contentpresent =
|
addUnlocked matcher mi contentpresent =
|
||||||
((not . coreSymlinks <$> Annex.getGitConfig) <||>
|
((not . coreSymlinks <$> Annex.getGitConfig) <||>
|
||||||
(checkAddUnlockedMatcher matcher mi) <||>
|
(checkAddUnlockedMatcher NoLiveUpdate matcher mi) <||>
|
||||||
(maybe False go . snd <$> getCurrentBranch)
|
(maybe False go . snd <$> getCurrentBranch)
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
|
@ -365,6 +365,6 @@ canProxyForRemote rs myproxies myclusters remoteuuid =
|
||||||
|
|
||||||
mkProxyMethods :: ProxyMethods
|
mkProxyMethods :: ProxyMethods
|
||||||
mkProxyMethods = ProxyMethods
|
mkProxyMethods = ProxyMethods
|
||||||
{ removedContent = \u k -> logChange k u InfoMissing
|
{ removedContent = \u k -> logChange NoLiveUpdate k u InfoMissing
|
||||||
, addedContent = \u k -> logChange k u InfoPresent
|
, addedContent = \u k -> logChange NoLiveUpdate k u InfoPresent
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ import Annex.Common
|
||||||
import Annex.RepoSize.LiveUpdate
|
import Annex.RepoSize.LiveUpdate
|
||||||
import qualified Annex
|
import qualified Annex
|
||||||
import Annex.Branch (UnmergedBranches(..), getBranch)
|
import Annex.Branch (UnmergedBranches(..), getBranch)
|
||||||
import Types.RepoSize
|
|
||||||
import qualified Database.RepoSize as Db
|
import qualified Database.RepoSize as Db
|
||||||
import Logs
|
import Logs
|
||||||
import Logs.Location
|
import Logs.Location
|
||||||
|
@ -71,9 +70,9 @@ calcRepoSizes quiet rsv = bracket setup cleanup $ \h -> go h `onException` faile
|
||||||
liftIO $ Db.setRepoSizes h sizemap branchsha
|
liftIO $ Db.setRepoSizes h sizemap branchsha
|
||||||
calcJournalledRepoSizes sizemap branchsha
|
calcJournalledRepoSizes sizemap branchsha
|
||||||
|
|
||||||
setup = Db.openDb
|
setup = Db.getRepoSizeHandle
|
||||||
|
|
||||||
cleanup = Db.closeDb
|
cleanup _ = return ()
|
||||||
|
|
||||||
failed = do
|
failed = do
|
||||||
liftIO $ putMVar rsv (Just M.empty)
|
liftIO $ putMVar rsv (Just M.empty)
|
||||||
|
|
|
@ -11,15 +11,16 @@ module Annex.RepoSize.LiveUpdate where
|
||||||
|
|
||||||
import Annex.Common
|
import Annex.Common
|
||||||
import qualified Annex
|
import qualified Annex
|
||||||
import Types.RepoSize
|
|
||||||
import Logs.Presence.Pure
|
import Logs.Presence.Pure
|
||||||
|
import qualified Database.RepoSize as Db
|
||||||
|
import Annex.UUID
|
||||||
|
|
||||||
import Control.Concurrent
|
import Control.Concurrent
|
||||||
import qualified Data.Map.Strict as M
|
import qualified Data.Map.Strict as M
|
||||||
import qualified Data.Set as S
|
import qualified Data.Set as S
|
||||||
|
|
||||||
updateRepoSize :: UUID -> Key -> LogStatus -> Annex ()
|
updateRepoSize :: LiveUpdate -> UUID -> Key -> LogStatus -> Annex ()
|
||||||
updateRepoSize u k s = do
|
updateRepoSize lu u k s = do
|
||||||
rsv <- Annex.getRead Annex.reposizes
|
rsv <- Annex.getRead Annex.reposizes
|
||||||
liftIO (takeMVar rsv) >>= \case
|
liftIO (takeMVar rsv) >>= \case
|
||||||
Nothing -> liftIO (putMVar rsv Nothing)
|
Nothing -> liftIO (putMVar rsv Nothing)
|
||||||
|
@ -52,3 +53,48 @@ accumRepoSizes :: Key -> (S.Set UUID, S.Set UUID) -> M.Map UUID RepoSize -> M.Ma
|
||||||
accumRepoSizes k (newlocs, removedlocs) sizemap =
|
accumRepoSizes k (newlocs, removedlocs) sizemap =
|
||||||
let !sizemap' = foldl' (flip $ M.alter $ addKeyRepoSize k) sizemap newlocs
|
let !sizemap' = foldl' (flip $ M.alter $ addKeyRepoSize k) sizemap newlocs
|
||||||
in foldl' (flip $ M.alter $ removeKeyRepoSize k) sizemap' removedlocs
|
in foldl' (flip $ M.alter $ removeKeyRepoSize k) sizemap' removedlocs
|
||||||
|
|
||||||
|
-- Called when a preferred content check indicates that a live update is
|
||||||
|
-- needed. Can be called more than once.
|
||||||
|
startLiveUpdate :: LiveUpdate -> Annex ()
|
||||||
|
startLiveUpdate (LiveUpdate startv _donev) =
|
||||||
|
liftIO $ void $ tryPutMVar startv ()
|
||||||
|
startLiveUpdate NoLiveUpdate = noop
|
||||||
|
|
||||||
|
-- When the UUID is Nothing, it's a live update of the local repository.
|
||||||
|
prepareLiveUpdate :: Maybe UUID -> Key -> SizeChange -> Annex LiveUpdate
|
||||||
|
prepareLiveUpdate mu k sc = do
|
||||||
|
h <- Db.getRepoSizeHandle
|
||||||
|
u <- maybe getUUID pure mu
|
||||||
|
startv <- liftIO newEmptyMVar
|
||||||
|
donev <- liftIO newEmptyMVar
|
||||||
|
void $ liftIO $ forkIO $ waitstart startv donev h u
|
||||||
|
return (LiveUpdate startv donev)
|
||||||
|
where
|
||||||
|
{- Wait for startLiveUpdate, or for the LiveUpdate to get garbage
|
||||||
|
- collected in the case where it is never going to start. -}
|
||||||
|
waitstart startv donev h u = tryNonAsync (takeMVar startv) >>= \case
|
||||||
|
Right _ -> do
|
||||||
|
Db.startingLiveSizeChange h u k sc
|
||||||
|
waitdone donev h u
|
||||||
|
Left _ -> noop
|
||||||
|
|
||||||
|
{- Wait for endLiveUpdate to be called, or for the LiveUpdate to
|
||||||
|
- get garbage collected in the case where the change didn't
|
||||||
|
- actually happen. -}
|
||||||
|
waitdone donev h u = tryNonAsync (takeMVar donev) >>= \case
|
||||||
|
-- TODO if succeeded == True, need to update RepoSize db
|
||||||
|
-- in same transaction as Db.finishedLiveSizeChange
|
||||||
|
Right (succeeded, u', k', sc')
|
||||||
|
| u' == u && k' == k && sc' == sc -> done h u
|
||||||
|
-- This can happen when eg, storing to a cluster
|
||||||
|
-- causes fanout and so this is called with
|
||||||
|
-- other UUIDs.
|
||||||
|
| otherwise -> waitdone donev h u
|
||||||
|
Left _ -> done h u
|
||||||
|
done h u = Db.finishedLiveSizeChange h u k sc
|
||||||
|
|
||||||
|
finishedLiveUpdate :: LiveUpdate -> Bool -> UUID -> Key -> SizeChange -> IO ()
|
||||||
|
finishedLiveUpdate (LiveUpdate _startv donev) succeeded u k sc =
|
||||||
|
putMVar donev (succeeded, u, k, sc)
|
||||||
|
finishedLiveUpdate NoLiveUpdate _ _ _ _ = noop
|
||||||
|
|
|
@ -18,12 +18,12 @@ import Types.FileMatcher
|
||||||
import qualified Data.Set as S
|
import qualified Data.Set as S
|
||||||
|
|
||||||
{- Check if a file is preferred content for the local repository. -}
|
{- Check if a file is preferred content for the local repository. -}
|
||||||
wantGet :: Bool -> Maybe Key -> AssociatedFile -> Annex Bool
|
wantGet :: LiveUpdate -> Bool -> Maybe Key -> AssociatedFile -> Annex Bool
|
||||||
wantGet d key file = isPreferredContent Nothing S.empty key file d
|
wantGet lu d key file = isPreferredContent lu Nothing S.empty key file d
|
||||||
|
|
||||||
{- Check if a file is preferred content for a repository. -}
|
{- Check if a file is preferred content for a repository. -}
|
||||||
wantGetBy :: Bool -> Maybe Key -> AssociatedFile -> UUID -> Annex Bool
|
wantGetBy :: LiveUpdate -> Bool -> Maybe Key -> AssociatedFile -> UUID -> Annex Bool
|
||||||
wantGetBy d key file to = isPreferredContent (Just to) S.empty key file d
|
wantGetBy lu d key file to = isPreferredContent lu (Just to) S.empty key file d
|
||||||
|
|
||||||
{- Check if a file is not preferred or required content, and can be
|
{- Check if a file is not preferred or required content, and can be
|
||||||
- dropped. When a UUID is provided, checks for that repository.
|
- dropped. When a UUID is provided, checks for that repository.
|
||||||
|
@ -34,20 +34,20 @@ wantGetBy d key file to = isPreferredContent (Just to) S.empty key file d
|
||||||
- that will prevent dropping. When the other associated files are known,
|
- that will prevent dropping. When the other associated files are known,
|
||||||
- they can be provided, otherwise this looks them up.
|
- they can be provided, otherwise this looks them up.
|
||||||
-}
|
-}
|
||||||
wantDrop :: Bool -> Maybe UUID -> Maybe Key -> AssociatedFile -> (Maybe [AssociatedFile]) -> Annex Bool
|
wantDrop :: LiveUpdate -> Bool -> Maybe UUID -> Maybe Key -> AssociatedFile -> (Maybe [AssociatedFile]) -> Annex Bool
|
||||||
wantDrop d from key file others =
|
wantDrop lu d from key file others =
|
||||||
isNothing <$> checkDrop isPreferredContent d from key file others
|
isNothing <$> checkDrop isPreferredContent lu d from key file others
|
||||||
|
|
||||||
{- Generalization of wantDrop that can also be used with isRequiredContent.
|
{- Generalization of wantDrop that can also be used with isRequiredContent.
|
||||||
-
|
-
|
||||||
- When the content should not be dropped, returns Just the file that
|
- When the content should not be dropped, returns Just the file that
|
||||||
- the checker matches.
|
- the checker matches.
|
||||||
-}
|
-}
|
||||||
checkDrop :: (Maybe UUID -> AssumeNotPresent -> Maybe Key -> AssociatedFile -> Bool -> Annex Bool) -> Bool -> Maybe UUID -> Maybe Key -> AssociatedFile -> (Maybe [AssociatedFile]) -> Annex (Maybe AssociatedFile)
|
checkDrop :: (LiveUpdate -> Maybe UUID -> AssumeNotPresent -> Maybe Key -> AssociatedFile -> Bool -> Annex Bool) -> LiveUpdate -> Bool -> Maybe UUID -> Maybe Key -> AssociatedFile -> (Maybe [AssociatedFile]) -> Annex (Maybe AssociatedFile)
|
||||||
checkDrop checker d from key file others = do
|
checkDrop checker lu d from key file others = do
|
||||||
u <- maybe getUUID (pure . id) from
|
u <- maybe getUUID (pure . id) from
|
||||||
let s = S.singleton u
|
let s = S.singleton u
|
||||||
let checker' f = checker (Just u) s key f d
|
let checker' f = checker lu (Just u) s key f d
|
||||||
ifM (checker' file)
|
ifM (checker' file)
|
||||||
( return (Just file)
|
( return (Just file)
|
||||||
, do
|
, do
|
||||||
|
|
|
@ -214,7 +214,7 @@ onAddFile symlinkssupported f fs =
|
||||||
Database.Keys.removeAssociatedFile oldkey
|
Database.Keys.removeAssociatedFile oldkey
|
||||||
=<< inRepo (toTopFilePath (toRawFilePath file))
|
=<< inRepo (toTopFilePath (toRawFilePath file))
|
||||||
unlessM (inAnnex oldkey) $
|
unlessM (inAnnex oldkey) $
|
||||||
logStatus oldkey InfoMissing
|
logStatus NoLiveUpdate oldkey InfoMissing
|
||||||
addlink file key = do
|
addlink file key = do
|
||||||
mode <- liftIO $ catchMaybeIO $ fileMode <$> R.getFileStatus (toRawFilePath file)
|
mode <- liftIO $ catchMaybeIO $ fileMode <$> R.getFileStatus (toRawFilePath file)
|
||||||
liftAnnex $ stagePointerFile (toRawFilePath file) mode =<< hashPointerFile key
|
liftAnnex $ stagePointerFile (toRawFilePath file) mode =<< hashPointerFile key
|
||||||
|
|
|
@ -60,7 +60,7 @@ queueTransfers = queueTransfersMatching (const True)
|
||||||
- condition. Honors preferred content settings. -}
|
- condition. Honors preferred content settings. -}
|
||||||
queueTransfersMatching :: (UUID -> Bool) -> Reason -> Schedule -> Key -> AssociatedFile -> Direction -> Assistant Bool
|
queueTransfersMatching :: (UUID -> Bool) -> Reason -> Schedule -> Key -> AssociatedFile -> Direction -> Assistant Bool
|
||||||
queueTransfersMatching matching reason schedule k f direction
|
queueTransfersMatching matching reason schedule k f direction
|
||||||
| direction == Download = ifM (liftAnnex $ wantGet True (Just k) f)
|
| direction == Download = ifM (liftAnnex $ wantGet NoLiveUpdate True (Just k) f)
|
||||||
( go
|
( go
|
||||||
, return False
|
, return False
|
||||||
)
|
)
|
||||||
|
@ -89,7 +89,7 @@ queueTransfersMatching matching reason schedule k f direction
|
||||||
- already have it. -}
|
- already have it. -}
|
||||||
| otherwise = do
|
| otherwise = do
|
||||||
s <- locs
|
s <- locs
|
||||||
filterM (wantGetBy True (Just k) f . Remote.uuid) $
|
filterM (wantGetBy NoLiveUpdate True (Just k) f . Remote.uuid) $
|
||||||
filter (\r -> not (inset s r || Remote.readonly r))
|
filter (\r -> not (inset s r || Remote.readonly r))
|
||||||
(syncDataRemotes st)
|
(syncDataRemotes st)
|
||||||
where
|
where
|
||||||
|
|
|
@ -210,11 +210,11 @@ genTransfer t info = case transferRemote info of
|
||||||
shouldTransfer :: Transfer -> TransferInfo -> Annex Bool
|
shouldTransfer :: Transfer -> TransferInfo -> Annex Bool
|
||||||
shouldTransfer t info
|
shouldTransfer t info
|
||||||
| transferDirection t == Download =
|
| transferDirection t == Download =
|
||||||
(not <$> inAnnex key) <&&> wantGet True (Just key) file
|
(not <$> inAnnex key) <&&> wantGet NoLiveUpdate True (Just key) file
|
||||||
| transferDirection t == Upload = case transferRemote info of
|
| transferDirection t == Upload = case transferRemote info of
|
||||||
Nothing -> return False
|
Nothing -> return False
|
||||||
Just r -> notinremote r
|
Just r -> notinremote r
|
||||||
<&&> wantGetBy True (Just key) file (Remote.uuid r)
|
<&&> wantGetBy NoLiveUpdate True (Just key) file (Remote.uuid r)
|
||||||
| otherwise = return False
|
| otherwise = return False
|
||||||
where
|
where
|
||||||
key = transferKey t
|
key = transferKey t
|
||||||
|
|
|
@ -77,7 +77,7 @@ expireUnused duration = do
|
||||||
debug ["removing old unused key", serializeKey k]
|
debug ["removing old unused key", serializeKey k]
|
||||||
liftAnnex $ tryNonAsync $ do
|
liftAnnex $ tryNonAsync $ do
|
||||||
lockContentForRemoval k noop removeAnnex
|
lockContentForRemoval k noop removeAnnex
|
||||||
logStatus k InfoMissing
|
logStatus NoLiveUpdate k InfoMissing
|
||||||
where
|
where
|
||||||
boundary = durationToPOSIXTime <$> duration
|
boundary = durationToPOSIXTime <$> duration
|
||||||
tooold now (_, mt) = case boundary of
|
tooold now (_, mt) = case boundary of
|
||||||
|
|
|
@ -101,7 +101,7 @@ startDistributionDownload d = go =<< liftIO . newVersionLocation d =<< liftIO ol
|
||||||
cleanup = liftAnnex $ do
|
cleanup = liftAnnex $ do
|
||||||
lockContentForRemoval k noop removeAnnex
|
lockContentForRemoval k noop removeAnnex
|
||||||
setUrlMissing k u
|
setUrlMissing k u
|
||||||
logStatus k InfoMissing
|
logStatus NoLiveUpdate k InfoMissing
|
||||||
|
|
||||||
{- Called once the download is done.
|
{- Called once the download is done.
|
||||||
- Passed an action that can be used to clean up the downloaded file.
|
- Passed an action that can be used to clean up the downloaded file.
|
||||||
|
|
|
@ -21,6 +21,7 @@ import CmdLine.AnnexSetter as ReExported
|
||||||
import CmdLine.GitAnnex.Options as ReExported
|
import CmdLine.GitAnnex.Options as ReExported
|
||||||
import CmdLine.Batch as ReExported
|
import CmdLine.Batch as ReExported
|
||||||
import Options.Applicative as ReExported hiding (command)
|
import Options.Applicative as ReExported hiding (command)
|
||||||
|
import Annex.RepoSize.LiveUpdate as ReExported
|
||||||
import qualified Git
|
import qualified Git
|
||||||
import Annex.Init
|
import Annex.Init
|
||||||
import Annex.Startup
|
import Annex.Startup
|
||||||
|
|
|
@ -95,7 +95,7 @@ seek' o = do
|
||||||
annexdotfiles <- getGitConfigVal annexDotFiles
|
annexdotfiles <- getGitConfigVal annexDotFiles
|
||||||
let gofile includingsmall (si, file) = case largeFilesOverride o of
|
let gofile includingsmall (si, file) = case largeFilesOverride o of
|
||||||
Nothing -> ifM (pure (annexdotfiles || not (dotfile file))
|
Nothing -> ifM (pure (annexdotfiles || not (dotfile file))
|
||||||
<&&> (checkFileMatcher largematcher file
|
<&&> (checkFileMatcher NoLiveUpdate largematcher file
|
||||||
<||> Annex.getRead Annex.force))
|
<||> Annex.getRead Annex.force))
|
||||||
( start dr si file addunlockedmatcher
|
( start dr si file addunlockedmatcher
|
||||||
, if includingsmall
|
, if includingsmall
|
||||||
|
@ -267,5 +267,5 @@ cleanup :: Key -> Bool -> CommandCleanup
|
||||||
cleanup key hascontent = do
|
cleanup key hascontent = do
|
||||||
maybeShowJSON $ JSONChunk [("key", serializeKey key)]
|
maybeShowJSON $ JSONChunk [("key", serializeKey key)]
|
||||||
when hascontent $
|
when hascontent $
|
||||||
logStatus key InfoPresent
|
logStatus NoLiveUpdate key InfoPresent
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -32,7 +32,7 @@ start = startUnused go (other "bad") (other "tmp")
|
||||||
(ActionItemTreeFile file)
|
(ActionItemTreeFile file)
|
||||||
(SeekInput [show n]) $
|
(SeekInput [show n]) $
|
||||||
next $ do
|
next $ do
|
||||||
logStatus key InfoPresent
|
logStatus NoLiveUpdate key InfoPresent
|
||||||
addSymlink file key Nothing
|
addSymlink file key Nothing
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
@ -323,7 +323,7 @@ addUrlChecked o url file u checkexistssize key =
|
||||||
Just (exists, samesize, url')
|
Just (exists, samesize, url')
|
||||||
| exists && (samesize || relaxedOption (downloadOptions o)) -> do
|
| exists && (samesize || relaxedOption (downloadOptions o)) -> do
|
||||||
setUrlPresent key url'
|
setUrlPresent key url'
|
||||||
logChange key u InfoPresent
|
logChange NoLiveUpdate key u InfoPresent
|
||||||
next $ return True
|
next $ return True
|
||||||
| otherwise -> do
|
| otherwise -> do
|
||||||
warning $ UnquotedString $ "while adding a new url to an already annexed file, " ++ if exists
|
warning $ UnquotedString $ "while adding a new url to an already annexed file, " ++ if exists
|
||||||
|
@ -511,7 +511,7 @@ addWorkTree _ addunlockedmatcher u url file key mtmp = case mtmp of
|
||||||
createWorkTreeDirectory (P.takeDirectory file)
|
createWorkTreeDirectory (P.takeDirectory file)
|
||||||
liftIO $ moveFile tmp file
|
liftIO $ moveFile tmp file
|
||||||
largematcher <- largeFilesMatcher
|
largematcher <- largeFilesMatcher
|
||||||
large <- checkFileMatcher largematcher file
|
large <- checkFileMatcher NoLiveUpdate largematcher file
|
||||||
if large
|
if large
|
||||||
then do
|
then do
|
||||||
-- Move back to tmp because addAnnexedFile
|
-- Move back to tmp because addAnnexedFile
|
||||||
|
@ -525,11 +525,11 @@ addWorkTree _ addunlockedmatcher u url file key mtmp = case mtmp of
|
||||||
go = do
|
go = do
|
||||||
maybeShowJSON $ JSONChunk [("key", serializeKey key)]
|
maybeShowJSON $ JSONChunk [("key", serializeKey key)]
|
||||||
setUrlPresent key url
|
setUrlPresent key url
|
||||||
logChange key u InfoPresent
|
logChange NoLiveUpdate key u InfoPresent
|
||||||
ifM (addAnnexedFile addunlockedmatcher file key mtmp)
|
ifM (addAnnexedFile addunlockedmatcher file key mtmp)
|
||||||
( do
|
( do
|
||||||
when (isJust mtmp) $
|
when (isJust mtmp) $
|
||||||
logStatus key InfoPresent
|
logStatus NoLiveUpdate key InfoPresent
|
||||||
, maybe noop (\tmp -> pruneTmpWorkDirBefore tmp (liftIO . removeWhenExistsWith R.removeLink)) mtmp
|
, maybe noop (\tmp -> pruneTmpWorkDirBefore tmp (liftIO . removeWhenExistsWith R.removeLink)) mtmp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -83,15 +83,17 @@ start o from si file key = start' o from key afile ai si
|
||||||
ai = mkActionItem (key, afile)
|
ai = mkActionItem (key, afile)
|
||||||
|
|
||||||
start' :: DropOptions -> Maybe Remote -> Key -> AssociatedFile -> ActionItem -> SeekInput -> CommandStart
|
start' :: DropOptions -> Maybe Remote -> Key -> AssociatedFile -> ActionItem -> SeekInput -> CommandStart
|
||||||
start' o from key afile ai si =
|
start' o from key afile ai si = do
|
||||||
checkDropAuto (autoMode o) from afile key $ \numcopies mincopies ->
|
checkDropAuto (autoMode o) from afile key $ \numcopies mincopies -> do
|
||||||
stopUnless wantdrop $
|
lu <- prepareLiveUpdate remoteuuid key RemovingKey
|
||||||
|
stopUnless (wantdrop lu) $
|
||||||
case from of
|
case from of
|
||||||
Nothing -> startLocal pcc afile ai si numcopies mincopies key [] ud
|
Nothing -> startLocal lu pcc afile ai si numcopies mincopies key [] ud
|
||||||
Just remote -> startRemote pcc afile ai si numcopies mincopies key ud remote
|
Just remote -> startRemote lu pcc afile ai si numcopies mincopies key ud remote
|
||||||
where
|
where
|
||||||
wantdrop
|
remoteuuid = Remote.uuid <$> from
|
||||||
| autoMode o = wantDrop False (Remote.uuid <$> from) (Just key) afile Nothing
|
wantdrop lu
|
||||||
|
| autoMode o = wantDrop lu False remoteuuid (Just key) afile Nothing
|
||||||
| otherwise = return True
|
| otherwise = return True
|
||||||
pcc = PreferredContentChecked (autoMode o)
|
pcc = PreferredContentChecked (autoMode o)
|
||||||
ud = case (batchOption o, keyOptions o) of
|
ud = case (batchOption o, keyOptions o) of
|
||||||
|
@ -101,22 +103,22 @@ start' o from key afile ai si =
|
||||||
startKeys :: DropOptions -> Maybe Remote -> (SeekInput, Key, ActionItem) -> CommandStart
|
startKeys :: DropOptions -> Maybe Remote -> (SeekInput, Key, ActionItem) -> CommandStart
|
||||||
startKeys o from (si, key, ai) = start' o from key (AssociatedFile Nothing) ai si
|
startKeys o from (si, key, ai) = start' o from key (AssociatedFile Nothing) ai si
|
||||||
|
|
||||||
startLocal :: PreferredContentChecked -> AssociatedFile -> ActionItem -> SeekInput -> NumCopies -> MinCopies -> Key -> [VerifiedCopy] -> DroppingUnused -> CommandStart
|
startLocal :: LiveUpdate -> PreferredContentChecked -> AssociatedFile -> ActionItem -> SeekInput -> NumCopies -> MinCopies -> Key -> [VerifiedCopy] -> DroppingUnused -> CommandStart
|
||||||
startLocal pcc afile ai si numcopies mincopies key preverified ud =
|
startLocal lu pcc afile ai si numcopies mincopies key preverified ud =
|
||||||
starting "drop" (OnlyActionOn key ai) si $
|
starting "drop" (OnlyActionOn key ai) si $
|
||||||
performLocal pcc key afile numcopies mincopies preverified ud
|
performLocal lu pcc key afile numcopies mincopies preverified ud
|
||||||
|
|
||||||
startRemote :: PreferredContentChecked -> AssociatedFile -> ActionItem -> SeekInput -> NumCopies -> MinCopies -> Key -> DroppingUnused -> Remote -> CommandStart
|
startRemote :: LiveUpdate -> PreferredContentChecked -> AssociatedFile -> ActionItem -> SeekInput -> NumCopies -> MinCopies -> Key -> DroppingUnused -> Remote -> CommandStart
|
||||||
startRemote pcc afile ai si numcopies mincopies key ud remote =
|
startRemote lu pcc afile ai si numcopies mincopies key ud remote =
|
||||||
starting "drop" (OnlyActionOn key ai) si $ do
|
starting "drop" (OnlyActionOn key ai) si $ do
|
||||||
showAction $ UnquotedString $ "from " ++ Remote.name remote
|
showAction $ UnquotedString $ "from " ++ Remote.name remote
|
||||||
performRemote pcc key afile numcopies mincopies remote ud
|
performRemote lu pcc key afile numcopies mincopies remote ud
|
||||||
|
|
||||||
performLocal :: PreferredContentChecked -> Key -> AssociatedFile -> NumCopies -> MinCopies -> [VerifiedCopy] -> DroppingUnused -> CommandPerform
|
performLocal :: LiveUpdate -> PreferredContentChecked -> Key -> AssociatedFile -> NumCopies -> MinCopies -> [VerifiedCopy] -> DroppingUnused -> CommandPerform
|
||||||
performLocal pcc key afile numcopies mincopies preverified ud = lockContentForRemoval key fallback $ \contentlock -> do
|
performLocal lu pcc key afile numcopies mincopies preverified ud = lockContentForRemoval key fallback $ \contentlock -> do
|
||||||
u <- getUUID
|
u <- getUUID
|
||||||
(tocheck, verified) <- verifiableCopies key [u]
|
(tocheck, verified) <- verifiableCopies key [u]
|
||||||
doDrop pcc u (Just contentlock) key afile numcopies mincopies [] (preverified ++ verified) tocheck
|
doDrop lu pcc u (Just contentlock) key afile numcopies mincopies [] (preverified ++ verified) tocheck
|
||||||
( \proof -> do
|
( \proof -> do
|
||||||
fastDebug "Command.Drop" $ unwords
|
fastDebug "Command.Drop" $ unwords
|
||||||
[ "Dropping from here"
|
[ "Dropping from here"
|
||||||
|
@ -125,7 +127,7 @@ performLocal pcc key afile numcopies mincopies preverified ud = lockContentForRe
|
||||||
]
|
]
|
||||||
removeAnnex contentlock
|
removeAnnex contentlock
|
||||||
notifyDrop afile True
|
notifyDrop afile True
|
||||||
next $ cleanupLocal key ud
|
next $ cleanupLocal lu key ud
|
||||||
, do
|
, do
|
||||||
notifyDrop afile False
|
notifyDrop afile False
|
||||||
stop
|
stop
|
||||||
|
@ -136,14 +138,14 @@ performLocal pcc key afile numcopies mincopies preverified ud = lockContentForRe
|
||||||
-- is present, but due to buffering, may find it present for the
|
-- is present, but due to buffering, may find it present for the
|
||||||
-- second file before the first is dropped. If so, nothing remains
|
-- second file before the first is dropped. If so, nothing remains
|
||||||
-- to be done except for cleaning up.
|
-- to be done except for cleaning up.
|
||||||
fallback = next $ cleanupLocal key ud
|
fallback = next $ cleanupLocal lu key ud
|
||||||
|
|
||||||
performRemote :: PreferredContentChecked -> Key -> AssociatedFile -> NumCopies -> MinCopies -> Remote -> DroppingUnused -> CommandPerform
|
performRemote :: LiveUpdate -> PreferredContentChecked -> Key -> AssociatedFile -> NumCopies -> MinCopies -> Remote -> DroppingUnused -> CommandPerform
|
||||||
performRemote pcc key afile numcopies mincopies remote ud = do
|
performRemote lu pcc key afile numcopies mincopies remote ud = do
|
||||||
-- Filter the uuid it's being dropped from out of the lists of
|
-- Filter the uuid it's being dropped from out of the lists of
|
||||||
-- places assumed to have the key, and places to check.
|
-- places assumed to have the key, and places to check.
|
||||||
(tocheck, verified) <- verifiableCopies key [uuid]
|
(tocheck, verified) <- verifiableCopies key [uuid]
|
||||||
doDrop pcc uuid Nothing key afile numcopies mincopies [uuid] verified tocheck
|
doDrop lu pcc uuid Nothing key afile numcopies mincopies [uuid] verified tocheck
|
||||||
( \proof -> do
|
( \proof -> do
|
||||||
fastDebug "Command.Drop" $ unwords
|
fastDebug "Command.Drop" $ unwords
|
||||||
[ "Dropping from remote"
|
[ "Dropping from remote"
|
||||||
|
@ -152,21 +154,21 @@ performRemote pcc key afile numcopies mincopies remote ud = do
|
||||||
, show proof
|
, show proof
|
||||||
]
|
]
|
||||||
ok <- Remote.action (Remote.removeKey remote proof key)
|
ok <- Remote.action (Remote.removeKey remote proof key)
|
||||||
next $ cleanupRemote key remote ud ok
|
next $ cleanupRemote lu key remote ud ok
|
||||||
, stop
|
, stop
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
uuid = Remote.uuid remote
|
uuid = Remote.uuid remote
|
||||||
|
|
||||||
cleanupLocal :: Key -> DroppingUnused -> CommandCleanup
|
cleanupLocal :: LiveUpdate -> Key -> DroppingUnused -> CommandCleanup
|
||||||
cleanupLocal key ud = do
|
cleanupLocal lu key ud = do
|
||||||
logStatus key (dropStatus ud)
|
logStatus lu key (dropStatus ud)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
cleanupRemote :: Key -> Remote -> DroppingUnused -> Bool -> CommandCleanup
|
cleanupRemote :: LiveUpdate -> Key -> Remote -> DroppingUnused -> Bool -> CommandCleanup
|
||||||
cleanupRemote key remote ud ok = do
|
cleanupRemote lu key remote ud ok = do
|
||||||
when ok $
|
when ok $
|
||||||
Remote.logStatus remote key (dropStatus ud)
|
Remote.logStatus lu remote key (dropStatus ud)
|
||||||
return ok
|
return ok
|
||||||
|
|
||||||
{- Set when the user explicitly chose to operate on unused content.
|
{- Set when the user explicitly chose to operate on unused content.
|
||||||
|
@ -189,7 +191,8 @@ dropStatus (DroppingUnused True) = InfoDead
|
||||||
- --force overrides and always allows dropping.
|
- --force overrides and always allows dropping.
|
||||||
-}
|
-}
|
||||||
doDrop
|
doDrop
|
||||||
:: PreferredContentChecked
|
:: LiveUpdate
|
||||||
|
-> PreferredContentChecked
|
||||||
-> UUID
|
-> UUID
|
||||||
-> Maybe ContentRemovalLock
|
-> Maybe ContentRemovalLock
|
||||||
-> Key
|
-> Key
|
||||||
|
@ -201,10 +204,10 @@ doDrop
|
||||||
-> [UnVerifiedCopy]
|
-> [UnVerifiedCopy]
|
||||||
-> (Maybe SafeDropProof -> CommandPerform, CommandPerform)
|
-> (Maybe SafeDropProof -> CommandPerform, CommandPerform)
|
||||||
-> CommandPerform
|
-> CommandPerform
|
||||||
doDrop pcc dropfrom contentlock key afile numcopies mincopies skip preverified check (dropaction, nodropaction) =
|
doDrop lu pcc dropfrom contentlock key afile numcopies mincopies skip preverified check (dropaction, nodropaction) =
|
||||||
ifM (Annex.getRead Annex.force)
|
ifM (Annex.getRead Annex.force)
|
||||||
( dropaction Nothing
|
( dropaction Nothing
|
||||||
, ifM (checkRequiredContent pcc dropfrom key afile)
|
, ifM (checkRequiredContent lu pcc dropfrom key afile)
|
||||||
( verifyEnoughCopiesToDrop nolocmsg key (Just dropfrom)
|
( verifyEnoughCopiesToDrop nolocmsg key (Just dropfrom)
|
||||||
contentlock numcopies mincopies
|
contentlock numcopies mincopies
|
||||||
skip preverified check
|
skip preverified check
|
||||||
|
@ -225,10 +228,10 @@ doDrop pcc dropfrom contentlock key afile numcopies mincopies skip preverified c
|
||||||
- providing this avoids that extra work. -}
|
- providing this avoids that extra work. -}
|
||||||
newtype PreferredContentChecked = PreferredContentChecked Bool
|
newtype PreferredContentChecked = PreferredContentChecked Bool
|
||||||
|
|
||||||
checkRequiredContent :: PreferredContentChecked -> UUID -> Key -> AssociatedFile -> Annex Bool
|
checkRequiredContent :: LiveUpdate -> PreferredContentChecked -> UUID -> Key -> AssociatedFile -> Annex Bool
|
||||||
checkRequiredContent (PreferredContentChecked True) _ _ _ = return True
|
checkRequiredContent _ (PreferredContentChecked True) _ _ _ = return True
|
||||||
checkRequiredContent (PreferredContentChecked False) u k afile =
|
checkRequiredContent lu (PreferredContentChecked False) u k afile =
|
||||||
checkDrop isRequiredContent False (Just u) (Just k) afile Nothing >>= \case
|
checkDrop isRequiredContent lu False (Just u) (Just k) afile Nothing >>= \case
|
||||||
Nothing -> return True
|
Nothing -> return True
|
||||||
Just afile' -> do
|
Just afile' -> do
|
||||||
if afile == afile'
|
if afile == afile'
|
||||||
|
|
|
@ -55,5 +55,5 @@ perform key = ifM (inAnnex key)
|
||||||
|
|
||||||
cleanup :: Key -> CommandCleanup
|
cleanup :: Key -> CommandCleanup
|
||||||
cleanup key = do
|
cleanup key = do
|
||||||
logStatus key InfoMissing
|
logStatus NoLiveUpdate key InfoMissing
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -57,7 +57,8 @@ perform :: Maybe Remote -> NumCopies -> MinCopies -> Key -> CommandPerform
|
||||||
perform from numcopies mincopies key = case from of
|
perform from numcopies mincopies key = case from of
|
||||||
Just r -> do
|
Just r -> do
|
||||||
showAction $ UnquotedString $ "from " ++ Remote.name r
|
showAction $ UnquotedString $ "from " ++ Remote.name r
|
||||||
Command.Drop.performRemote pcc key (AssociatedFile Nothing) numcopies mincopies r ud
|
Command.Drop.performRemote NoLiveUpdate pcc key
|
||||||
|
(AssociatedFile Nothing) numcopies mincopies r ud
|
||||||
Nothing -> ifM (inAnnex key)
|
Nothing -> ifM (inAnnex key)
|
||||||
( droplocal
|
( droplocal
|
||||||
, ifM (objectFileExists key)
|
, ifM (objectFileExists key)
|
||||||
|
@ -71,7 +72,8 @@ perform from numcopies mincopies key = case from of
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
droplocal = Command.Drop.performLocal pcc key (AssociatedFile Nothing) numcopies mincopies [] ud
|
droplocal = Command.Drop.performLocal NoLiveUpdate pcc
|
||||||
|
key (AssociatedFile Nothing) numcopies mincopies [] ud
|
||||||
pcc = Command.Drop.PreferredContentChecked False
|
pcc = Command.Drop.PreferredContentChecked False
|
||||||
ud = Command.Drop.DroppingUnused True
|
ud = Command.Drop.DroppingUnused True
|
||||||
|
|
||||||
|
|
|
@ -334,12 +334,12 @@ verifyLocationLog key keystatus ai = do
|
||||||
whenM (annexSecureHashesOnly <$> Annex.getGitConfig) $
|
whenM (annexSecureHashesOnly <$> Annex.getGitConfig) $
|
||||||
warning $ "** Despite annex.securehashesonly being set, " <> QuotedPath obj <> " has content present in the annex using an insecure " <> UnquotedString (decodeBS (formatKeyVariety (fromKey keyVariety key))) <> " key"
|
warning $ "** Despite annex.securehashesonly being set, " <> QuotedPath obj <> " has content present in the annex using an insecure " <> UnquotedString (decodeBS (formatKeyVariety (fromKey keyVariety key))) <> " key"
|
||||||
|
|
||||||
verifyLocationLog' key ai present u (logChange key u)
|
verifyLocationLog' key ai present u (logChange NoLiveUpdate key u)
|
||||||
|
|
||||||
verifyLocationLogRemote :: Key -> ActionItem -> Remote -> Bool -> Annex Bool
|
verifyLocationLogRemote :: Key -> ActionItem -> Remote -> Bool -> Annex Bool
|
||||||
verifyLocationLogRemote key ai remote present =
|
verifyLocationLogRemote key ai remote present =
|
||||||
verifyLocationLog' key ai present (Remote.uuid remote)
|
verifyLocationLog' key ai present (Remote.uuid remote)
|
||||||
(Remote.logStatus remote key)
|
(Remote.logStatus NoLiveUpdate remote key)
|
||||||
|
|
||||||
verifyLocationLog' :: Key -> ActionItem -> Bool -> UUID -> (LogStatus -> Annex ()) -> Annex Bool
|
verifyLocationLog' :: Key -> ActionItem -> Bool -> UUID -> (LogStatus -> Annex ()) -> Annex Bool
|
||||||
verifyLocationLog' key ai present u updatestatus = do
|
verifyLocationLog' key ai present u updatestatus = do
|
||||||
|
@ -385,7 +385,7 @@ verifyRequiredContent key ai@(ActionItemAssociatedFile afile _) = case afile of
|
||||||
go requiredlocs = do
|
go requiredlocs = do
|
||||||
presentlocs <- S.fromList <$> loggedLocations key
|
presentlocs <- S.fromList <$> loggedLocations key
|
||||||
missinglocs <- filterM
|
missinglocs <- filterM
|
||||||
(\u -> isRequiredContent (Just u) S.empty (Just key) afile False)
|
(\u -> isRequiredContent NoLiveUpdate (Just u) S.empty (Just key) afile False)
|
||||||
(S.toList $ S.difference requiredlocs presentlocs)
|
(S.toList $ S.difference requiredlocs presentlocs)
|
||||||
if null missinglocs
|
if null missinglocs
|
||||||
then return True
|
then return True
|
||||||
|
@ -641,7 +641,7 @@ badContentRemote remote localcopy key = do
|
||||||
|
|
||||||
dropped <- tryNonAsync (Remote.removeKey remote Nothing key)
|
dropped <- tryNonAsync (Remote.removeKey remote Nothing key)
|
||||||
when (isRight dropped) $
|
when (isRight dropped) $
|
||||||
Remote.logStatus remote key InfoMissing
|
Remote.logStatus NoLiveUpdate remote key InfoMissing
|
||||||
return $ case (movedbad, dropped) of
|
return $ case (movedbad, dropped) of
|
||||||
(True, Right ()) -> "moved from " ++ Remote.name remote ++
|
(True, Right ()) -> "moved from " ++ Remote.name remote ++
|
||||||
" to " ++ fromRawFilePath destbad
|
" to " ++ fromRawFilePath destbad
|
||||||
|
|
|
@ -51,7 +51,6 @@ import qualified Limit
|
||||||
import Messages.JSON (DualDisp(..), ObjectMap(..))
|
import Messages.JSON (DualDisp(..), ObjectMap(..))
|
||||||
import Annex.BloomFilter
|
import Annex.BloomFilter
|
||||||
import Annex.RepoSize
|
import Annex.RepoSize
|
||||||
import Types.RepoSize
|
|
||||||
import qualified Command.Unused
|
import qualified Command.Unused
|
||||||
import qualified Utility.RawFilePath as R
|
import qualified Utility.RawFilePath as R
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ perform file key = do
|
||||||
)
|
)
|
||||||
Nothing -> lostcontent
|
Nothing -> lostcontent
|
||||||
|
|
||||||
lostcontent = logStatus key InfoMissing
|
lostcontent = logStatus NoLiveUpdate key InfoMissing
|
||||||
|
|
||||||
errorModified :: a
|
errorModified :: a
|
||||||
errorModified = giveup "Locking this file would discard any changes you have made to it. Use 'git annex add' to stage your changes. (Or, use --force to override)"
|
errorModified = giveup "Locking this file would discard any changes you have made to it. Use 'git annex add' to stage your changes. (Or, use --force to override)"
|
||||||
|
|
|
@ -90,7 +90,7 @@ seek o = do
|
||||||
, liftIO exitFailure
|
, liftIO exitFailure
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
checkmatcher matcher = checkMatcher' matcher (matchinfo o) S.empty
|
checkmatcher matcher = checkMatcher' matcher (matchinfo o) NoLiveUpdate S.empty
|
||||||
|
|
||||||
bail :: String -> IO a
|
bail :: String -> IO a
|
||||||
bail s = do
|
bail s = do
|
||||||
|
|
|
@ -174,7 +174,7 @@ update oldkey newkey =
|
||||||
starting "migrate" ai (SeekInput []) $
|
starting "migrate" ai (SeekInput []) $
|
||||||
ifM (Command.ReKey.linkKey' v oldkey newkey)
|
ifM (Command.ReKey.linkKey' v oldkey newkey)
|
||||||
( do
|
( do
|
||||||
logStatus newkey InfoPresent
|
logStatus NoLiveUpdate newkey InfoPresent
|
||||||
next $ return True
|
next $ return True
|
||||||
, next $ return False
|
, next $ return False
|
||||||
)
|
)
|
||||||
|
|
|
@ -213,7 +213,7 @@ storeReceived f = do
|
||||||
Nothing -> do
|
Nothing -> do
|
||||||
warning $ "Received a file " <> QuotedPath (toRawFilePath f) <> " that is not a git-annex key. Deleting this file."
|
warning $ "Received a file " <> QuotedPath (toRawFilePath f) <> " that is not a git-annex key. Deleting this file."
|
||||||
liftIO $ removeWhenExistsWith R.removeLink (toRawFilePath f)
|
liftIO $ removeWhenExistsWith R.removeLink (toRawFilePath f)
|
||||||
Just k -> void $ logStatusAfter k $
|
Just k -> void $ logStatusAfter NoLiveUpdate k $
|
||||||
getViaTmpFromDisk RetrievalVerifiableKeysSecure AlwaysVerify k (AssociatedFile Nothing) $ \dest -> unVerified $
|
getViaTmpFromDisk RetrievalVerifiableKeysSecure AlwaysVerify k (AssociatedFile Nothing) $ \dest -> unVerified $
|
||||||
liftIO $ catchBoolIO $ do
|
liftIO $ catchBoolIO $ do
|
||||||
R.rename (toRawFilePath f) dest
|
R.rename (toRawFilePath f) dest
|
||||||
|
|
|
@ -149,6 +149,6 @@ cleanup file newkey a = do
|
||||||
return (MigrationRecord sha)
|
return (MigrationRecord sha)
|
||||||
)
|
)
|
||||||
whenM (inAnnex newkey) $
|
whenM (inAnnex newkey) $
|
||||||
logStatus newkey InfoPresent
|
logStatus NoLiveUpdate newkey InfoPresent
|
||||||
a newkeyrec
|
a newkeyrec
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -30,7 +30,7 @@ start (_, key) = fieldTransfer Download key $ \_p -> do
|
||||||
let rsp = RetrievalAllKeysSecure
|
let rsp = RetrievalAllKeysSecure
|
||||||
ifM (getViaTmp rsp DefaultVerify key (AssociatedFile Nothing) Nothing go)
|
ifM (getViaTmp rsp DefaultVerify key (AssociatedFile Nothing) Nothing go)
|
||||||
( do
|
( do
|
||||||
logStatus key InfoPresent
|
logStatus NoLiveUpdate key InfoPresent
|
||||||
_ <- quiesce True
|
_ <- quiesce True
|
||||||
return True
|
return True
|
||||||
, return False
|
, return False
|
||||||
|
|
|
@ -86,5 +86,5 @@ registerUrl remote key url = do
|
||||||
-- does not have an OtherDownloader, but this command needs to do
|
-- does not have an OtherDownloader, but this command needs to do
|
||||||
-- it for urls claimed by other remotes as well.
|
-- it for urls claimed by other remotes as well.
|
||||||
case snd (getDownloader url) of
|
case snd (getDownloader url) of
|
||||||
OtherDownloader -> logChange key (Remote.uuid remote) InfoPresent
|
OtherDownloader -> logChange NoLiveUpdate key (Remote.uuid remote) InfoPresent
|
||||||
_ -> return ()
|
_ -> return ()
|
||||||
|
|
|
@ -133,5 +133,5 @@ perform src key = do
|
||||||
|
|
||||||
cleanup :: Key -> CommandCleanup
|
cleanup :: Key -> CommandCleanup
|
||||||
cleanup key = do
|
cleanup key = do
|
||||||
logStatus key InfoPresent
|
logStatus NoLiveUpdate key InfoPresent
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -48,5 +48,5 @@ perform file key = do
|
||||||
|
|
||||||
cleanup :: Key -> CommandCleanup
|
cleanup :: Key -> CommandCleanup
|
||||||
cleanup key = do
|
cleanup key = do
|
||||||
logStatus key InfoPresent
|
logStatus NoLiveUpdate key InfoPresent
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -54,5 +54,5 @@ start si (KeyStatus k u s) = starting "setpresentkey" ai si $ perform k u s
|
||||||
|
|
||||||
perform :: Key -> UUID -> LogStatus -> CommandPerform
|
perform :: Key -> UUID -> LogStatus -> CommandPerform
|
||||||
perform k u s = next $ do
|
perform k u s = next $ do
|
||||||
logChange k u s
|
logChange NoLiveUpdate k u s
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -191,7 +191,7 @@ clean' file mk passthrough discardreststdin emitpointer =
|
||||||
=<< lockDown cfg (fromRawFilePath file)
|
=<< lockDown cfg (fromRawFilePath file)
|
||||||
|
|
||||||
postingest (Just k, _) = do
|
postingest (Just k, _) = do
|
||||||
logStatus k InfoPresent
|
logStatus NoLiveUpdate k InfoPresent
|
||||||
return k
|
return k
|
||||||
postingest _ = giveup "could not add file to the annex"
|
postingest _ = giveup "could not add file to the annex"
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ shouldAnnex file indexmeta moldkey = do
|
||||||
where
|
where
|
||||||
go = do
|
go = do
|
||||||
matcher <- largeFilesMatcher
|
matcher <- largeFilesMatcher
|
||||||
checkFileMatcher' matcher file d
|
checkFileMatcher' NoLiveUpdate matcher file d
|
||||||
|
|
||||||
checkwasannexed = pure $ isJust moldkey
|
checkwasannexed = pure $ isJust moldkey
|
||||||
|
|
||||||
|
|
|
@ -298,7 +298,7 @@ test runannex mkr mkk =
|
||||||
Just verifier -> do
|
Just verifier -> do
|
||||||
loc <- Annex.calcRepo (gitAnnexLocation k)
|
loc <- Annex.calcRepo (gitAnnexLocation k)
|
||||||
verifier k loc
|
verifier k loc
|
||||||
get r k = logStatusAfter k $ getViaTmp (Remote.retrievalSecurityPolicy r) (RemoteVerify r) k (AssociatedFile Nothing) Nothing $ \dest ->
|
get r k = logStatusAfter NoLiveUpdate k $ getViaTmp (Remote.retrievalSecurityPolicy r) (RemoteVerify r) k (AssociatedFile Nothing) Nothing $ \dest ->
|
||||||
tryNonAsync (Remote.retrieveKeyFile r k (AssociatedFile Nothing) (fromRawFilePath dest) nullMeterUpdate (RemoteVerify r)) >>= \case
|
tryNonAsync (Remote.retrieveKeyFile r k (AssociatedFile Nothing) (fromRawFilePath dest) nullMeterUpdate (RemoteVerify r)) >>= \case
|
||||||
Right v -> return (True, v)
|
Right v -> return (True, v)
|
||||||
Left _ -> return (False, UnVerified)
|
Left _ -> return (False, UnVerified)
|
||||||
|
@ -372,13 +372,13 @@ testUnavailable runannex mkr mkk =
|
||||||
, check (`notElem` [Right True, Right False]) "checkPresent" $ \r k ->
|
, check (`notElem` [Right True, Right False]) "checkPresent" $ \r k ->
|
||||||
Remote.checkPresent r k
|
Remote.checkPresent r k
|
||||||
, check (== Right False) "retrieveKeyFile" $ \r k ->
|
, check (== Right False) "retrieveKeyFile" $ \r k ->
|
||||||
logStatusAfter k $ getViaTmp (Remote.retrievalSecurityPolicy r) (RemoteVerify r) k (AssociatedFile Nothing) Nothing $ \dest ->
|
logStatusAfter NoLiveUpdate k $ getViaTmp (Remote.retrievalSecurityPolicy r) (RemoteVerify r) k (AssociatedFile Nothing) Nothing $ \dest ->
|
||||||
tryNonAsync (Remote.retrieveKeyFile r k (AssociatedFile Nothing) (fromRawFilePath dest) nullMeterUpdate (RemoteVerify r)) >>= \case
|
tryNonAsync (Remote.retrieveKeyFile r k (AssociatedFile Nothing) (fromRawFilePath dest) nullMeterUpdate (RemoteVerify r)) >>= \case
|
||||||
Right v -> return (True, v)
|
Right v -> return (True, v)
|
||||||
Left _ -> return (False, UnVerified)
|
Left _ -> return (False, UnVerified)
|
||||||
, check (== Right False) "retrieveKeyFileCheap" $ \r k -> case Remote.retrieveKeyFileCheap r of
|
, check (== Right False) "retrieveKeyFileCheap" $ \r k -> case Remote.retrieveKeyFileCheap r of
|
||||||
Nothing -> return False
|
Nothing -> return False
|
||||||
Just a -> logStatusAfter k $ getViaTmp (Remote.retrievalSecurityPolicy r) (RemoteVerify r) k (AssociatedFile Nothing) Nothing $ \dest ->
|
Just a -> logStatusAfter NoLiveUpdate k $ getViaTmp (Remote.retrievalSecurityPolicy r) (RemoteVerify r) k (AssociatedFile Nothing) Nothing $ \dest ->
|
||||||
unVerified $ isRight
|
unVerified $ isRight
|
||||||
<$> tryNonAsync (a k (AssociatedFile Nothing) (fromRawFilePath dest))
|
<$> tryNonAsync (a k (AssociatedFile Nothing) (fromRawFilePath dest))
|
||||||
]
|
]
|
||||||
|
|
|
@ -54,7 +54,7 @@ toPerform key af remote = go Upload af $
|
||||||
upload' (uuid remote) key af Nothing stdRetry $ \p -> do
|
upload' (uuid remote) key af Nothing stdRetry $ \p -> do
|
||||||
tryNonAsync (Remote.storeKey remote key af Nothing p) >>= \case
|
tryNonAsync (Remote.storeKey remote key af Nothing p) >>= \case
|
||||||
Right () -> do
|
Right () -> do
|
||||||
Remote.logStatus remote key InfoPresent
|
Remote.logStatus NoLiveUpdate remote key InfoPresent
|
||||||
return True
|
return True
|
||||||
Left e -> do
|
Left e -> do
|
||||||
warning (UnquotedString (show e))
|
warning (UnquotedString (show e))
|
||||||
|
@ -63,7 +63,7 @@ toPerform key af remote = go Upload af $
|
||||||
fromPerform :: Key -> AssociatedFile -> Remote -> CommandPerform
|
fromPerform :: Key -> AssociatedFile -> Remote -> CommandPerform
|
||||||
fromPerform key af remote = go Upload af $
|
fromPerform key af remote = go Upload af $
|
||||||
download' (uuid remote) key af Nothing stdRetry $ \p ->
|
download' (uuid remote) key af Nothing stdRetry $ \p ->
|
||||||
logStatusAfter key $ getViaTmp (retrievalSecurityPolicy remote) vc key af Nothing $ \t ->
|
logStatusAfter NoLiveUpdate key $ getViaTmp (retrievalSecurityPolicy remote) vc key af Nothing $ \t ->
|
||||||
tryNonAsync (Remote.retrieveKeyFile remote key af (fromRawFilePath t) p vc) >>= \case
|
tryNonAsync (Remote.retrieveKeyFile remote key af (fromRawFilePath t) p vc) >>= \case
|
||||||
Right v -> return (True, v)
|
Right v -> return (True, v)
|
||||||
Left e -> do
|
Left e -> do
|
||||||
|
|
|
@ -46,11 +46,11 @@ start = do
|
||||||
warning (UnquotedString (show e))
|
warning (UnquotedString (show e))
|
||||||
return False
|
return False
|
||||||
Right () -> do
|
Right () -> do
|
||||||
Remote.logStatus remote key InfoPresent
|
Remote.logStatus NoLiveUpdate remote key InfoPresent
|
||||||
return True
|
return True
|
||||||
| otherwise = notifyTransfer direction af $
|
| otherwise = notifyTransfer direction af $
|
||||||
download' (Remote.uuid remote) key af Nothing stdRetry $ \p ->
|
download' (Remote.uuid remote) key af Nothing stdRetry $ \p ->
|
||||||
logStatusAfter key $ getViaTmp (Remote.retrievalSecurityPolicy remote) (RemoteVerify remote) key af Nothing $ \t -> do
|
logStatusAfter NoLiveUpdate key $ getViaTmp (Remote.retrievalSecurityPolicy remote) (RemoteVerify remote) key af Nothing $ \t -> do
|
||||||
r <- tryNonAsync (Remote.retrieveKeyFile remote key af (fromRawFilePath t) p (RemoteVerify remote)) >>= \case
|
r <- tryNonAsync (Remote.retrieveKeyFile remote key af (fromRawFilePath t) p (RemoteVerify remote)) >>= \case
|
||||||
Left e -> do
|
Left e -> do
|
||||||
warning (UnquotedString (show e))
|
warning (UnquotedString (show e))
|
||||||
|
|
|
@ -67,12 +67,12 @@ start = do
|
||||||
warning (UnquotedString (show e))
|
warning (UnquotedString (show e))
|
||||||
return False
|
return False
|
||||||
Right () -> do
|
Right () -> do
|
||||||
Remote.logStatus remote key InfoPresent
|
Remote.logStatus NoLiveUpdate remote key InfoPresent
|
||||||
return True
|
return True
|
||||||
runner (AssistantDownloadRequest _ key (TransferAssociatedFile file)) remote =
|
runner (AssistantDownloadRequest _ key (TransferAssociatedFile file)) remote =
|
||||||
notifyTransfer Download file $
|
notifyTransfer Download file $
|
||||||
download' (Remote.uuid remote) key file Nothing stdRetry $ \p ->
|
download' (Remote.uuid remote) key file Nothing stdRetry $ \p ->
|
||||||
logStatusAfter key $ getViaTmp (Remote.retrievalSecurityPolicy remote) (RemoteVerify remote) key file Nothing $ \t -> do
|
logStatusAfter NoLiveUpdate key $ getViaTmp (Remote.retrievalSecurityPolicy remote) (RemoteVerify remote) key file Nothing $ \t -> do
|
||||||
r <- tryNonAsync (Remote.retrieveKeyFile remote key file (fromRawFilePath t) p (RemoteVerify remote)) >>= \case
|
r <- tryNonAsync (Remote.retrieveKeyFile remote key file (fromRawFilePath t) p (RemoteVerify remote)) >>= \case
|
||||||
Left e -> do
|
Left e -> do
|
||||||
warning (UnquotedString (show e))
|
warning (UnquotedString (show e))
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
-}
|
-}
|
||||||
|
|
||||||
{-# LANGUAGE CPP #-}
|
{-# LANGUAGE CPP #-}
|
||||||
{-# LANGUAGE ScopedTypeVariables #-}
|
|
||||||
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell #-}
|
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell #-}
|
||||||
{-# LANGUAGE OverloadedStrings, GADTs, FlexibleContexts #-}
|
{-# LANGUAGE OverloadedStrings, GADTs, FlexibleContexts #-}
|
||||||
{-# LANGUAGE MultiParamTypeClasses, GeneralizedNewtypeDeriving #-}
|
{-# LANGUAGE MultiParamTypeClasses, GeneralizedNewtypeDeriving #-}
|
||||||
|
@ -21,6 +20,7 @@
|
||||||
|
|
||||||
module Database.RepoSize (
|
module Database.RepoSize (
|
||||||
RepoSizeHandle,
|
RepoSizeHandle,
|
||||||
|
getRepoSizeHandle,
|
||||||
openDb,
|
openDb,
|
||||||
closeDb,
|
closeDb,
|
||||||
getRepoSizes,
|
getRepoSizes,
|
||||||
|
@ -31,22 +31,20 @@ module Database.RepoSize (
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Annex.Common
|
import Annex.Common
|
||||||
import Annex.LockFile
|
import qualified Annex
|
||||||
import Types.RepoSize
|
import Database.RepoSize.Handle
|
||||||
import Git.Types
|
|
||||||
import qualified Database.Handle as H
|
import qualified Database.Handle as H
|
||||||
import Database.Init
|
import Database.Init
|
||||||
import Database.Utility
|
import Database.Utility
|
||||||
import Database.Types
|
import Database.Types
|
||||||
|
import Annex.LockFile
|
||||||
|
import Git.Types
|
||||||
import qualified Utility.RawFilePath as R
|
import qualified Utility.RawFilePath as R
|
||||||
|
|
||||||
import Database.Persist.Sql hiding (Key)
|
import Database.Persist.Sql hiding (Key)
|
||||||
import Database.Persist.TH
|
import Database.Persist.TH
|
||||||
import qualified System.FilePath.ByteString as P
|
import qualified System.FilePath.ByteString as P
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import qualified Data.Text as T
|
|
||||||
|
|
||||||
newtype RepoSizeHandle = RepoSizeHandle (Maybe H.DbHandle)
|
|
||||||
|
|
||||||
share [mkPersist sqlSettings, mkMigrate "migrateRepoSizes"] [persistLowerCase|
|
share [mkPersist sqlSettings, mkMigrate "migrateRepoSizes"] [persistLowerCase|
|
||||||
-- Corresponds to location log information from the git-annex branch.
|
-- Corresponds to location log information from the git-annex branch.
|
||||||
|
@ -66,6 +64,15 @@ LiveSizeChanges
|
||||||
UniqueLiveSizeChange repo key
|
UniqueLiveSizeChange repo key
|
||||||
|]
|
|]
|
||||||
|
|
||||||
|
{- Gets a handle to the database. It's cached in Annex state. -}
|
||||||
|
getRepoSizeHandle :: Annex RepoSizeHandle
|
||||||
|
getRepoSizeHandle = Annex.getState Annex.reposizehandle >>= \case
|
||||||
|
Just h -> return h
|
||||||
|
Nothing -> do
|
||||||
|
h <- openDb
|
||||||
|
Annex.changeState $ \s -> s { Annex.reposizehandle = Just h }
|
||||||
|
return h
|
||||||
|
|
||||||
{- Opens the database, creating it if it doesn't exist yet.
|
{- Opens the database, creating it if it doesn't exist yet.
|
||||||
-
|
-
|
||||||
- Multiple readers and writers can have the database open at the same
|
- Multiple readers and writers can have the database open at the same
|
||||||
|
@ -155,23 +162,24 @@ recordAnnexBranchCommit branchcommitsha = do
|
||||||
deleteWhere ([] :: [Filter AnnexBranch])
|
deleteWhere ([] :: [Filter AnnexBranch])
|
||||||
void $ insertUniqueFast $ AnnexBranch $ toSSha branchcommitsha
|
void $ insertUniqueFast $ AnnexBranch $ toSSha branchcommitsha
|
||||||
|
|
||||||
data SizeChange = AddingKey | RemovingKey
|
|
||||||
|
|
||||||
{- If there is already a size change for the same UUID and Key, it is
|
{- If there is already a size change for the same UUID and Key, it is
|
||||||
- overwritten with the new size change. -}
|
- overwritten with the new size change. -}
|
||||||
startingLiveSizeChange :: UUID -> Key -> SizeChange -> SqlPersistM ()
|
startingLiveSizeChange :: RepoSizeHandle -> UUID -> Key -> SizeChange -> IO ()
|
||||||
startingLiveSizeChange u k sc =
|
startingLiveSizeChange (RepoSizeHandle (Just h)) u k sc =
|
||||||
void $ upsertBy
|
H.commitDb h $ void $ upsertBy
|
||||||
(UniqueLiveSizeChange u k)
|
(UniqueLiveSizeChange u k)
|
||||||
(LiveSizeChanges u k sc)
|
(LiveSizeChanges u k sc)
|
||||||
[LiveSizeChangesChange =. sc]
|
[LiveSizeChangesChange =. sc]
|
||||||
|
startingLiveSizeChange (RepoSizeHandle Nothing) _ _ _ = noop
|
||||||
|
|
||||||
finishedLiveSizeChange :: UUID -> Key -> SizeChange -> SqlPersistM ()
|
finishedLiveSizeChange :: RepoSizeHandle -> UUID -> Key -> SizeChange -> IO ()
|
||||||
finishedLiveSizeChange u k sc = deleteWhere
|
finishedLiveSizeChange (RepoSizeHandle (Just h)) u k sc =
|
||||||
|
H.commitDb h $ deleteWhere
|
||||||
[ LiveSizeChangesRepo ==. u
|
[ LiveSizeChangesRepo ==. u
|
||||||
, LiveSizeChangesKey ==. k
|
, LiveSizeChangesKey ==. k
|
||||||
, LiveSizeChangesChange ==. sc
|
, LiveSizeChangesChange ==. sc
|
||||||
]
|
]
|
||||||
|
finishedLiveSizeChange (RepoSizeHandle Nothing) _ _ _ = noop
|
||||||
|
|
||||||
getLiveSizeChanges :: RepoSizeHandle -> IO (M.Map UUID (Key, SizeChange))
|
getLiveSizeChanges :: RepoSizeHandle -> IO (M.Map UUID (Key, SizeChange))
|
||||||
getLiveSizeChanges (RepoSizeHandle (Just h)) = H.queryDb h $ do
|
getLiveSizeChanges (RepoSizeHandle (Just h)) = H.queryDb h $ do
|
||||||
|
@ -185,14 +193,3 @@ getLiveSizeChanges (RepoSizeHandle Nothing) = return mempty
|
||||||
|
|
||||||
getLiveSizeChanges' :: SqlPersistM [Entity LiveSizeChanges]
|
getLiveSizeChanges' :: SqlPersistM [Entity LiveSizeChanges]
|
||||||
getLiveSizeChanges' = selectList [] []
|
getLiveSizeChanges' = selectList [] []
|
||||||
|
|
||||||
instance PersistField SizeChange where
|
|
||||||
toPersistValue AddingKey = toPersistValue (1 :: Int)
|
|
||||||
toPersistValue RemovingKey = toPersistValue (-1 :: Int)
|
|
||||||
fromPersistValue b = fromPersistValue b >>= \case
|
|
||||||
(1 :: Int) -> Right AddingKey
|
|
||||||
-1 -> Right RemovingKey
|
|
||||||
v -> Left $ T.pack $ "bad serialized SizeChange "++ show v
|
|
||||||
|
|
||||||
instance PersistFieldSql SizeChange where
|
|
||||||
sqlType _ = SqlInt32
|
|
||||||
|
|
14
Database/RepoSize/Handle.hs
Normal file
14
Database/RepoSize/Handle.hs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{- Sqlite database used to track the sizes of repositories.
|
||||||
|
-
|
||||||
|
- Copyright 2024 Joey Hess <id@joeyh.name>
|
||||||
|
-:
|
||||||
|
- Licensed under the GNU AGPL version 3 or higher.
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Database.RepoSize.Handle where
|
||||||
|
|
||||||
|
import qualified Database.Handle as H
|
||||||
|
|
||||||
|
-- Contains Nothing if the database was not able to be opened due to
|
||||||
|
-- permissions.
|
||||||
|
newtype RepoSizeHandle = RepoSizeHandle (Maybe H.DbHandle)
|
67
Limit.hs
67
Limit.hs
|
@ -18,7 +18,6 @@ import Annex.WorkTree
|
||||||
import Annex.UUID
|
import Annex.UUID
|
||||||
import Annex.Magic
|
import Annex.Magic
|
||||||
import Annex.RepoSize
|
import Annex.RepoSize
|
||||||
import Types.RepoSize
|
|
||||||
import Logs.MaxSize
|
import Logs.MaxSize
|
||||||
import Annex.Link
|
import Annex.Link
|
||||||
import Types.Link
|
import Types.Link
|
||||||
|
@ -67,7 +66,7 @@ getMatcher = run <$> getMatcher'
|
||||||
run matcher i = do
|
run matcher i = do
|
||||||
(match, desc) <- runWriterT $
|
(match, desc) <- runWriterT $
|
||||||
Utility.Matcher.matchMrun' matcher $ \o ->
|
Utility.Matcher.matchMrun' matcher $ \o ->
|
||||||
matchAction o S.empty i
|
matchAction o NoLiveUpdate S.empty i
|
||||||
explain (mkActionItem i) $ UnquotedString <$>
|
explain (mkActionItem i) $ UnquotedString <$>
|
||||||
Utility.Matcher.describeMatchResult matchDesc desc
|
Utility.Matcher.describeMatchResult matchDesc desc
|
||||||
(if match then "matches:" else "does not match:")
|
(if match then "matches:" else "does not match:")
|
||||||
|
@ -109,7 +108,7 @@ addInclude = addLimit . limitInclude
|
||||||
|
|
||||||
limitInclude :: MkLimit Annex
|
limitInclude :: MkLimit Annex
|
||||||
limitInclude glob = Right $ MatchFiles
|
limitInclude glob = Right $ MatchFiles
|
||||||
{ matchAction = const $ matchGlobFile glob
|
{ matchAction = const $ const $ matchGlobFile glob
|
||||||
, matchNeedsFileName = True
|
, matchNeedsFileName = True
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
, matchNeedsKey = False
|
, matchNeedsKey = False
|
||||||
|
@ -123,7 +122,7 @@ addExclude = addLimit . limitExclude
|
||||||
|
|
||||||
limitExclude :: MkLimit Annex
|
limitExclude :: MkLimit Annex
|
||||||
limitExclude glob = Right $ MatchFiles
|
limitExclude glob = Right $ MatchFiles
|
||||||
{ matchAction = const $ not <$$> matchGlobFile glob
|
{ matchAction = const $ const $ not <$$> matchGlobFile glob
|
||||||
, matchNeedsFileName = True
|
, matchNeedsFileName = True
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
, matchNeedsKey = False
|
, matchNeedsKey = False
|
||||||
|
@ -148,7 +147,7 @@ addIncludeSameContent = addLimit . limitIncludeSameContent
|
||||||
|
|
||||||
limitIncludeSameContent :: MkLimit Annex
|
limitIncludeSameContent :: MkLimit Annex
|
||||||
limitIncludeSameContent glob = Right $ MatchFiles
|
limitIncludeSameContent glob = Right $ MatchFiles
|
||||||
{ matchAction = const $ matchSameContentGlob glob
|
{ matchAction = const $ const $ matchSameContentGlob glob
|
||||||
, matchNeedsFileName = True
|
, matchNeedsFileName = True
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
, matchNeedsKey = False
|
, matchNeedsKey = False
|
||||||
|
@ -163,7 +162,7 @@ addExcludeSameContent = addLimit . limitExcludeSameContent
|
||||||
|
|
||||||
limitExcludeSameContent :: MkLimit Annex
|
limitExcludeSameContent :: MkLimit Annex
|
||||||
limitExcludeSameContent glob = Right $ MatchFiles
|
limitExcludeSameContent glob = Right $ MatchFiles
|
||||||
{ matchAction = const $ not <$$> matchSameContentGlob glob
|
{ matchAction = const $ const $ not <$$> matchSameContentGlob glob
|
||||||
, matchNeedsFileName = True
|
, matchNeedsFileName = True
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
, matchNeedsKey = False
|
, matchNeedsKey = False
|
||||||
|
@ -239,7 +238,7 @@ matchMagic
|
||||||
-> MkLimit Annex
|
-> MkLimit Annex
|
||||||
matchMagic limitname querymagic selectprovidedinfo selectuserprovidedinfo (Just magic) glob =
|
matchMagic limitname querymagic selectprovidedinfo selectuserprovidedinfo (Just magic) glob =
|
||||||
Right $ MatchFiles
|
Right $ MatchFiles
|
||||||
{ matchAction = const go
|
{ matchAction = const $ const go
|
||||||
, matchNeedsFileName = False
|
, matchNeedsFileName = False
|
||||||
, matchNeedsFileContent = True
|
, matchNeedsFileContent = True
|
||||||
, matchNeedsKey = False
|
, matchNeedsKey = False
|
||||||
|
@ -266,7 +265,7 @@ matchMagic limitname _ _ _ Nothing _ =
|
||||||
|
|
||||||
addUnlocked :: Annex ()
|
addUnlocked :: Annex ()
|
||||||
addUnlocked = addLimit $ Right $ MatchFiles
|
addUnlocked = addLimit $ Right $ MatchFiles
|
||||||
{ matchAction = const $ matchLockStatus False
|
{ matchAction = const $ const $ matchLockStatus False
|
||||||
, matchNeedsFileName = True
|
, matchNeedsFileName = True
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
, matchNeedsKey = False
|
, matchNeedsKey = False
|
||||||
|
@ -276,7 +275,7 @@ addUnlocked = addLimit $ Right $ MatchFiles
|
||||||
|
|
||||||
addLocked :: Annex ()
|
addLocked :: Annex ()
|
||||||
addLocked = addLimit $ Right $ MatchFiles
|
addLocked = addLimit $ Right $ MatchFiles
|
||||||
{ matchAction = const $ matchLockStatus True
|
{ matchAction = const $ const $ matchLockStatus True
|
||||||
, matchNeedsFileName = True
|
, matchNeedsFileName = True
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
, matchNeedsKey = False
|
, matchNeedsKey = False
|
||||||
|
@ -311,7 +310,7 @@ addIn s = do
|
||||||
where
|
where
|
||||||
(name, date) = separate (== '@') s
|
(name, date) = separate (== '@') s
|
||||||
use inhere a = Right $ MatchFiles
|
use inhere a = Right $ MatchFiles
|
||||||
{ matchAction = checkKey . a
|
{ matchAction = const $ checkKey . a
|
||||||
, matchNeedsFileName = False
|
, matchNeedsFileName = False
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
, matchNeedsKey = True
|
, matchNeedsKey = True
|
||||||
|
@ -339,7 +338,7 @@ addExpectedPresent :: Annex ()
|
||||||
addExpectedPresent = do
|
addExpectedPresent = do
|
||||||
hereu <- getUUID
|
hereu <- getUUID
|
||||||
addLimit $ Right $ MatchFiles
|
addLimit $ Right $ MatchFiles
|
||||||
{ matchAction = const $ checkKey $ \key -> do
|
{ matchAction = const $ const $ checkKey $ \key -> do
|
||||||
us <- Remote.keyLocations key
|
us <- Remote.keyLocations key
|
||||||
return $ hereu `elem` us
|
return $ hereu `elem` us
|
||||||
, matchNeedsFileName = False
|
, matchNeedsFileName = False
|
||||||
|
@ -352,7 +351,7 @@ addExpectedPresent = do
|
||||||
{- Limit to content that is currently present on a uuid. -}
|
{- Limit to content that is currently present on a uuid. -}
|
||||||
limitPresent :: Maybe UUID -> MatchFiles Annex
|
limitPresent :: Maybe UUID -> MatchFiles Annex
|
||||||
limitPresent u = MatchFiles
|
limitPresent u = MatchFiles
|
||||||
{ matchAction = const $ checkKey $ \key -> do
|
{ matchAction = const $ const $ checkKey $ \key -> do
|
||||||
hereu <- getUUID
|
hereu <- getUUID
|
||||||
if u == Just hereu || isNothing u
|
if u == Just hereu || isNothing u
|
||||||
then inAnnex key
|
then inAnnex key
|
||||||
|
@ -369,7 +368,7 @@ limitPresent u = MatchFiles
|
||||||
{- Limit to content that is in a directory, anywhere in the repository tree -}
|
{- Limit to content that is in a directory, anywhere in the repository tree -}
|
||||||
limitInDir :: FilePath -> String -> MatchFiles Annex
|
limitInDir :: FilePath -> String -> MatchFiles Annex
|
||||||
limitInDir dir desc = MatchFiles
|
limitInDir dir desc = MatchFiles
|
||||||
{ matchAction = const go
|
{ matchAction = const $ const go
|
||||||
, matchNeedsFileName = True
|
, matchNeedsFileName = True
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
, matchNeedsKey = False
|
, matchNeedsKey = False
|
||||||
|
@ -400,7 +399,7 @@ limitCopies want = case splitc ':' want of
|
||||||
go num good = case readish num of
|
go num good = case readish num of
|
||||||
Nothing -> Left "bad number for copies"
|
Nothing -> Left "bad number for copies"
|
||||||
Just n -> Right $ MatchFiles
|
Just n -> Right $ MatchFiles
|
||||||
{ matchAction = \notpresent -> checkKey $
|
{ matchAction = const $ \notpresent -> checkKey $
|
||||||
go' n good notpresent
|
go' n good notpresent
|
||||||
, matchNeedsFileName = False
|
, matchNeedsFileName = False
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
|
@ -425,7 +424,7 @@ addLackingCopies desc approx = addLimit . limitLackingCopies desc approx
|
||||||
limitLackingCopies :: String -> Bool -> MkLimit Annex
|
limitLackingCopies :: String -> Bool -> MkLimit Annex
|
||||||
limitLackingCopies desc approx want = case readish want of
|
limitLackingCopies desc approx want = case readish want of
|
||||||
Just needed -> Right $ MatchFiles
|
Just needed -> Right $ MatchFiles
|
||||||
{ matchAction = \notpresent mi -> flip checkKey mi $
|
{ matchAction = const $ \notpresent mi -> flip checkKey mi $
|
||||||
go mi needed notpresent
|
go mi needed notpresent
|
||||||
, matchNeedsFileName = False
|
, matchNeedsFileName = False
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
|
@ -456,7 +455,7 @@ limitLackingCopies desc approx want = case readish want of
|
||||||
-}
|
-}
|
||||||
limitUnused :: MatchFiles Annex
|
limitUnused :: MatchFiles Annex
|
||||||
limitUnused = MatchFiles
|
limitUnused = MatchFiles
|
||||||
{ matchAction = go
|
{ matchAction = const $ const go
|
||||||
, matchNeedsFileName = True
|
, matchNeedsFileName = True
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
, matchNeedsKey = True
|
, matchNeedsKey = True
|
||||||
|
@ -464,9 +463,9 @@ limitUnused = MatchFiles
|
||||||
, matchDesc = matchDescSimple "unused"
|
, matchDesc = matchDescSimple "unused"
|
||||||
}
|
}
|
||||||
where
|
where
|
||||||
go _ (MatchingFile _) = return False
|
go (MatchingFile _) = return False
|
||||||
go _ (MatchingInfo p) = maybe (pure False) isunused (providedKey p)
|
go (MatchingInfo p) = maybe (pure False) isunused (providedKey p)
|
||||||
go _ (MatchingUserInfo p) = do
|
go (MatchingUserInfo p) = do
|
||||||
k <- getUserInfo (userProvidedKey p)
|
k <- getUserInfo (userProvidedKey p)
|
||||||
isunused k
|
isunused k
|
||||||
|
|
||||||
|
@ -479,7 +478,7 @@ addAnything = addLimit (Right limitAnything)
|
||||||
{- Limit that matches any version of any file or key. -}
|
{- Limit that matches any version of any file or key. -}
|
||||||
limitAnything :: MatchFiles Annex
|
limitAnything :: MatchFiles Annex
|
||||||
limitAnything = MatchFiles
|
limitAnything = MatchFiles
|
||||||
{ matchAction = \_ _ -> return True
|
{ matchAction = \_ _ _ -> return True
|
||||||
, matchNeedsFileName = False
|
, matchNeedsFileName = False
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
, matchNeedsKey = False
|
, matchNeedsKey = False
|
||||||
|
@ -494,7 +493,7 @@ addNothing = addLimit (Right limitNothing)
|
||||||
{- Limit that never matches. -}
|
{- Limit that never matches. -}
|
||||||
limitNothing :: MatchFiles Annex
|
limitNothing :: MatchFiles Annex
|
||||||
limitNothing = MatchFiles
|
limitNothing = MatchFiles
|
||||||
{ matchAction = \_ _ -> return False
|
{ matchAction = \_ _ _ -> return False
|
||||||
, matchNeedsFileName = False
|
, matchNeedsFileName = False
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
, matchNeedsKey = False
|
, matchNeedsKey = False
|
||||||
|
@ -509,7 +508,7 @@ addInAllGroup groupname = addLimit $ limitInAllGroup groupMap groupname
|
||||||
|
|
||||||
limitInAllGroup :: Annex GroupMap -> MkLimit Annex
|
limitInAllGroup :: Annex GroupMap -> MkLimit Annex
|
||||||
limitInAllGroup getgroupmap groupname = Right $ MatchFiles
|
limitInAllGroup getgroupmap groupname = Right $ MatchFiles
|
||||||
{ matchAction = \notpresent mi -> do
|
{ matchAction = const $ \notpresent mi -> do
|
||||||
m <- getgroupmap
|
m <- getgroupmap
|
||||||
let want = fromMaybe S.empty $ M.lookup (toGroup groupname) $ uuidsByGroup m
|
let want = fromMaybe S.empty $ M.lookup (toGroup groupname) $ uuidsByGroup m
|
||||||
if S.null want
|
if S.null want
|
||||||
|
@ -537,7 +536,7 @@ addOnlyInGroup groupname = addLimit $ limitOnlyInGroup groupMap groupname
|
||||||
|
|
||||||
limitOnlyInGroup :: Annex GroupMap -> MkLimit Annex
|
limitOnlyInGroup :: Annex GroupMap -> MkLimit Annex
|
||||||
limitOnlyInGroup getgroupmap groupname = Right $ MatchFiles
|
limitOnlyInGroup getgroupmap groupname = Right $ MatchFiles
|
||||||
{ matchAction = \notpresent mi -> do
|
{ matchAction = const $ \notpresent mi -> do
|
||||||
m <- getgroupmap
|
m <- getgroupmap
|
||||||
let want = fromMaybe S.empty $ M.lookup (toGroup groupname) $ uuidsByGroup m
|
let want = fromMaybe S.empty $ M.lookup (toGroup groupname) $ uuidsByGroup m
|
||||||
if S.null want
|
if S.null want
|
||||||
|
@ -568,12 +567,12 @@ limitBalanced' termname fullybalanced mu groupname = do
|
||||||
else groupname ++ ":1"
|
else groupname ++ ":1"
|
||||||
let present = limitPresent mu
|
let present = limitPresent mu
|
||||||
Right $ MatchFiles
|
Right $ MatchFiles
|
||||||
{ matchAction = \a i ->
|
{ matchAction = \lu a i ->
|
||||||
ifM (Annex.getRead Annex.rebalance)
|
ifM (Annex.getRead Annex.rebalance)
|
||||||
( matchAction fullybalanced a i
|
( matchAction fullybalanced lu a i
|
||||||
, matchAction present a i <||>
|
, matchAction present lu a i <||>
|
||||||
((not <$> matchAction copies a i)
|
((not <$> matchAction copies lu a i)
|
||||||
<&&> matchAction fullybalanced a i
|
<&&> matchAction fullybalanced lu a i
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
, matchNeedsFileName =
|
, matchNeedsFileName =
|
||||||
|
@ -659,7 +658,7 @@ limitFullyBalanced'''
|
||||||
-> Int
|
-> Int
|
||||||
-> MkLimit Annex
|
-> MkLimit Annex
|
||||||
limitFullyBalanced''' filtercandidates termname mu getgroupmap g n want = Right $ MatchFiles
|
limitFullyBalanced''' filtercandidates termname mu getgroupmap g n want = Right $ MatchFiles
|
||||||
{ matchAction = const $ checkKey $ \key -> do
|
{ matchAction = \lu -> const $ checkKey $ \key -> do
|
||||||
gm <- getgroupmap
|
gm <- getgroupmap
|
||||||
let groupmembers = fromMaybe S.empty $
|
let groupmembers = fromMaybe S.empty $
|
||||||
M.lookup g (uuidsByGroup gm)
|
M.lookup g (uuidsByGroup gm)
|
||||||
|
@ -728,7 +727,7 @@ addInBackend = addLimit . limitInBackend
|
||||||
|
|
||||||
limitInBackend :: MkLimit Annex
|
limitInBackend :: MkLimit Annex
|
||||||
limitInBackend name = Right $ MatchFiles
|
limitInBackend name = Right $ MatchFiles
|
||||||
{ matchAction = const $ checkKey check
|
{ matchAction = const $ const $ checkKey check
|
||||||
, matchNeedsFileName = False
|
, matchNeedsFileName = False
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
, matchNeedsKey = True
|
, matchNeedsKey = True
|
||||||
|
@ -745,7 +744,7 @@ addSecureHash = addLimit $ Right limitSecureHash
|
||||||
|
|
||||||
limitSecureHash :: MatchFiles Annex
|
limitSecureHash :: MatchFiles Annex
|
||||||
limitSecureHash = MatchFiles
|
limitSecureHash = MatchFiles
|
||||||
{ matchAction = const $ checkKey isCryptographicallySecureKey
|
{ matchAction = const $ const $ checkKey isCryptographicallySecureKey
|
||||||
, matchNeedsFileName = False
|
, matchNeedsFileName = False
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
, matchNeedsKey = True
|
, matchNeedsKey = True
|
||||||
|
@ -764,7 +763,7 @@ limitSize :: LimitBy -> String -> (Maybe Integer -> Maybe Integer -> Bool) -> Mk
|
||||||
limitSize lb desc vs s = case readSize dataUnits s of
|
limitSize lb desc vs s = case readSize dataUnits s of
|
||||||
Nothing -> Left "bad size"
|
Nothing -> Left "bad size"
|
||||||
Just sz -> Right $ MatchFiles
|
Just sz -> Right $ MatchFiles
|
||||||
{ matchAction = go sz
|
{ matchAction = const $ go sz
|
||||||
, matchNeedsFileName = case lb of
|
, matchNeedsFileName = case lb of
|
||||||
LimitAnnexFiles -> False
|
LimitAnnexFiles -> False
|
||||||
LimitDiskFiles -> True
|
LimitDiskFiles -> True
|
||||||
|
@ -796,7 +795,7 @@ limitMetaData :: MkLimit Annex
|
||||||
limitMetaData s = case parseMetaDataMatcher s of
|
limitMetaData s = case parseMetaDataMatcher s of
|
||||||
Left e -> Left e
|
Left e -> Left e
|
||||||
Right (f, matching) -> Right $ MatchFiles
|
Right (f, matching) -> Right $ MatchFiles
|
||||||
{ matchAction = const $ checkKey (check f matching)
|
{ matchAction = const $ const $ checkKey (check f matching)
|
||||||
, matchNeedsFileName = False
|
, matchNeedsFileName = False
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
, matchNeedsKey = True
|
, matchNeedsKey = True
|
||||||
|
@ -812,7 +811,7 @@ addAccessedWithin :: Duration -> Annex ()
|
||||||
addAccessedWithin duration = do
|
addAccessedWithin duration = do
|
||||||
now <- liftIO getPOSIXTime
|
now <- liftIO getPOSIXTime
|
||||||
addLimit $ Right $ MatchFiles
|
addLimit $ Right $ MatchFiles
|
||||||
{ matchAction = const $ checkKey $ check now
|
{ matchAction = const $ const $ checkKey $ check now
|
||||||
, matchNeedsFileName = False
|
, matchNeedsFileName = False
|
||||||
, matchNeedsFileContent = False
|
, matchNeedsFileContent = False
|
||||||
, matchNeedsKey = False
|
, matchNeedsKey = False
|
||||||
|
|
|
@ -16,23 +16,23 @@ import qualified Remote
|
||||||
|
|
||||||
addWantGet :: Annex ()
|
addWantGet :: Annex ()
|
||||||
addWantGet = addPreferredContentLimit "want-get" $
|
addWantGet = addPreferredContentLimit "want-get" $
|
||||||
checkWant $ wantGet False Nothing
|
checkWant $ wantGet NoLiveUpdate False Nothing
|
||||||
|
|
||||||
addWantGetBy :: String -> Annex ()
|
addWantGetBy :: String -> Annex ()
|
||||||
addWantGetBy name = do
|
addWantGetBy name = do
|
||||||
u <- Remote.nameToUUID name
|
u <- Remote.nameToUUID name
|
||||||
addPreferredContentLimit "want-get-by" $ checkWant $ \af ->
|
addPreferredContentLimit "want-get-by" $ checkWant $ \af ->
|
||||||
wantGetBy False Nothing af u
|
wantGetBy NoLiveUpdate False Nothing af u
|
||||||
|
|
||||||
addWantDrop :: Annex ()
|
addWantDrop :: Annex ()
|
||||||
addWantDrop = addPreferredContentLimit "want-drop" $ checkWant $ \af ->
|
addWantDrop = addPreferredContentLimit "want-drop" $ checkWant $ \af ->
|
||||||
wantDrop False Nothing Nothing af (Just [])
|
wantDrop NoLiveUpdate False Nothing Nothing af (Just [])
|
||||||
|
|
||||||
addWantDropBy :: String -> Annex ()
|
addWantDropBy :: String -> Annex ()
|
||||||
addWantDropBy name = do
|
addWantDropBy name = do
|
||||||
u <- Remote.nameToUUID name
|
u <- Remote.nameToUUID name
|
||||||
addPreferredContentLimit "want-drop-by" $ checkWant $ \af ->
|
addPreferredContentLimit "want-drop-by" $ checkWant $ \af ->
|
||||||
wantDrop False (Just u) Nothing af (Just [])
|
wantDrop NoLiveUpdate False (Just u) Nothing af (Just [])
|
||||||
|
|
||||||
addPreferredContentLimit :: String -> (MatchInfo -> Annex Bool) -> Annex ()
|
addPreferredContentLimit :: String -> (MatchInfo -> Annex Bool) -> Annex ()
|
||||||
addPreferredContentLimit desc a = do
|
addPreferredContentLimit desc a = do
|
||||||
|
@ -41,7 +41,7 @@ addPreferredContentLimit desc a = do
|
||||||
nk <- introspectPreferredRequiredContent matchNeedsKey Nothing
|
nk <- introspectPreferredRequiredContent matchNeedsKey Nothing
|
||||||
nl <- introspectPreferredRequiredContent matchNeedsLocationLog Nothing
|
nl <- introspectPreferredRequiredContent matchNeedsLocationLog Nothing
|
||||||
addLimit $ Right $ MatchFiles
|
addLimit $ Right $ MatchFiles
|
||||||
{ matchAction = const a
|
{ matchAction = const $ const a
|
||||||
, matchNeedsFileName = nfn
|
, matchNeedsFileName = nfn
|
||||||
, matchNeedsFileContent = nfc
|
, matchNeedsFileContent = nfc
|
||||||
, matchNeedsKey = nk
|
, matchNeedsKey = nk
|
||||||
|
|
|
@ -58,17 +58,17 @@ import qualified Data.Map as M
|
||||||
import qualified Data.Set as S
|
import qualified Data.Set as S
|
||||||
|
|
||||||
{- Log a change in the presence of a key's value in current repository. -}
|
{- Log a change in the presence of a key's value in current repository. -}
|
||||||
logStatus :: Key -> LogStatus -> Annex ()
|
logStatus :: LiveUpdate -> Key -> LogStatus -> Annex ()
|
||||||
logStatus key s = do
|
logStatus lu key s = do
|
||||||
u <- getUUID
|
u <- getUUID
|
||||||
logChange key u s
|
logChange lu key u s
|
||||||
|
|
||||||
{- Run an action that gets the content of a key, and update the log
|
{- Run an action that gets the content of a key, and update the log
|
||||||
- when it succeeds. -}
|
- when it succeeds. -}
|
||||||
logStatusAfter :: Key -> Annex Bool -> Annex Bool
|
logStatusAfter :: LiveUpdate -> Key -> Annex Bool -> Annex Bool
|
||||||
logStatusAfter key a = ifM a
|
logStatusAfter lu key a = ifM a
|
||||||
( do
|
( do
|
||||||
logStatus key InfoPresent
|
logStatus lu key InfoPresent
|
||||||
return True
|
return True
|
||||||
, return False
|
, return False
|
||||||
)
|
)
|
||||||
|
@ -79,8 +79,8 @@ logStatusAfter key a = ifM a
|
||||||
- logged to contain a key, loading the log will include the cluster's
|
- logged to contain a key, loading the log will include the cluster's
|
||||||
- UUID.
|
- UUID.
|
||||||
-}
|
-}
|
||||||
logChange :: Key -> UUID -> LogStatus -> Annex ()
|
logChange :: LiveUpdate -> Key -> UUID -> LogStatus -> Annex ()
|
||||||
logChange key u@(UUID _) s
|
logChange lu key u@(UUID _) s
|
||||||
| isClusterUUID u = noop
|
| isClusterUUID u = noop
|
||||||
| otherwise = do
|
| otherwise = do
|
||||||
config <- Annex.getGitConfig
|
config <- Annex.getGitConfig
|
||||||
|
@ -90,8 +90,8 @@ logChange key u@(UUID _) s
|
||||||
s
|
s
|
||||||
(LogInfo (fromUUID u))
|
(LogInfo (fromUUID u))
|
||||||
when changed $
|
when changed $
|
||||||
updateRepoSize u key s
|
updateRepoSize lu u key s
|
||||||
logChange _ NoUUID _ = noop
|
logChange _ _ NoUUID _ = noop
|
||||||
|
|
||||||
{- Returns a list of repository UUIDs that, according to the log, have
|
{- Returns a list of repository UUIDs that, according to the log, have
|
||||||
- the value of a key. -}
|
- the value of a key. -}
|
||||||
|
@ -181,7 +181,7 @@ setDead key = do
|
||||||
Unknown -> CandidateVectorClock 0
|
Unknown -> CandidateVectorClock 0
|
||||||
addLog' (Annex.Branch.RegardingUUID [u]) logfile InfoDead
|
addLog' (Annex.Branch.RegardingUUID [u]) logfile InfoDead
|
||||||
(info l) c
|
(info l) c
|
||||||
updateRepoSize u key InfoDead
|
updateRepoSize NoLiveUpdate u key InfoDead
|
||||||
|
|
||||||
data Unchecked a = Unchecked (Annex (Maybe a))
|
data Unchecked a = Unchecked (Annex (Maybe a))
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ module Logs.MaxSize (
|
||||||
|
|
||||||
import qualified Annex
|
import qualified Annex
|
||||||
import Annex.Common
|
import Annex.Common
|
||||||
import Types.RepoSize
|
|
||||||
import Logs
|
import Logs
|
||||||
import Logs.UUIDBased
|
import Logs.UUIDBased
|
||||||
import Logs.MapLog
|
import Logs.MapLog
|
||||||
|
|
|
@ -48,19 +48,19 @@ import Limit
|
||||||
|
|
||||||
{- Checks if a file is preferred content (or required content) for the
|
{- Checks if a file is preferred content (or required content) for the
|
||||||
- specified repository (or the current repository if none is specified). -}
|
- specified repository (or the current repository if none is specified). -}
|
||||||
isPreferredContent :: Maybe UUID -> AssumeNotPresent -> Maybe Key -> AssociatedFile -> Bool -> Annex Bool
|
isPreferredContent :: LiveUpdate -> Maybe UUID -> AssumeNotPresent -> Maybe Key -> AssociatedFile -> Bool -> Annex Bool
|
||||||
isPreferredContent = checkMap preferredContentMap
|
isPreferredContent = checkMap preferredContentMap
|
||||||
|
|
||||||
isRequiredContent :: Maybe UUID -> AssumeNotPresent -> Maybe Key -> AssociatedFile -> Bool -> Annex Bool
|
isRequiredContent :: LiveUpdate -> Maybe UUID -> AssumeNotPresent -> Maybe Key -> AssociatedFile -> Bool -> Annex Bool
|
||||||
isRequiredContent = checkMap requiredContentMap
|
isRequiredContent = checkMap requiredContentMap
|
||||||
|
|
||||||
checkMap :: Annex (FileMatcherMap Annex) -> Maybe UUID -> AssumeNotPresent -> Maybe Key -> AssociatedFile -> Bool -> Annex Bool
|
checkMap :: Annex (FileMatcherMap Annex) -> LiveUpdate -> Maybe UUID -> AssumeNotPresent -> Maybe Key -> AssociatedFile -> Bool -> Annex Bool
|
||||||
checkMap getmap mu notpresent mkey afile d = do
|
checkMap getmap lu mu notpresent mkey afile d = do
|
||||||
u <- maybe getUUID return mu
|
u <- maybe getUUID return mu
|
||||||
m <- getmap
|
m <- getmap
|
||||||
case M.lookup u m of
|
case M.lookup u m of
|
||||||
Nothing -> return d
|
Nothing -> return d
|
||||||
Just matcher -> checkMatcher matcher mkey afile notpresent (return d) (return d)
|
Just matcher -> checkMatcher matcher mkey afile lu notpresent (return d) (return d)
|
||||||
|
|
||||||
{- Checks if the preferred or required content for the specified repository
|
{- Checks if the preferred or required content for the specified repository
|
||||||
- (or the current repository if none is specified) contains any terms
|
- (or the current repository if none is specified) contains any terms
|
||||||
|
|
|
@ -80,7 +80,7 @@ setUrlPresent key url = do
|
||||||
-- in the web.
|
-- in the web.
|
||||||
case snd (getDownloader url) of
|
case snd (getDownloader url) of
|
||||||
OtherDownloader -> return ()
|
OtherDownloader -> return ()
|
||||||
_ -> logChange key webUUID InfoPresent
|
_ -> logChange NoLiveUpdate key webUUID InfoPresent
|
||||||
|
|
||||||
setUrlMissing :: Key -> URLString -> Annex ()
|
setUrlMissing :: Key -> URLString -> Annex ()
|
||||||
setUrlMissing key url = do
|
setUrlMissing key url = do
|
||||||
|
@ -94,7 +94,7 @@ setUrlMissing key url = do
|
||||||
-- for the key are web urls, the key must not be present
|
-- for the key are web urls, the key must not be present
|
||||||
-- in the web.
|
-- in the web.
|
||||||
when (isweb url && null (filter isweb $ filter (/= url) us)) $
|
when (isweb url && null (filter isweb $ filter (/= url) us)) $
|
||||||
logChange key webUUID InfoMissing
|
logChange NoLiveUpdate key webUUID InfoMissing
|
||||||
where
|
where
|
||||||
isweb u = case snd (getDownloader u) of
|
isweb u = case snd (getDownloader u) of
|
||||||
OtherDownloader -> False
|
OtherDownloader -> False
|
||||||
|
|
|
@ -80,7 +80,7 @@ runLocal runst runner a = case a of
|
||||||
iv <- startVerifyKeyContentIncrementally DefaultVerify k
|
iv <- startVerifyKeyContentIncrementally DefaultVerify k
|
||||||
let runtransfer ti =
|
let runtransfer ti =
|
||||||
Right <$> transfer download' k af Nothing (\p ->
|
Right <$> transfer download' k af Nothing (\p ->
|
||||||
logStatusAfter k $ getViaTmp rsp DefaultVerify k af Nothing $ \tmp ->
|
logStatusAfter NoLiveUpdate k $ getViaTmp rsp DefaultVerify k af Nothing $ \tmp ->
|
||||||
storefile (fromRawFilePath tmp) o l getb iv validitycheck p ti)
|
storefile (fromRawFilePath tmp) o l getb iv validitycheck p ti)
|
||||||
let fallback = return $ Left $
|
let fallback = return $ Left $
|
||||||
ProtoFailureMessage "transfer already in progress, or unable to take transfer lock"
|
ProtoFailureMessage "transfer already in progress, or unable to take transfer lock"
|
||||||
|
@ -121,7 +121,8 @@ runLocal runst runner a = case a of
|
||||||
Right (Left e) -> return $ Left e
|
Right (Left e) -> return $ Left e
|
||||||
Right (Right ok) -> runner (next ok)
|
Right (Right ok) -> runner (next ok)
|
||||||
SetPresent k u next -> do
|
SetPresent k u next -> do
|
||||||
v <- tryNonAsync $ logChange k u InfoPresent
|
-- FIXME: Can a live update be done here?
|
||||||
|
v <- tryNonAsync $ logChange NoLiveUpdate k u InfoPresent
|
||||||
case v of
|
case v of
|
||||||
Left e -> return $ Left $ ProtoFailureException e
|
Left e -> return $ Left $ ProtoFailureException e
|
||||||
Right () -> runner next
|
Right () -> runner next
|
||||||
|
@ -132,7 +133,8 @@ runLocal runst runner a = case a of
|
||||||
Right result -> runner (next result)
|
Right result -> runner (next result)
|
||||||
RemoveContent k mts next -> do
|
RemoveContent k mts next -> do
|
||||||
let cleanup = do
|
let cleanup = do
|
||||||
logStatus k InfoMissing
|
-- FIXME: Can a live update be done here?
|
||||||
|
logStatus NoLiveUpdate k InfoMissing
|
||||||
return True
|
return True
|
||||||
let checkts = case mts of
|
let checkts = case mts of
|
||||||
Nothing -> return True
|
Nothing -> return True
|
||||||
|
|
|
@ -425,8 +425,8 @@ forceTrust level remotename = do
|
||||||
- in the local repo, not on the remote. The process of transferring the
|
- in the local repo, not on the remote. The process of transferring the
|
||||||
- key to the remote, or removing the key from it *may* log the change
|
- key to the remote, or removing the key from it *may* log the change
|
||||||
- on the remote, but this cannot always be relied on. -}
|
- on the remote, but this cannot always be relied on. -}
|
||||||
logStatus :: Remote -> Key -> LogStatus -> Annex ()
|
logStatus :: LiveUpdate -> Remote -> Key -> LogStatus -> Annex ()
|
||||||
logStatus remote key = logChange key (uuid remote)
|
logStatus lu remote key = logChange lu key (uuid remote)
|
||||||
|
|
||||||
{- Orders remotes by cost, with ones with the lowest cost grouped together. -}
|
{- Orders remotes by cost, with ones with the lowest cost grouped together. -}
|
||||||
byCost :: [Remote] -> [[Remote]]
|
byCost :: [Remote] -> [[Remote]]
|
||||||
|
|
|
@ -495,7 +495,7 @@ dropKey' repo r st@(State connpool duc _ _ _) proof key
|
||||||
ifM (Annex.Content.inAnnex key)
|
ifM (Annex.Content.inAnnex key)
|
||||||
( do
|
( do
|
||||||
let cleanup = do
|
let cleanup = do
|
||||||
logStatus key InfoMissing
|
logStatus NoLiveUpdate key InfoMissing
|
||||||
return True
|
return True
|
||||||
Annex.Content.lockContentForRemoval key cleanup $ \lock ->
|
Annex.Content.lockContentForRemoval key cleanup $ \lock ->
|
||||||
ifM (liftIO $ checkSafeDropProofEndTime proof)
|
ifM (liftIO $ checkSafeDropProofEndTime proof)
|
||||||
|
@ -509,7 +509,7 @@ dropKey' repo r st@(State connpool duc _ _ _) proof key
|
||||||
unless proofunexpired
|
unless proofunexpired
|
||||||
safeDropProofExpired
|
safeDropProofExpired
|
||||||
|
|
||||||
storefanout = P2PHelper.storeFanout key InfoMissing (uuid r) . map fromB64UUID
|
storefanout = P2PHelper.storeFanout NoLiveUpdate key InfoMissing (uuid r) . map fromB64UUID
|
||||||
|
|
||||||
lockKey :: Remote -> State -> Key -> (VerifiedCopy -> Annex r) -> Annex r
|
lockKey :: Remote -> State -> Key -> (VerifiedCopy -> Annex r) -> Annex r
|
||||||
lockKey r st key callback = do
|
lockKey r st key callback = do
|
||||||
|
@ -667,7 +667,7 @@ copyToRemote' repo r st@(State connpool duc _ _ _) key af o meterupdate
|
||||||
let checksuccess = liftIO checkio >>= \case
|
let checksuccess = liftIO checkio >>= \case
|
||||||
Just err -> giveup err
|
Just err -> giveup err
|
||||||
Nothing -> return True
|
Nothing -> return True
|
||||||
logStatusAfter key $ Annex.Content.getViaTmp rsp verify key af (Just sz) $ \dest ->
|
logStatusAfter NoLiveUpdate key $ Annex.Content.getViaTmp rsp verify key af (Just sz) $ \dest ->
|
||||||
metered (Just (combineMeterUpdate meterupdate p)) key bwlimit $ \_ p' ->
|
metered (Just (combineMeterUpdate meterupdate p)) key bwlimit $ \_ p' ->
|
||||||
copier object (fromRawFilePath dest) key p' checksuccess verify
|
copier object (fromRawFilePath dest) key p' checksuccess verify
|
||||||
)
|
)
|
||||||
|
@ -695,7 +695,7 @@ copyToRemote' repo r st@(State connpool duc _ _ _) key af o meterupdate
|
||||||
PutOffsetResultAlreadyHavePlus fanoutuuids ->
|
PutOffsetResultAlreadyHavePlus fanoutuuids ->
|
||||||
storefanout fanoutuuids
|
storefanout fanoutuuids
|
||||||
|
|
||||||
storefanout = P2PHelper.storeFanout key InfoPresent (uuid r) . map fromB64UUID
|
storefanout = P2PHelper.storeFanout NoLiveUpdate key InfoPresent (uuid r) . map fromB64UUID
|
||||||
|
|
||||||
fsckOnRemote :: Git.Repo -> [CommandParam] -> Annex (IO Bool)
|
fsckOnRemote :: Git.Repo -> [CommandParam] -> Annex (IO Bool)
|
||||||
fsckOnRemote r params
|
fsckOnRemote r params
|
||||||
|
|
|
@ -43,15 +43,15 @@ store remoteuuid gc runner k af o p = do
|
||||||
metered (Just p) sizer bwlimit $ \_ p' ->
|
metered (Just p) sizer bwlimit $ \_ p' ->
|
||||||
runner (P2P.put k af p') >>= \case
|
runner (P2P.put k af p') >>= \case
|
||||||
Just (Just fanoutuuids) ->
|
Just (Just fanoutuuids) ->
|
||||||
storeFanout k InfoPresent remoteuuid fanoutuuids
|
storeFanout NoLiveUpdate k InfoPresent remoteuuid fanoutuuids
|
||||||
Just Nothing -> giveup "Transfer failed"
|
Just Nothing -> giveup "Transfer failed"
|
||||||
Nothing -> remoteUnavail
|
Nothing -> remoteUnavail
|
||||||
|
|
||||||
storeFanout :: Key -> LogStatus -> UUID -> [UUID] -> Annex ()
|
storeFanout :: LiveUpdate -> Key -> LogStatus -> UUID -> [UUID] -> Annex ()
|
||||||
storeFanout k logstatus remoteuuid us =
|
storeFanout lu k logstatus remoteuuid us =
|
||||||
forM_ us $ \u ->
|
forM_ us $ \u ->
|
||||||
when (u /= remoteuuid) $
|
when (u /= remoteuuid) $
|
||||||
logChange k u logstatus
|
logChange lu k u logstatus
|
||||||
|
|
||||||
retrieve :: RemoteGitConfig -> (ProtoRunner (Bool, Verification)) -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> VerifyConfig -> Annex Verification
|
retrieve :: RemoteGitConfig -> (ProtoRunner (Bool, Verification)) -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> VerifyConfig -> Annex Verification
|
||||||
retrieve gc runner k af dest p verifyconfig = do
|
retrieve gc runner k af dest p verifyconfig = do
|
||||||
|
@ -66,10 +66,10 @@ retrieve gc runner k af dest p verifyconfig = do
|
||||||
remove :: UUID -> ProtoRunner (Either String Bool, Maybe [UUID]) -> Maybe SafeDropProof -> Key -> Annex ()
|
remove :: UUID -> ProtoRunner (Either String Bool, Maybe [UUID]) -> Maybe SafeDropProof -> Key -> Annex ()
|
||||||
remove remoteuuid runner proof k = runner (P2P.remove proof k) >>= \case
|
remove remoteuuid runner proof k = runner (P2P.remove proof k) >>= \case
|
||||||
Just (Right True, alsoremoveduuids) ->
|
Just (Right True, alsoremoveduuids) ->
|
||||||
storeFanout k InfoMissing remoteuuid
|
storeFanout NoLiveUpdate k InfoMissing remoteuuid
|
||||||
(fromMaybe [] alsoremoveduuids)
|
(fromMaybe [] alsoremoveduuids)
|
||||||
Just (Right False, alsoremoveduuids) -> do
|
Just (Right False, alsoremoveduuids) -> do
|
||||||
storeFanout k InfoMissing remoteuuid
|
storeFanout NoLiveUpdate k InfoMissing remoteuuid
|
||||||
(fromMaybe [] alsoremoveduuids)
|
(fromMaybe [] alsoremoveduuids)
|
||||||
giveup "removing content from remote failed"
|
giveup "removing content from remote failed"
|
||||||
Just (Left err, _) -> do
|
Just (Left err, _) -> do
|
||||||
|
|
|
@ -11,6 +11,7 @@ import Types.UUID (UUID)
|
||||||
import Types.Key (Key)
|
import Types.Key (Key)
|
||||||
import Types.Link (LinkType)
|
import Types.Link (LinkType)
|
||||||
import Types.Mime
|
import Types.Mime
|
||||||
|
import Types.RepoSize (LiveUpdate)
|
||||||
import Utility.Matcher (Matcher, Token, MatchDesc)
|
import Utility.Matcher (Matcher, Token, MatchDesc)
|
||||||
import Utility.FileSize
|
import Utility.FileSize
|
||||||
import Utility.FileSystemEncoding
|
import Utility.FileSystemEncoding
|
||||||
|
@ -85,7 +86,7 @@ type MkLimit a = String -> Either String (MatchFiles a)
|
||||||
type AssumeNotPresent = S.Set UUID
|
type AssumeNotPresent = S.Set UUID
|
||||||
|
|
||||||
data MatchFiles a = MatchFiles
|
data MatchFiles a = MatchFiles
|
||||||
{ matchAction :: AssumeNotPresent -> MatchInfo -> a Bool
|
{ matchAction :: LiveUpdate -> AssumeNotPresent -> MatchInfo -> a Bool
|
||||||
, matchNeedsFileName :: Bool
|
, matchNeedsFileName :: Bool
|
||||||
-- ^ does the matchAction need a filename in order to match?
|
-- ^ does the matchAction need a filename in order to match?
|
||||||
, matchNeedsFileContent :: Bool
|
, matchNeedsFileContent :: Bool
|
||||||
|
|
|
@ -5,10 +5,17 @@
|
||||||
- Licensed under the GNU AGPL version 3 or higher.
|
- Licensed under the GNU AGPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
|
||||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
{-# LANGUAGE GeneralizedNewtypeDeriving, ScopedTypeVariables #-}
|
||||||
|
|
||||||
module Types.RepoSize where
|
module Types.RepoSize where
|
||||||
|
|
||||||
|
import Types.UUID
|
||||||
|
import Types.Key
|
||||||
|
|
||||||
|
import Control.Concurrent
|
||||||
|
import Database.Persist.Sql hiding (Key)
|
||||||
|
import qualified Data.Text as T
|
||||||
|
|
||||||
-- The current size of a repo.
|
-- The current size of a repo.
|
||||||
newtype RepoSize = RepoSize { fromRepoSize :: Integer }
|
newtype RepoSize = RepoSize { fromRepoSize :: Integer }
|
||||||
deriving (Show, Eq, Ord, Num)
|
deriving (Show, Eq, Ord, Num)
|
||||||
|
@ -16,3 +23,35 @@ newtype RepoSize = RepoSize { fromRepoSize :: Integer }
|
||||||
-- The maximum size of a repo.
|
-- The maximum size of a repo.
|
||||||
newtype MaxSize = MaxSize { fromMaxSize :: Integer }
|
newtype MaxSize = MaxSize { fromMaxSize :: Integer }
|
||||||
deriving (Show, Eq, Ord)
|
deriving (Show, Eq, Ord)
|
||||||
|
|
||||||
|
-- Used when an action is in progress that will change the current size of
|
||||||
|
-- a repository.
|
||||||
|
--
|
||||||
|
-- The live update has been recorded as starting, and filling the MVar with
|
||||||
|
-- the correct UUID, Key, and SizeChange will record the live update
|
||||||
|
-- as complete. The Bool should be True when the action successfully
|
||||||
|
-- added/removed the key from the repository.
|
||||||
|
--
|
||||||
|
-- If the MVar gets garbage collected before it is filled, the live update
|
||||||
|
-- will be removed.
|
||||||
|
--
|
||||||
|
-- This allows other concurrent changes to the same repository take
|
||||||
|
-- the changes to its size into account. If NoLiveUpdate is used, it
|
||||||
|
-- prevents that.
|
||||||
|
data LiveUpdate
|
||||||
|
= LiveUpdate (MVar ()) (MVar (Bool, UUID, Key, SizeChange))
|
||||||
|
| NoLiveUpdate
|
||||||
|
|
||||||
|
data SizeChange = AddingKey | RemovingKey
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
instance PersistField SizeChange where
|
||||||
|
toPersistValue AddingKey = toPersistValue (1 :: Int)
|
||||||
|
toPersistValue RemovingKey = toPersistValue (-1 :: Int)
|
||||||
|
fromPersistValue b = fromPersistValue b >>= \case
|
||||||
|
(1 :: Int) -> Right AddingKey
|
||||||
|
-1 -> Right RemovingKey
|
||||||
|
v -> Left $ T.pack $ "bad serialized SizeChange "++ show v
|
||||||
|
|
||||||
|
instance PersistFieldSql SizeChange where
|
||||||
|
sqlType _ = SqlInt32
|
||||||
|
|
|
@ -154,7 +154,7 @@ upgradeDirectWorkTree = do
|
||||||
locs <- Direct.associatedFiles k
|
locs <- Direct.associatedFiles k
|
||||||
unlessM (anyM (Direct.goodContent k) locs) $ do
|
unlessM (anyM (Direct.goodContent k) locs) $ do
|
||||||
u <- getUUID
|
u <- getUUID
|
||||||
logChange k u InfoMissing
|
logChange NoLiveUpdate k u InfoMissing
|
||||||
)
|
)
|
||||||
|
|
||||||
writepointer f k = liftIO $ do
|
writepointer f k = liftIO $ do
|
||||||
|
|
|
@ -35,10 +35,6 @@ Planned schedule of work:
|
||||||
|
|
||||||
May not be a bug, needs reproducing and analysis.
|
May not be a bug, needs reproducing and analysis.
|
||||||
|
|
||||||
* Check if reposizes updates works when using `git-annex transferrer`.
|
|
||||||
Eg, does the location log update happen in the parent process or in
|
|
||||||
the transferrer process?
|
|
||||||
|
|
||||||
* Concurrency issues with RepoSizes calculation and balanced content:
|
* Concurrency issues with RepoSizes calculation and balanced content:
|
||||||
|
|
||||||
* What if 2 concurrent threads are considering sending two different
|
* What if 2 concurrent threads are considering sending two different
|
||||||
|
@ -146,6 +142,12 @@ Planned schedule of work:
|
||||||
also be done by just repeatedly touching a file named with the processes's
|
also be done by just repeatedly touching a file named with the processes's
|
||||||
pid in it, to avoid sqlite overhead.
|
pid in it, to avoid sqlite overhead.
|
||||||
|
|
||||||
|
* Check all uses of NoLiveUpdate to see if a live update can be started and
|
||||||
|
performed there. There is one in Annex.Cluster in particular that needs a
|
||||||
|
live update
|
||||||
|
|
||||||
|
* Check for TODO XXX markers
|
||||||
|
|
||||||
* `git-annex info` in the limitedcalc path in cachedAllRepoData
|
* `git-annex info` in the limitedcalc path in cachedAllRepoData
|
||||||
double-counts redundant information from the journal due to using
|
double-counts redundant information from the journal due to using
|
||||||
overLocationLogs. In the other path it does not, and this should be fixed
|
overLocationLogs. In the other path it does not, and this should be fixed
|
||||||
|
|
|
@ -786,6 +786,7 @@ Executable git-annex
|
||||||
Database.Queue
|
Database.Queue
|
||||||
Database.RawFilePath
|
Database.RawFilePath
|
||||||
Database.RepoSize
|
Database.RepoSize
|
||||||
|
Database.RepoSize.Handle
|
||||||
Database.Types
|
Database.Types
|
||||||
Database.Utility
|
Database.Utility
|
||||||
Git
|
Git
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue