Added ways to configure rsync options to be used only when uploading or downloading from a remote. Useful to eg limit upload bandwidth.

This commit is contained in:
Joey Hess 2014-02-02 16:06:34 -04:00
parent 9e4675d3c8
commit 089c0109a2
7 changed files with 60 additions and 21 deletions

View file

@ -310,7 +310,7 @@ copyFromRemote r key file dest _p = copyFromRemote' r key file dest
copyFromRemote' :: Remote -> Key -> AssociatedFile -> FilePath -> Annex Bool copyFromRemote' :: Remote -> Key -> AssociatedFile -> FilePath -> Annex Bool
copyFromRemote' r key file dest copyFromRemote' r key file dest
| not $ Git.repoIsUrl (repo r) = guardUsable (repo r) False $ do | not $ Git.repoIsUrl (repo r) = guardUsable (repo r) False $ do
let params = Ssh.rsyncParams r let params = Ssh.rsyncParams r Download
u <- getUUID u <- getUUID
-- run copy from perspective of remote -- run copy from perspective of remote
liftIO $ onLocal (repo r) $ do liftIO $ onLocal (repo r) $ do
@ -409,7 +409,7 @@ copyToRemote r key file p
-- the remote's Annex, but it needs access to the current -- the remote's Annex, but it needs access to the current
-- Annex monad's state. -- Annex monad's state.
checksuccessio <- Annex.withCurrentState checksuccess checksuccessio <- Annex.withCurrentState checksuccess
let params = Ssh.rsyncParams r let params = Ssh.rsyncParams r Upload
u <- getUUID u <- getUUID
-- run copy from perspective of remote -- run copy from perspective of remote
liftIO $ onLocal (repo r) $ ifM (Annex.Content.inAnnex key) liftIO $ onLocal (repo r) $ ifM (Annex.Content.inAnnex key)

View file

@ -122,7 +122,7 @@ rsyncParamsRemote direct r direction key file afile = do
fields fields
-- Convert the ssh command into rsync command line. -- Convert the ssh command into rsync command line.
let eparam = rsyncShell (Param shellcmd:shellparams) let eparam = rsyncShell (Param shellcmd:shellparams)
let o = rsyncParams r let o = rsyncParams r direction
return $ if direction == Download return $ if direction == Download
then o ++ rsyncopts eparam dummy (File file) then o ++ rsyncopts eparam dummy (File file)
else o ++ rsyncopts eparam (File file) dummy else o ++ rsyncopts eparam (File file) dummy
@ -140,7 +140,11 @@ rsyncParamsRemote direct r direction key file afile = do
dummy = Param "dummy:" dummy = Param "dummy:"
-- --inplace to resume partial files -- --inplace to resume partial files
rsyncParams :: Remote -> [CommandParam] rsyncParams :: Remote -> Direction -> [CommandParam]
rsyncParams r = Params "--progress --inplace" : rsyncParams r direction = Params "--progress --inplace" :
map Param (remoteAnnexRsyncOptions $ gitconfig r) map Param (remoteAnnexRsyncOptions gc ++ dps)
where
dps
| direction == Download = remoteAnnexRsyncDownloadOptions gc
| otherwise = remoteAnnexRsyncUploadOptions gc
gc = gitconfig r

View file

@ -41,12 +41,15 @@ import Utility.Rsync
import Utility.CopyFile import Utility.CopyFile
import Utility.Metered import Utility.Metered
import Annex.Perms import Annex.Perms
import Logs.Transfer
type RsyncUrl = String type RsyncUrl = String
data RsyncOpts = RsyncOpts data RsyncOpts = RsyncOpts
{ rsyncUrl :: RsyncUrl { rsyncUrl :: RsyncUrl
, rsyncOptions :: [CommandParam] , rsyncOptions :: [CommandParam]
, rsyncUploadOptions :: [CommandParam]
, rsyncDownloadOptions :: [CommandParam]
, rsyncShellEscape :: Bool , rsyncShellEscape :: Bool
} }
@ -93,10 +96,16 @@ gen r u c gc = do
} }
genRsyncOpts :: RemoteConfig -> RemoteGitConfig -> [CommandParam] -> RsyncUrl -> RsyncOpts genRsyncOpts :: RemoteConfig -> RemoteGitConfig -> [CommandParam] -> RsyncUrl -> RsyncOpts
genRsyncOpts c gc transport url = RsyncOpts url (transport ++ opts) escape genRsyncOpts c gc transport url = RsyncOpts
{ rsyncUrl = url
, rsyncOptions = opts []
, rsyncUploadOptions = transport ++ opts (remoteAnnexRsyncUploadOptions gc)
, rsyncDownloadOptions = transport ++ opts (remoteAnnexRsyncDownloadOptions gc)
, rsyncShellEscape = M.lookup "shellescape" c /= Just "no"
}
where where
opts = map Param $ filter safe $ remoteAnnexRsyncOptions gc opts specificopts = map Param $ filter safe $
escape = M.lookup "shellescape" c /= Just "no" remoteAnnexRsyncOptions gc ++ specificopts
safe opt safe opt
-- Don't allow user to pass --delete to rsync; -- Don't allow user to pass --delete to rsync;
-- that could cause it to delete other keys -- that could cause it to delete other keys
@ -257,7 +266,7 @@ withRsyncScratchDir a = do
rsyncRetrieve :: RsyncOpts -> Key -> FilePath -> Maybe MeterUpdate -> Annex Bool rsyncRetrieve :: RsyncOpts -> Key -> FilePath -> Maybe MeterUpdate -> Annex Bool
rsyncRetrieve o k dest callback = rsyncRetrieve o k dest callback =
showResumable $ untilTrue (rsyncUrls o k) $ \u -> rsyncRemote o callback showResumable $ untilTrue (rsyncUrls o k) $ \u -> rsyncRemote Download o callback
-- use inplace when retrieving to support resuming -- use inplace when retrieving to support resuming
[ Param "--inplace" [ Param "--inplace"
, Param u , Param u
@ -272,13 +281,15 @@ showResumable a = ifM a
return False return False
) )
rsyncRemote :: RsyncOpts -> Maybe MeterUpdate -> [CommandParam] -> Annex Bool rsyncRemote :: Direction -> RsyncOpts -> Maybe MeterUpdate -> [CommandParam] -> Annex Bool
rsyncRemote o callback params = do rsyncRemote direction o callback params = do
showOutput -- make way for progress bar showOutput -- make way for progress bar
liftIO $ (maybe rsync rsyncProgress callback) ps liftIO $ (maybe rsync rsyncProgress callback) $
opts ++ [Params "--progress"] ++ params
where where
defaultParams = [Params "--progress"] opts
ps = rsyncOptions o ++ defaultParams ++ params | direction == Download = rsyncDownloadOptions o
| otherwise = rsyncUploadOptions o
{- To send a single key is slightly tricky; need to build up a temporary {- To send a single key is slightly tricky; need to build up a temporary
- directory structure to pass to rsync so it can create the hash - directory structure to pass to rsync so it can create the hash
@ -301,7 +312,7 @@ rsyncSend o callback k canrename src = withRsyncScratchDir $ \tmp -> do
else createLinkOrCopy src dest else createLinkOrCopy src dest
ps <- sendParams ps <- sendParams
if ok if ok
then showResumable $ rsyncRemote o (Just callback) $ ps ++ then showResumable $ rsyncRemote Upload o (Just callback) $ ps ++
[ Param "--recursive" [ Param "--recursive"
, partialParams , partialParams
-- tmp/ to send contents of tmp dir -- tmp/ to send contents of tmp dir

View file

@ -115,6 +115,8 @@ data RemoteGitConfig = RemoteGitConfig
- including special remotes. -} - including special remotes. -}
, remoteAnnexSshOptions :: [String] , remoteAnnexSshOptions :: [String]
, remoteAnnexRsyncOptions :: [String] , remoteAnnexRsyncOptions :: [String]
, remoteAnnexRsyncUploadOptions :: [String]
, remoteAnnexRsyncDownloadOptions :: [String]
, remoteAnnexRsyncTransport :: [String] , remoteAnnexRsyncTransport :: [String]
, remoteAnnexGnupgOptions :: [String] , remoteAnnexGnupgOptions :: [String]
, remoteAnnexRsyncUrl :: Maybe String , remoteAnnexRsyncUrl :: Maybe String
@ -144,6 +146,8 @@ extractRemoteGitConfig r remotename = RemoteGitConfig
, remoteAnnexSshOptions = getoptions "ssh-options" , remoteAnnexSshOptions = getoptions "ssh-options"
, remoteAnnexRsyncOptions = getoptions "rsync-options" , remoteAnnexRsyncOptions = getoptions "rsync-options"
, remoteAnnexRsyncDownloadOptions = getoptions "rsync-download-options"
, remoteAnnexRsyncUploadOptions = getoptions "rsync-upload-options"
, remoteAnnexRsyncTransport = getoptions "rsync-transport" , remoteAnnexRsyncTransport = getoptions "rsync-transport"
, remoteAnnexGnupgOptions = getoptions "gnupg-options" , remoteAnnexGnupgOptions = getoptions "gnupg-options"
, remoteAnnexRsyncUrl = notempty $ getmaybe "rsyncurl" , remoteAnnexRsyncUrl = notempty $ getmaybe "rsyncurl"

2
debian/changelog vendored
View file

@ -12,6 +12,8 @@ git-annex (5.20140128) UNRELEASED; urgency=medium
* sync --content: Re-pull from remotes after downloading content, * sync --content: Re-pull from remotes after downloading content,
since that can take a while and other changes may be pushed in the since that can take a while and other changes may be pushed in the
meantime. meantime.
* Added ways to configure rsync options to be used only when uploading
or downloading from a remote. Useful to eg limit upload bandwidth.
-- Joey Hess <joeyh@debian.org> Tue, 28 Jan 2014 13:57:19 -0400 -- Joey Hess <joeyh@debian.org> Tue, 28 Jan 2014 13:57:19 -0400

View file

@ -1379,6 +1379,21 @@ Here are all the supported configuration settings.
to or from this remote. For example, to force ipv6, and limit to or from this remote. For example, to force ipv6, and limit
the bandwidth to 100Kbyte/s, set it to `-6 --bwlimit 100` the bandwidth to 100Kbyte/s, set it to `-6 --bwlimit 100`
* `remote.<name>.annex-rsync-upload-options`
Options to use when using rsync to upload a file to a remote.
These options are passed after other applicable rsync options,
so can be used to override them. For example, to limit upload bandwidth
to 10Kbye/s, set `--bwlimit 10`.
* `remote.<name>.annex-rsync-download-options`
Options to use when using rsync to download a file from a remote.
These options are passed after other applicable rsync options,
so can be used to override them.
* `remote.<name>.annex-rsync-transport` * `remote.<name>.annex-rsync-transport`
The remote shell to use to connect to the rsync remote. Possible The remote shell to use to connect to the rsync remote. Possible
@ -1402,11 +1417,12 @@ Here are all the supported configuration settings.
precedence over the default GnuPG configuration, which is otherwise precedence over the default GnuPG configuration, which is otherwise
used.) used.)
* `annex.ssh-options`, `annex.rsync-options`, `annex.bup-split-options`, * `annex.ssh-options`, `annex.rsync-options`,
`annex.gnupg-options` `annex.rsync-upload-options`, `annex.rsync-download-options`,
`annex.bup-split-options`, `annex.gnupg-options`
Default ssh, rsync, wget/curl, bup, and GnuPG options to use if a Default options to use if a remote does not have more specific options
remote does not have specific options. as described above.
* `annex.web-options` * `annex.web-options`

View file

@ -1,2 +1,4 @@
The bandwidth for upload and download are often different. It would be useful to have different settings for upload and download limits. The bandwidth for upload and download are often different. It would be useful to have different settings for upload and download limits.
As it is, I have to keep changing annex-rsync-options options between uploads and downloads. As it is, I have to keep changing annex-rsync-options options between uploads and downloads.
> [[done]] --[[Joey]]