- Repositories record their UUID and the date when they --get or --drop
- a value.
-
- - Copyright 2010-2023 Joey Hess <id@joeyh.name>
+ - Copyright 2010-2024 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
import qualified Annex.Branch
import Logs
import Logs.Presence
+import Logs.Cluster
import Annex.UUID
import Annex.CatFile
import Annex.VectorClock
import Data.Time.Clock
import qualified Data.ByteString.Lazy as L
+import qualified Data.Map as M
+import qualified Data.Set as S
{- Log a change in the presence of a key's value in current repository. -}
logStatus :: Key -> LogStatus -> Annex ()
, return False
)
-{- Log a change in the presence of a key's value in a repository. -}
+{- Log a change in the presence of a key's value in a repository.
+ -
+ - Cluster UUIDs are not logged. Instead, when a node of a cluster is
+ - logged to contain a key, loading the log will include the cluster's
+ - UUID.
+ -}
logChange :: Key -> UUID -> LogStatus -> Annex ()
-logChange key u@(UUID _) s = do
- config <- Annex.getGitConfig
- maybeAddLog
- (Annex.Branch.RegardingUUID [u])
- (locationLogFile config key)
- s
- (LogInfo (fromUUID u))
+logChange key u@(UUID _) s
+ | isClusterUUID u = noop
+ | otherwise = do
+ config <- Annex.getGitConfig
+ maybeAddLog
+ (Annex.Branch.RegardingUUID [u])
+ (locationLogFile config key)
+ s
+ (LogInfo (fromUUID u))
logChange _ NoUUID _ = noop
{- Returns a list of repository UUIDs that, according to the log, have
loggedLocationsRef ref = map (toUUID . fromLogInfo) . getLog <$> catObject ref
{- Parses the content of a log file and gets the locations in it. -}
-parseLoggedLocations :: L.ByteString -> [UUID]
-parseLoggedLocations l = map (toUUID . fromLogInfo . info)
- (filterPresent (parseLog l))
+parseLoggedLocations :: Clusters -> L.ByteString -> [UUID]
+parseLoggedLocations clusters l = addClusterUUIDs clusters $
+ map (toUUID . fromLogInfo . info)
+ (filterPresent (parseLog l))
getLoggedLocations :: (RawFilePath -> Annex [LogInfo]) -> Key -> Annex [UUID]
getLoggedLocations getter key = do
config <- Annex.getGitConfig
- map (toUUID . fromLogInfo) <$> getter (locationLogFile config key)
+ locs <- map (toUUID . fromLogInfo) <$> getter (locationLogFile config key)
+ clusters <- getClusters
+ return $ addClusterUUIDs clusters locs
+
+-- Add UUIDs of any clusters whose nodes are in the list.
+addClusterUUIDs :: Clusters -> [UUID] -> [UUID]
+addClusterUUIDs clusters locs
+ | M.null clustermap = locs
+ -- ^ optimisation for common case of no clusters
+ | otherwise = clusterlocs ++ locs
+ where
+ clustermap = clusterNodeUUIDs clusters
+ clusterlocs = map fromClusterUUID $ S.toList $
+ S.unions $ mapMaybe findclusters locs
+ findclusters u = M.lookup (ClusterNodeUUID u) clustermap
{- Is there a location log for the key? True even for keys with no
- remaining locations. -}
-> Annex v
overLocationLogs' iv discarder keyaction = do
config <- Annex.getGitConfig
+ clusters <- getClusters
let getk = locationLogFileKey config
let go v reader = reader >>= \case
ifM (checkDead k)
( go v reader
, do
- !v' <- keyaction k (maybe [] parseLoggedLocations content) v
+ !v' <- keyaction k (maybe [] (parseLoggedLocations clusters) content) v
go v' reader
)
Nothing -> return v
Annex.Branch.overBranchFileContents getk (go iv) >>= \case
Just r -> return r
- Nothing -> giveup "This repository is read-only, and there are unmerged git-annex branches, which prevents operating on all keys. (Set annex.merge-annex-branches to false to ignore the unmerged git-annex branches.)"
+ Nothing -> giveup "This repository is read-only, and there are unmerged git-annex branches, which prevents operating on allu keys. (Set annex.merge-annex-branches to false to ignore the unmerged git-annex branches.)"
* Implement `git-annex updatecluster` command (done)
+* Implement cluster UUID insertation on location log load, and removal
+ on location log store. (done)
+
+* Don't count cluster UUID as a copy. (Including in `whereis` display.)
+
+* Omit cluster UUIDs when constructing drop proofs, since lockcontent will
+ always fail on a cluster.
+
* Basic proxying to special remote support (non-streaming).
* Consider getting instantiated remotes into git remote list.
* Implement upload with fanout and reporting back additional UUIDs over P2P
protocol.
-* Don't count cluster UUID as a copy. (Including in `whereis` display.)
-
-* Implement cluster UUID insertation on location log load, and removal
- on location log store.
-
* Getting a key from a cluster should proxy from one of the nodes that has
it, or from the proxy repository itself if it has the key.
* Implement cluster drops, trying to remove from all nodes, and returning
which UUIDs it was dropped from.
-* Omit cluster UUIDs when constructing drop proofs, since lockcontent will
- always fail on a cluster.
-
* Support proxies-of-proxies better, eg foo-bar-baz.
Currently, it does work, but have to run `git-annex updateproxy`
on foo in order for it to notice the bar-baz proxied remote exists,