support chunking for all external special remotes!

Removing code and at the same time adding great features, including
upload/download resuming.

This commit was sponsored by Romain Lenglet.
This commit is contained in:
Joey Hess 2014-07-29 18:47:26 -04:00
parent bc9e4697b9
commit c0dc134cde
3 changed files with 15 additions and 50 deletions

View file

@ -15,14 +15,12 @@ import Types.CleanupActions
import qualified Git import qualified Git
import Config import Config
import Remote.Helper.Special import Remote.Helper.Special
import Remote.Helper.Encryptable import Remote.Helper.ChunkedEncryptable
import Crypto
import Utility.Metered import Utility.Metered
import Logs.Transfer import Logs.Transfer
import Logs.PreferredContent.Raw import Logs.PreferredContent.Raw
import Logs.RemoteState import Logs.RemoteState
import Config.Cost import Config.Cost
import Annex.Content
import Annex.UUID import Annex.UUID
import Annex.Exception import Annex.Exception
import Creds import Creds
@ -30,7 +28,6 @@ import Creds
import Control.Concurrent.STM import Control.Concurrent.STM
import System.Log.Logger (debugM) import System.Log.Logger (debugM)
import qualified Data.Map as M import qualified Data.Map as M
import qualified Data.ByteString.Lazy as L
remote :: RemoteType remote :: RemoteType
remote = RemoteType { remote = RemoteType {
@ -46,15 +43,15 @@ gen r u c gc = do
Annex.addCleanup (RemoteCleanup u) $ stopExternal external Annex.addCleanup (RemoteCleanup u) $ stopExternal external
cst <- getCost external r gc cst <- getCost external r gc
avail <- getAvailability external r gc avail <- getAvailability external r gc
return $ Just $ encryptableRemote c return $ Just $ chunkedEncryptableRemote c
(storeEncrypted external $ getGpgEncParams (c,gc)) (simplyPrepare $ store external)
(retrieveEncrypted external) (simplyPrepare $ retrieve external)
Remote { Remote {
uuid = u, uuid = u,
cost = cst, cost = cst,
name = Git.repoDescribe r, name = Git.repoDescribe r,
storeKey = store external, storeKey = storeKeyDummy,
retrieveKeyFile = retrieve external, retrieveKeyFile = retreiveKeyFileDummy,
retrieveKeyFileCheap = \_ _ -> return False, retrieveKeyFileCheap = \_ _ -> return False,
removeKey = remove external, removeKey = remove external,
hasKey = checkPresent external, hasKey = checkPresent external,
@ -90,25 +87,8 @@ externalSetup mu _ c = do
gitConfigSpecialRemote u c'' "externaltype" externaltype gitConfigSpecialRemote u c'' "externaltype" externaltype
return (c'', u) return (c'', u)
store :: External -> Key -> AssociatedFile -> MeterUpdate -> Annex Bool store :: External -> Storer
store external k _f p = sendAnnex k rollback $ \f -> store external = fileStorer $ \k f p ->
metered (Just p) k $
storeHelper external k f
where
rollback = void $ remove external k
storeEncrypted :: External -> [CommandParam] -> (Cipher, Key) -> Key -> MeterUpdate -> Annex Bool
storeEncrypted external gpgOpts (cipher, enck) k p = withTmp enck $ \tmp ->
sendAnnex k rollback $ \src -> do
metered (Just p) k $ \meterupdate -> do
liftIO $ encrypt gpgOpts cipher (feedFile src) $
readBytes $ L.writeFile tmp
storeHelper external enck tmp meterupdate
where
rollback = void $ remove external enck
storeHelper :: External -> Key -> FilePath -> MeterUpdate -> Annex Bool
storeHelper external k f p = safely $
handleRequest external (TRANSFER Upload k f) (Just p) $ \resp -> handleRequest external (TRANSFER Upload k f) (Just p) $ \resp ->
case resp of case resp of
TRANSFER_SUCCESS Upload k' | k == k' -> TRANSFER_SUCCESS Upload k' | k == k' ->
@ -119,31 +99,15 @@ storeHelper external k f p = safely $
return False return False
_ -> Nothing _ -> Nothing
retrieve :: External -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Bool retrieve :: External -> Retriever
retrieve external k _f d p = metered (Just p) k $ retrieve external = fileRetriever $ \d k p ->
retrieveHelper external k d
retrieveEncrypted :: External -> (Cipher, Key) -> Key -> FilePath -> MeterUpdate -> Annex Bool
retrieveEncrypted external (cipher, enck) k f p = withTmp enck $ \tmp ->
metered (Just p) k $ \meterupdate ->
ifM (retrieveHelper external enck tmp meterupdate)
( liftIO $ catchBoolIO $ do
decrypt cipher (feedFile tmp) $
readBytes $ L.writeFile f
return True
, return False
)
retrieveHelper :: External -> Key -> FilePath -> MeterUpdate -> Annex Bool
retrieveHelper external k d p = safely $
handleRequest external (TRANSFER Download k d) (Just p) $ \resp -> handleRequest external (TRANSFER Download k d) (Just p) $ \resp ->
case resp of case resp of
TRANSFER_SUCCESS Download k' TRANSFER_SUCCESS Download k'
| k == k' -> Just $ return True | k == k' -> Just $ return ()
TRANSFER_FAILURE Download k' errmsg TRANSFER_FAILURE Download k' errmsg
| k == k' -> Just $ do | k == k' -> Just $ do
warning errmsg error errmsg
return False
_ -> Nothing _ -> Nothing
remove :: External -> Key -> Annex Bool remove :: External -> Key -> Annex Bool

View file

@ -295,7 +295,7 @@ retrieveChunks retriever u chunkconfig encryptor basek dest basep sink
return True return True
tosink h _ (FileContent f) = liftIO $ do tosink h _ (FileContent f) = liftIO $ do
sink h Nothing =<< L.readFile f sink h Nothing =<< L.readFile f
nukeFile h nukeFile f
return True return True
{- Can resume when the chunk's offset is at or before the end of {- Can resume when the chunk's offset is at or before the end of

3
debian/changelog vendored
View file

@ -1,6 +1,7 @@
git-annex (5.20140718) UNRELEASED; urgency=medium git-annex (5.20140718) UNRELEASED; urgency=medium
* New chunk= option to chunk files stored in directory remotes. * New chunk= option to chunk files stored in special remotes.
Currently supported by: directory, and all external special remotes.
* Partially transferred files are automatically resumed when using * Partially transferred files are automatically resumed when using
chunked remotes! chunked remotes!
* The old chunksize= option is deprecated. Do not use for new remotes. * The old chunksize= option is deprecated. Do not use for new remotes.