From 6d967341289220c9b83b1930b32627c69f93ebf1 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 7 Aug 2024 12:27:24 -0400 Subject: [PATCH] updateproxy, updatecluster check annexobjects=yes updateproxy, updatecluster: Prevent using an exporttree=yes special remote that does not have annexobjects=yes, since it will not work. --- CHANGELOG | 2 ++ Command/UpdateCluster.hs | 15 +++++++++++---- Command/UpdateProxy.hs | 33 +++++++++++++++++++++++++++++---- doc/git-annex-updateproxy.mdwn | 9 +++++++++ doc/todo/git-annex_proxies.mdwn | 7 ++++--- 5 files changed, 55 insertions(+), 11 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index e2161f943f..ca00b79261 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -9,6 +9,8 @@ git-annex (10.20240732) UNRELEASED; urgency=medium * post-retrieve: When proxying is enabled for an exporttree=yes special remote and the configured remote.name.annex-tracking-branch is received, the tree is exported to the special remote. + * updateproxy, updatecluster: Prevent using an exporttree=yes special + remote that does not have annexobjects=yes, since it will not work. * git-remote-annex: Store objects in exportree=yes special remotes in the same paths used by annexobjects=yes. * When proxying an upload to a special remote, verify the hash. diff --git a/Command/UpdateCluster.hs b/Command/UpdateCluster.hs index f16318bed0..003ab48ed6 100644 --- a/Command/UpdateCluster.hs +++ b/Command/UpdateCluster.hs @@ -34,10 +34,17 @@ seek = withNothing $ do start :: CommandStart start = startingCustomOutput (ActionItemOther Nothing) $ do rs <- R.remoteList - let getnode r = do - clusternames <- remoteAnnexClusterNode (R.gitconfig r) - return $ M.fromList $ zip clusternames (repeat (S.singleton r)) - let myclusternodes = M.unionsWith S.union (mapMaybe getnode rs) + let getnode r = case remoteAnnexClusterNode (R.gitconfig r) of + Nothing -> return Nothing + Just [] -> return Nothing + Just clusternames -> + ifM (Command.UpdateProxy.checkCanProxy r "Cannot use this special remote as a cluster node.") + ( return $ Just $ M.fromList $ + zip clusternames (repeat (S.singleton r)) + , return Nothing + ) + myclusternodes <- M.unionsWith S.union . catMaybes + <$> mapM getnode rs myclusters <- annexClusters <$> Annex.getGitConfig recordedclusters <- getClusters descs <- R.uuidDescriptions diff --git a/Command/UpdateProxy.hs b/Command/UpdateProxy.hs index ab81199a97..88a8ecaf77 100644 --- a/Command/UpdateProxy.hs +++ b/Command/UpdateProxy.hs @@ -14,6 +14,7 @@ import Logs.Cluster import Annex.UUID import qualified Remote as R import qualified Types.Remote as R +import Annex.SpecialRemote.Config import Utility.SafeOutput import qualified Data.Map as M @@ -30,8 +31,8 @@ seek = withNothing (commandAction start) start :: CommandStart start = startingCustomOutput (ActionItemOther Nothing) $ do rs <- R.remoteList - let remoteproxies = S.fromList $ map mkproxy $ - filter (isproxy . R.gitconfig) rs + remoteproxies <- S.fromList . map mkproxy + <$> filterM isproxy rs clusterproxies <- getClusterProxies remoteproxies let proxies = S.union remoteproxies clusterproxies u <- getUUID @@ -54,9 +55,33 @@ start = startingCustomOutput (ActionItemOther Nothing) $ do "Stopped proxying for " ++ proxyRemoteName p _ -> noop - isproxy c = remoteAnnexProxy c || not (null (remoteAnnexClusterNode c)) - mkproxy r = Proxy (R.uuid r) (R.name r) + + isproxy r + | remoteAnnexProxy (R.gitconfig r) || not (null (remoteAnnexClusterNode (R.gitconfig r))) = + checkCanProxy r "Cannot proxy to this special remote." + | otherwise = pure False + +checkCanProxy :: Remote -> String -> Annex Bool +checkCanProxy r cannotmessage = + ifM (R.isExportSupported r) + ( if annexObjects (R.config r) + then pure True + else do + warnannexobjects + pure False + , pure True + ) + where + warnannexobjects = warning $ UnquotedString $ unwords + [ R.name r + , "is configured with exporttree=yes, but without" + , "annexobjects=yes." + , cannotmessage + , "Suggest you run: git-annex enableremote" + , R.name r + , "annexobjects=yes" + ] -- Automatically proxy nodes of any cluster this repository is configured -- to serve as a gateway for. Also proxy other cluster nodes that are diff --git a/doc/git-annex-updateproxy.mdwn b/doc/git-annex-updateproxy.mdwn index e9b77256c5..ea5adbd5ce 100644 --- a/doc/git-annex-updateproxy.mdwn +++ b/doc/git-annex-updateproxy.mdwn @@ -28,6 +28,14 @@ a proxy. Proxies can only be accessed via ssh or by an annex+http url. +To set up proxying to a special remote that is configured with +exporttree=yes, its necessary for it to also be configured with +annexobjects=yes. And, "remote..annex-tracking-branch" needs to +be configured to the branch that will be exported to the special remote. +When that branch is pushed to the proxy, it will update the tree exported +to the special remote. When files are copied to the remote via the proxy, +it will also update the exported tree. + # OPTIONS * The [[git-annex-common-options]](1) can be used. @@ -36,6 +44,7 @@ Proxies can only be accessed via ssh or by an annex+http url. * [[git-annex]](1) * [[git-annex-updatecluster]](1) +* [[git-annex-export]](1) # AUTHOR diff --git a/doc/todo/git-annex_proxies.mdwn b/doc/todo/git-annex_proxies.mdwn index aa6be63cbe..6dc28249c3 100644 --- a/doc/todo/git-annex_proxies.mdwn +++ b/doc/todo/git-annex_proxies.mdwn @@ -41,9 +41,6 @@ Planned schedule of work: export not supported failed -* Prevent `updateproxy` from enabling an exporttree=yes special remote - that does not have annexobjects=yes, to avoid foot shooting. - * Handle cases where a single key is used by multiple files in the exported tree. Need to download from the special remote in order to export multiple copies to it. (In particular, this is needed when using @@ -69,6 +66,10 @@ Planned schedule of work: * When getting from a P2P HTTP remote, prompt for credentials when required, instead of failing. +* Prevent `updateproxy` and `updatecluster` from adding + an exporttree=yes special remote that does not have + annexobjects=yes, to avoid foot shooting. + ## items deferred until later for p2p protocol over http * `git-annex p2phttp` should support serving several repositories at the same