2024-06-04 18:50:38 +00:00
|
|
|
{- git-annex command
|
|
|
|
-
|
|
|
|
- Copyright 2024 Joey Hess <id@joeyh.name>
|
|
|
|
-
|
|
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
|
|
|
-}
|
|
|
|
|
|
|
|
module Command.UpdateProxy where
|
|
|
|
|
|
|
|
import Command
|
2024-06-14 19:03:20 +00:00
|
|
|
import qualified Annex
|
2024-06-04 18:50:38 +00:00
|
|
|
import Logs.Proxy
|
2024-06-26 15:24:55 +00:00
|
|
|
import Logs.Cluster
|
2024-06-04 18:50:38 +00:00
|
|
|
import Annex.UUID
|
|
|
|
import qualified Remote as R
|
|
|
|
import qualified Types.Remote as R
|
|
|
|
import Utility.SafeOutput
|
|
|
|
|
|
|
|
import qualified Data.Map as M
|
|
|
|
import qualified Data.Set as S
|
|
|
|
|
|
|
|
cmd :: Command
|
|
|
|
cmd = noMessages $ command "updateproxy" SectionSetup
|
|
|
|
"update records with proxy configuration"
|
|
|
|
paramNothing (withParams seek)
|
|
|
|
|
|
|
|
seek :: CmdParams -> CommandSeek
|
|
|
|
seek = withNothing (commandAction start)
|
|
|
|
|
|
|
|
start :: CommandStart
|
|
|
|
start = startingCustomOutput (ActionItemOther Nothing) $ do
|
|
|
|
rs <- R.remoteList
|
2024-06-14 19:03:20 +00:00
|
|
|
let remoteproxies = S.fromList $ map mkproxy $
|
|
|
|
filter (isproxy . R.gitconfig) rs
|
2024-06-26 15:24:55 +00:00
|
|
|
clusterproxies <- getClusterProxies
|
|
|
|
let proxies = S.union remoteproxies clusterproxies
|
2024-06-04 18:50:38 +00:00
|
|
|
u <- getUUID
|
|
|
|
oldproxies <- fromMaybe mempty . M.lookup u <$> getProxies
|
|
|
|
if oldproxies == proxies
|
|
|
|
then liftIO $ putStrLn "No proxy changes to record."
|
|
|
|
else do
|
|
|
|
describechanges oldproxies proxies
|
|
|
|
recordProxies proxies
|
|
|
|
next $ return True
|
|
|
|
where
|
|
|
|
describechanges oldproxies proxies =
|
|
|
|
forM_ (S.toList $ S.union oldproxies proxies) $ \p ->
|
|
|
|
case (S.member p oldproxies, S.member p proxies) of
|
|
|
|
(False, True) -> liftIO $
|
|
|
|
putStrLn $ safeOutput $
|
|
|
|
"Started proxying for " ++ proxyRemoteName p
|
|
|
|
(True, False) -> liftIO $
|
|
|
|
putStrLn $ safeOutput $
|
|
|
|
"Stopped proxying for " ++ proxyRemoteName p
|
|
|
|
_ -> noop
|
2024-06-14 18:21:50 +00:00
|
|
|
|
|
|
|
isproxy c = remoteAnnexProxy c || not (null (remoteAnnexClusterNode c))
|
2024-06-14 19:03:20 +00:00
|
|
|
|
|
|
|
mkproxy r = Proxy (R.uuid r) (R.name r)
|
|
|
|
|
2024-06-26 15:24:55 +00:00
|
|
|
-- Automatically proxy nodes of any cluster this repository is configured
|
|
|
|
-- to serve as a gateway for. Also proxy other cluster nodes that are
|
|
|
|
-- themselves proxied via other remotes.
|
|
|
|
getClusterProxies :: Annex (S.Set Proxy)
|
|
|
|
getClusterProxies = do
|
|
|
|
mynodes <- (map mkclusterproxy . M.toList . annexClusters)
|
|
|
|
<$> Annex.getGitConfig
|
|
|
|
remoteproxiednodes <- findRemoteProxiedClusterNodes
|
|
|
|
let mynodesuuids = S.fromList $ map proxyRemoteUUID mynodes
|
|
|
|
-- filter out nodes we proxy for from the remote proxied nodes
|
|
|
|
-- to avoid cycles
|
|
|
|
let remoteproxiednodes' = filter
|
|
|
|
(\n -> proxyRemoteUUID n `S.notMember` mynodesuuids)
|
|
|
|
remoteproxiednodes
|
|
|
|
return (S.fromList (mynodes ++ remoteproxiednodes'))
|
|
|
|
where
|
2024-06-14 19:03:20 +00:00
|
|
|
mkclusterproxy (remotename, cu) =
|
|
|
|
Proxy (fromClusterUUID cu) remotename
|
2024-06-26 15:24:55 +00:00
|
|
|
|
|
|
|
findRemoteProxiedClusterNodes :: Annex [Proxy]
|
|
|
|
findRemoteProxiedClusterNodes = do
|
|
|
|
myclusters <- (S.fromList . M.elems . annexClusters)
|
|
|
|
<$> Annex.getGitConfig
|
|
|
|
clusternodes <- clusterNodeUUIDs <$> getClusters
|
|
|
|
let isproxiedclusternode r
|
2024-06-26 16:56:16 +00:00
|
|
|
| isJust (remoteAnnexProxiedBy (R.gitconfig r)) =
|
2024-06-26 15:24:55 +00:00
|
|
|
case M.lookup (ClusterNodeUUID (R.uuid r)) clusternodes of
|
|
|
|
Nothing -> False
|
|
|
|
Just s -> not $ S.null $
|
|
|
|
S.intersection s myclusters
|
|
|
|
| otherwise = False
|
|
|
|
(map asproxy . filter isproxiedclusternode)
|
|
|
|
<$> R.remoteList
|
|
|
|
where
|
|
|
|
asproxy r = Proxy (R.uuid r) (R.name r)
|