]> dgit.raspbian.org Git - git-annex.git/commitdiff
implement remove-before
authorJoey Hess <joeyh@joeyh.name>
Wed, 10 Jul 2024 14:03:26 +0000 (10:03 -0400)
committerJoey Hess <joeyh@joeyh.name>
Wed, 10 Jul 2024 14:03:26 +0000 (10:03 -0400)
The reason to use removeBeforeRemoteEndTime is twofold.

First, removeBefore sends two protocol commands. Currently, the HTTP
protocol runner only supports sending a single command per invocation.

Secondly, the http server gets a monotonic timestamp from the client. So
translating back to a POSIXTime would be annoying.

The timestamp flow with a proxy will be:

- client gets timestamp, which gets the monotonic timestamp from the
  proxied remote via the proxy. The timestamp is currently not
  proxied when there is a single proxy.
- client calls remove-before
- http server calls removeBeforeRemoteEndTime which sends REMOVE-BEFORE
  to the proxied remote.

Command/P2PHttp.hs
P2P/Http.hs
P2P/Protocol.hs
doc/design/p2p_protocol_over_http/draft1.mdwn

index 21a85b20c02224d4e4a34cccec36e09f396b9bf8..9e94a93b01304ed29700d1a28f1b6aa25cfb4df9 100644 (file)
@@ -16,6 +16,8 @@ import P2P.Http
 import qualified P2P.Protocol as P2P
 import Annex.Url
 import Utility.Env
+import Utility.ThreadScheduler
+import Utility.MonotonicClock
 
 import qualified Network.Wai.Handler.Warp as Warp
 import Servant
@@ -71,7 +73,7 @@ seek o = startConcurrency commandStages $ do
        -- XXX remove this
        when (isNothing (portOption o)) $ do
                liftIO $ putStrLn "test begins"
-               testRemove
+               testRemoveBefore
                giveup "TEST DONE" 
        withLocalP2PConnections $ \acquireconn -> liftIO $ do
                authenv <- getAuthEnv
@@ -149,7 +151,7 @@ testCheckPresent = do
        burl <- liftIO $ parseBaseUrl "http://localhost:8080/"
        res <- liftIO $ clientCheckPresent (mkClientEnv mgr burl)
                (P2P.ProtocolVersion 3)
-               (B64Key (fromJust $ deserializeKey ("WORM-s30-m1720547401--foo" :: String)))
+               (B64Key (fromJust $ deserializeKey ("WORM-s30-m1720617630--bar" :: String)))
                (B64UUID (toUUID ("cu" :: String)))
                (B64UUID (toUUID ("f11773f0-11e1-45b2-9805-06db16768efe" :: String)))
                []
@@ -168,3 +170,20 @@ testRemove = do
                Nothing
        liftIO $ print res
 
+testRemoveBefore = do
+       mgr <- httpManager <$> getUrlOptions
+       burl <- liftIO $ parseBaseUrl "http://localhost:8080/"
+       MonotonicTimestamp t <- liftIO currentMonotonicTimestamp
+       --liftIO $ threadDelaySeconds (Seconds 10)
+       let ts = MonotonicTimestamp (t + 10)
+       liftIO $ print ("running with timestamp", ts)
+       res <- liftIO $ clientRemoveBefore (mkClientEnv mgr burl)
+               (P2P.ProtocolVersion 3)
+               (B64Key (fromJust $ deserializeKey ("WORM-s30-m1720617630--bar" :: String)))
+               (B64UUID (toUUID ("cu" :: String)))
+               (B64UUID (toUUID ("f11773f0-11e1-45b2-9805-06db16768efe" :: String)))
+               []
+               (Timestamp ts)
+               Nothing
+       liftIO $ print res
+
index aeb3d131bf77d6cd63690c6c48bce20d38c5c24b..08bb85dad4e172e33d4b3ff8e515f89895cde4a3 100644 (file)
@@ -111,7 +111,7 @@ serveP2pHttp st
 type GetGenericAPI = StreamGet NoFraming OctetStream (SourceIO B.ByteString)
 
 serveGetGeneric :: P2PHttpServerState -> B64Key -> Handler (S.SourceT IO B.ByteString)
-serveGetGeneric = undefined
+serveGetGeneric = undefined -- TODO
 
 type GetAPI
        = ClientUUID Optional
@@ -135,7 +135,7 @@ serveGet
        -> Maybe Offset
        -> Maybe Auth
        -> Handler (Headers '[DataLengthHeader] (S.SourceT IO B.ByteString))
-serveGet = undefined
+serveGet = undefined -- TODO
 
 clientGet
        :: ProtocolVersion
@@ -234,8 +234,8 @@ serveRemove st resultmangle apiver (B64Key k) cu su bypass sec auth = do
                $ \runst conn ->
                        liftIO $ runNetProto runst conn $ remove Nothing k
        case res of
-               (Right b, plus) -> return $ resultmangle $ 
-                       RemoveResultPlus b (map B64UUID (fromMaybe [] plus))
+               (Right b, plusuuids) -> return $ resultmangle $ 
+                       RemoveResultPlus b (map B64UUID (fromMaybe [] plusuuids))
                (Left err, _) -> throwError $
                        err500 { errBody = encodeBL err }
 
@@ -270,7 +270,9 @@ type RemoveBeforeAPI
        :> ServerUUID Required
        :> BypassUUIDs
        :> QueryParam' '[Required] "timestamp" Timestamp
-       :> Post '[JSON] RemoveResult
+       :> IsSecure
+       :> AuthHeader
+       :> Post '[JSON] RemoveResultPlus
 
 serveRemoveBefore
        :: APIVersion v
@@ -281,27 +283,44 @@ serveRemoveBefore
        -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> Timestamp
-       -> Handler RemoveResult
-serveRemoveBefore = undefined
+       -> IsSecure
+       -> Maybe Auth
+       -> Handler RemoveResultPlus
+serveRemoveBefore st apiver (B64Key k) cu su bypass (Timestamp ts) sec auth = do
+       res <- withP2PConnection apiver st cu su bypass sec auth RemoveAction
+               $ \runst conn ->
+                       liftIO $ runNetProto runst conn $
+                               removeBeforeRemoteEndTime ts k
+       case res of
+               (Right b, plusuuids) -> return $ 
+                       RemoveResultPlus b (map B64UUID (fromMaybe [] plusuuids))
+               (Left err, _) -> throwError $
+                       err500 { errBody = encodeBL err }
 
 clientRemoveBefore
-       :: ProtocolVersion
+       :: ClientEnv
+       -> ProtocolVersion
        -> B64Key
        -> B64UUID ClientSide
        -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> Timestamp
-       -> ClientM RemoveResult
-clientRemoveBefore (ProtocolVersion ver) = case ver of
-       3 -> v3 V3
-       _ -> error "unsupported protocol version"
+       -> Maybe Auth
+       -> IO RemoveResultPlus
+clientRemoveBefore clientenv (ProtocolVersion ver) key cu su bypass ts auth =
+       withClientM (cli key cu su bypass ts auth) clientenv $ \case
+               Left err -> throwM err
+               Right res -> return res
   where
+       cli = case ver of
+               3 -> v3 V3
+               _ -> error "unsupported protocol version"
+       
        _ :<|> _ :<|> _ :<|> _ :<|>
                _ :<|> _ :<|> _ :<|> _ :<|>
                _ :<|> _ :<|> _ :<|> _ :<|>
                v3 :<|> _ = client p2pHttpAPI
 
-
 type GetTimestampAPI
        = ClientUUID Required
        :> ServerUUID Required
@@ -316,7 +335,7 @@ serveGetTimestamp
        -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> Handler GetTimestampResult
-serveGetTimestamp = undefined
+serveGetTimestamp = undefined -- TODO
 
 clientGetTimestamp
        :: ProtocolVersion
@@ -360,7 +379,7 @@ servePut
        -> DataLength
        -> S.SourceT IO B.ByteString
        -> Handler t
-servePut = undefined
+servePut = undefined -- TODO
 
 clientPut
        :: ProtocolVersion
@@ -405,7 +424,7 @@ servePutOffset
        -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> Handler t
-servePutOffset = undefined
+servePutOffset = undefined -- TODO
 
 clientPutOffset
        :: ProtocolVersion
@@ -443,7 +462,7 @@ serveLockContent
        -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> Handler LockResult
-serveLockContent = undefined
+serveLockContent = undefined -- TODO
 
 clientLockContent
        :: ProtocolVersion
index 9dcbdba01642e2187d6a5d3ac352993249f00f5b..79fcc24bfb78a4d5f29da23a5983ab9427bfef00 100644 (file)
@@ -437,15 +437,18 @@ removeBefore endtime key = do
                        let remoteendtime = remotetime + timeleft'
                        if timeleft <= 0
                                then return (Right False, Nothing)
-                               else do
-                                       net $ sendMessage $
-                                               REMOVE_BEFORE remoteendtime key
-                                       checkSuccessFailurePlus 
+                               else removeBeforeRemoteEndTime remoteendtime key
                Just (ERROR err) -> return (Left err, Nothing)
                _ -> do
                        net $ sendMessage (ERROR "expected TIMESTAMP")
                        return (Right False, Nothing)
 
+removeBeforeRemoteEndTime :: MonotonicTimestamp -> Key -> Proto (Either String Bool, Maybe [UUID])
+removeBeforeRemoteEndTime remoteendtime key = do
+       net $ sendMessage $
+               REMOVE_BEFORE remoteendtime key
+       checkSuccessFailurePlus 
+
 get :: FilePath -> Key -> Maybe IncrementalVerifier -> AssociatedFile -> Meter -> MeterUpdate -> Proto (Bool, Verification)
 get dest key iv af m p = 
        receiveContent (Just m) p sizer storer $ \offset ->
index 891684c7698e21f353793099d104ce4337a87e66..c8f9975769f208156f2bb0e53a65e4c31924d1cb 100644 (file)
@@ -272,10 +272,6 @@ or false if the key was not able to be removed.
 The JSON object can have an additional field "plusuuids" that is a list of
 UUIDs of other repositories that the content was removed from.
 
-If the server does not allow removing the key due to a policy
-(eg due to being read-only or append-only), it will respond with a JSON
-object with an "error" field that has an error message as its value.
-
 ### POST /git-annex/v2/remove
 
 Identical to v3.
@@ -362,17 +358,11 @@ should not be used. This can happen when eg, the data was being sent from
 an unlocked annexed file, which got modified while it was being sent.
 
 The server responds with a JSON object with a field "stored"
-that is true if it received the data and stored the
-content.
+that is true if it received the data and stored the content.
 
 The JSON object can have an additional field "plusuuids" that is a list of
 UUIDs of other repositories that the content was stored to.
 
-If the server does not allow storing the key due eg to a policy
-(eg due to being read-only or append-only), or due to the data being
-invalid, or because it ran out of disk space, it will respond with a
-JSON object with an "error" field that has an error message as its value.
-
 ### POST /git-annex/v2/put
 
 Identical to v3.
@@ -412,10 +402,6 @@ object may also have a field "plusuuids" that lists
 the UUIDs of other repositories where the content is stored, in addition to
 the serveruuid.
 
-If the server does not allow storing the key due to a policy
-(eg due to being read-only or append-only), it will respond with a JSON
-object with an "error" field that has an error message as its value.
-
 [Implementation note: This will be implemented by sending `PUT` and
 returning the `PUT-FROM` offset. To avoid leaving the P2P protocol stuck
 part way through a `PUT`, a synthetic empty `DATA` followed by `INVALID`