To enable an existing special remote, the new enableremote command must be used. The initremote command now is used only to create new special remotes.

This commit is contained in:
Joey Hess 2013-04-26 18:22:44 -04:00
parent 9a24728d95
commit 85d83e7756
14 changed files with 141 additions and 52 deletions

View file

@ -69,17 +69,22 @@ makeRsyncRemote name location = makeRemote name location $
, ("type", "rsync") , ("type", "rsync")
] ]
{- Inits a special remote. Currently, only 'weak' ciphers can be {- Inits a new special remote, or enables an existing one.
- generated from the assistant, because otherwise GnuPG may block once -
- the entropy pool is drained, and as of now there's no way to tell the - Currently, only 'weak' ciphers can be generated from the assistant,
- user to perform IO actions to refill the pool. -} - because otherwise GnuPG may block once the entropy pool is drained,
- and as of now there's no way to tell the user to perform IO actions
- to refill the pool. -}
makeSpecialRemote :: String -> RemoteType -> R.RemoteConfig -> Annex () makeSpecialRemote :: String -> RemoteType -> R.RemoteConfig -> Annex ()
makeSpecialRemote name remotetype config = do makeSpecialRemote name remotetype config =
(u, c) <- Command.InitRemote.findByName name go =<< Command.InitRemote.findExisting name
c' <- R.setup remotetype u $ where
M.insert "highRandomQuality" "false" $ M.union config c go Nothing = go =<< Just <$> Command.InitRemote.generateNew name
describeUUID u name go (Just (u, c)) = do
configSet u c' c' <- R.setup remotetype u $
M.insert "highRandomQuality" "false" $ M.union config c
describeUUID u name
configSet u c'
{- Returns the name of the git remote it created. If there's already a {- Returns the name of the git remote it created. If there's already a
- remote at the location, returns its name. -} - remote at the location, returns its name. -}

56
Command/EnableRemote.hs Normal file
View file

@ -0,0 +1,56 @@
{- git-annex command
-
- Copyright 2013 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU GPL version 3 or higher.
-}
module Command.EnableRemote where
import Common.Annex
import Command
import qualified Logs.Remote
import qualified Types.Remote as R
import qualified Command.InitRemote as InitRemote
import qualified Data.Map as M
def :: [Command]
def = [command "enableremote"
(paramPair paramName $ paramOptional $ paramRepeating paramKeyValue)
seek SectionSetup "enables use of an existing special remote"]
seek :: [CommandSeek]
seek = [withWords start]
start :: [String] -> CommandStart
start [] = unknownNameError "Specify the name of the special remote to enable."
start (name:ws) = go =<< InitRemote.findExisting name
where
config = Logs.Remote.keyValToConfig ws
go Nothing = unknownNameError "Unknown special remote name."
go (Just (u, c)) = do
let fullconfig = config `M.union` c
t <- InitRemote.findType fullconfig
showStart "enableremote" name
next $ perform t u fullconfig
unknownNameError :: String -> Annex a
unknownNameError prefix = do
names <- InitRemote.remoteNames
error $ prefix ++
if null names
then ""
else " Known special remotes: " ++ intercalate " " names
perform :: RemoteType -> UUID -> R.RemoteConfig -> CommandPerform
perform t u c = do
c' <- R.setup t u c
next $ cleanup u c'
cleanup :: UUID -> R.RemoteConfig -> CommandCleanup
cleanup u c = do
Logs.Remote.configSet u c
return True

View file

@ -1,6 +1,6 @@
{- git-annex command {- git-annex command
- -
- Copyright 2011 Joey Hess <joey@kitenet.net> - Copyright 2011,2013 Joey Hess <joey@kitenet.net>
- -
- Licensed under the GNU GPL version 3 or higher. - Licensed under the GNU GPL version 3 or higher.
-} -}
@ -23,26 +23,23 @@ import Data.Ord
def :: [Command] def :: [Command]
def = [command "initremote" def = [command "initremote"
(paramPair paramName $ paramOptional $ paramRepeating paramKeyValue) (paramPair paramName $ paramOptional $ paramRepeating paramKeyValue)
seek SectionSetup "sets up a special (non-git) remote"] seek SectionSetup "creates a special (non-git) remote"]
seek :: [CommandSeek] seek :: [CommandSeek]
seek = [withWords start] seek = [withWords start]
start :: [String] -> CommandStart start :: [String] -> CommandStart
start [] = do start [] = error "Specify a name for the remote."
names <- remoteNames start (name:ws) = ifM (isJust <$> findExisting name)
error $ "Specify a name for the remote. " ++ ( error $ "There is already a special remote named \"" ++ name ++
if null names "\". (Use enableremote to enable an existing special remote.)"
then "" , do
else "Either a new name, or one of these existing special remotes: " ++ intercalate " " names (u, c) <- generateNew name
start (name:ws) = do t <- findType config
(u, c) <- findByName name
let fullconfig = config `M.union` c
t <- findType fullconfig
showStart "initremote" name
next $ perform t u name $ M.union config c
showStart "initremote" name
next $ perform t u name $ M.union config c
)
where where
config = Logs.Remote.keyValToConfig ws config = Logs.Remote.keyValToConfig ws
@ -57,21 +54,22 @@ cleanup u name c = do
Logs.Remote.configSet u c Logs.Remote.configSet u c
return True return True
{- Look up existing remote's UUID and config by name, or generate a new one -} {- See if there's an existing special remote with this name. -}
findByName :: String -> Annex (UUID, R.RemoteConfig) findExisting :: String -> Annex (Maybe (UUID, R.RemoteConfig))
findByName name = do findExisting name = do
t <- trustMap t <- trustMap
matches <- sortBy (comparing $ \(u, _c) -> M.lookup u t ) matches <- sortBy (comparing $ \(u, _c) -> M.lookup u t )
. findByName' name . findByName name
<$> Logs.Remote.readRemoteLog <$> Logs.Remote.readRemoteLog
maybe generate return $ headMaybe matches return $ headMaybe matches
where
generate = do
uuid <- liftIO genUUID
return (uuid, M.insert nameKey name M.empty)
findByName' :: String -> M.Map UUID R.RemoteConfig -> [(UUID, R.RemoteConfig)] generateNew :: String -> Annex (UUID, R.RemoteConfig)
findByName' n = filter (matching . snd) . M.toList generateNew name = do
uuid <- liftIO genUUID
return (uuid, M.singleton nameKey name)
findByName :: String -> M.Map UUID R.RemoteConfig -> [(UUID, R.RemoteConfig)]
findByName n = filter (matching . snd) . M.toList
where where
matching c = case M.lookup nameKey c of matching c = case M.lookup nameKey c of
Nothing -> False Nothing -> False

View file

@ -30,6 +30,7 @@ import qualified Command.Fix
import qualified Command.Init import qualified Command.Init
import qualified Command.Describe import qualified Command.Describe
import qualified Command.InitRemote import qualified Command.InitRemote
import qualified Command.EnableRemote
import qualified Command.Fsck import qualified Command.Fsck
import qualified Command.Unused import qualified Command.Unused
import qualified Command.DropUnused import qualified Command.DropUnused
@ -91,6 +92,7 @@ cmds = concat
, Command.Init.def , Command.Init.def
, Command.Describe.def , Command.Describe.def
, Command.InitRemote.def , Command.InitRemote.def
, Command.EnableRemote.def
, Command.Reinject.def , Command.Reinject.def
, Command.Unannex.def , Command.Unannex.def
, Command.Uninit.def , Command.Uninit.def

3
debian/changelog vendored
View file

@ -40,6 +40,9 @@ git-annex (4.20130418) UNRELEASED; urgency=low
its edit page. its edit page.
* Automatically register public urls for files uploaded to the * Automatically register public urls for files uploaded to the
Internet Archive. Internet Archive.
* To enable an existing special remote, the new enableremote command
must be used. The initremote command now is used only to create
new special remotes.
-- Joey Hess <joeyh@debian.org> Thu, 18 Apr 2013 16:22:48 -0400 -- Joey Hess <joeyh@debian.org> Thu, 18 Apr 2013 16:22:48 -0400

View file

@ -31,10 +31,10 @@ non-empty remote.
The [[encryption_design|design/encryption]] allows additional encryption keys The [[encryption_design|design/encryption]] allows additional encryption keys
to be added on to a special remote later. Once a key is added, it is able to be added on to a special remote later. Once a key is added, it is able
to access content that has already been stored in the special remote. to access content that has already been stored in the special remote.
To add a new key, just run `git annex initremote` again, specifying the To add a new key, just run `git annex enableremote` specifying the
new encryption key: new encryption key:
git annex initremote myremote encryption=788A3F4C git annex enableremote myremote encryption=788A3F4C
Note that once a key has been given access to a remote, it's not Note that once a key has been given access to a remote, it's not
possible to revoke that access, short of deleting the remote. See possible to revoke that access, short of deleting the remote. See

View file

@ -236,15 +236,40 @@ subdirectories).
* initremote name [param=value ...] * initremote name [param=value ...]
Sets up a special remote. The remote's Creates a new special remote, and adds it to `.git/config`.
configuration is specified by the parameters. If a remote
with the specified name has already been configured, its configuration The remote's configuration is specified by the parameters. Different
is modified by any values specified. In either case, the remote will be types of special remotes need different configuration values. The
added to `.git/config`. command will prompt for parameters as needed.
All special remotes support encryption. You must either specify
encryption=none to disable encryption, or use encryption=keyid
(or encryption=emailaddress) to specify a gpg key that can access
the encrypted special remote.
Example Amazon S3 remote: Example Amazon S3 remote:
initremote mys3 type=S3 encryption=none datacenter=EU git annex initremote mys3 type=S3 encryption=me@example.com datacenter=EU
* enableremote name [param=value ...]
Enables use of an existing special remote in the current repository,
which may be a different repository than the one in which it was
originally created with the initremote command.
The name of the remote is the same name used when origianlly
creating that remote with "initremote". Run "git annex enableremote"
with no parameters to get a list of special remote names.
Some special remotes may need parameters to be specified every time.
For example, the directory special remote requires a directory= parameter.
This command can also be used to modify the configuration of an existing
special remote, by specifying new values for parameters that were originally
set when using initremote. For example, to add a new gpg key to the keys
that can access an encrypted remote:
git annex initremote mys3 encryption=friend@example.com
* trust [repository ...] * trust [repository ...]

View file

@ -21,7 +21,7 @@ the S3 remote.
every clone of the repository to access the encrypted data (use with caution). every clone of the repository to access the encrypted data (use with caution).
Note that additional gpg keys can be given access to a remote by Note that additional gpg keys can be given access to a remote by
rerunning initremote with the new key id. See [[encryption]]. running enableremote with the new key id. See [[encryption]].
* `embedcreds` - Optional. Set to "yes" embed the login credentials inside * `embedcreds` - Optional. Set to "yes" embed the login credentials inside
the git repository, which allows other clones to also access them. This is the git repository, which allows other clones to also access them. This is

View file

@ -26,7 +26,7 @@ These parameters can be passed to `git annex initremote` to configure bup:
every clone of the repository to access the encrypted data (use with caution). every clone of the repository to access the encrypted data (use with caution).
Note that additional gpg keys can be given access to a remote by Note that additional gpg keys can be given access to a remote by
rerunning initremote with the new key id. See [[encryption]]. running enableremote with the new key id. See [[encryption]].
* `buprepo` - Required. This is passed to `bup` as the `--remote` * `buprepo` - Required. This is passed to `bup` as the `--remote`
to use to store data. To create the repository,`bup init` will be run. to use to store data. To create the repository,`bup init` will be run.

View file

@ -16,7 +16,7 @@ remote:
every clone of the repository to decrypt the encrypted data. every clone of the repository to decrypt the encrypted data.
Note that additional gpg keys can be given access to a remote by Note that additional gpg keys can be given access to a remote by
rerunning initremote with the new key id. See [[encryption]]. running enableremote with the new key id. See [[encryption]].
* `chunksize` - Avoid storing files larger than the specified size in the * `chunksize` - Avoid storing files larger than the specified size in the
directory. For use on directories on mount points that have file size directory. For use on directories on mount points that have file size

View file

@ -27,7 +27,7 @@ the Glacier remote.
every clone of the repository to access the encrypted data (use with caution). every clone of the repository to access the encrypted data (use with caution).
Note that additional gpg keys can be given access to a remote by Note that additional gpg keys can be given access to a remote by
rerunning initremote with the new key id. See [[encryption]]. running enableremote with the new key id. See [[encryption]].
* `embedcreds` - Optional. Set to "yes" embed the login credentials inside * `embedcreds` - Optional. Set to "yes" embed the login credentials inside
the git repository, which allows other clones to also access them. This is the git repository, which allows other clones to also access them. This is

View file

@ -31,7 +31,7 @@ These parameters can be passed to `git annex initremote`:
every clone of the repository to access the encrypted data. every clone of the repository to access the encrypted data.
Note that additional gpg keys can be given access to a remote by Note that additional gpg keys can be given access to a remote by
rerunning initremote with the new key id. See [[encryption]]. running enableremote with the new key id. See [[encryption]].
* `hooktype` - Required. This specifies a collection of hooks to use for * `hooktype` - Required. This specifies a collection of hooks to use for
this remote. this remote.

View file

@ -21,7 +21,7 @@ These parameters can be passed to `git annex initremote` to configure rsync:
every clone of the repository to decrypt the encrypted data. every clone of the repository to decrypt the encrypted data.
Note that additional gpg keys can be given access to a remote by Note that additional gpg keys can be given access to a remote by
rerunning initremote with the new key id. See [[encryption]]. running enableremote with the new key id. See [[encryption]].
* `rsyncurl` - Required. This is the url or `hostname:/directory` to * `rsyncurl` - Required. This is the url or `hostname:/directory` to
pass to rsync to tell it where to store content. pass to rsync to tell it where to store content.
@ -31,7 +31,7 @@ These parameters can be passed to `git annex initremote` to configure rsync:
setups, but not with some hosting providers that do not expose rsynced setups, but not with some hosting providers that do not expose rsynced
filenames to the shell. You'll know you need this option if `git annex get` filenames to the shell. You'll know you need this option if `git annex get`
from the special remote fails with an error message containing a single from the special remote fails with an error message containing a single
quote (`'`) character. If that happens, you can re-run initremote quote (`'`) character. If that happens, you can run enableremote
setting shellescape=no. setting shellescape=no.
The `annex-rsync-options` git configuration setting can be used to pass The `annex-rsync-options` git configuration setting can be used to pass

View file

@ -16,7 +16,7 @@ the webdav remote.
every clone of the repository to access the encrypted data (use with caution). every clone of the repository to access the encrypted data (use with caution).
Note that additional gpg keys can be given access to a remote by Note that additional gpg keys can be given access to a remote by
rerunning initremote with the new key id. See [[encryption]]. running enableremote with the new key id. See [[encryption]].
* `embedcreds` - Optional. Set to "yes" embed the login credentials inside * `embedcreds` - Optional. Set to "yes" embed the login credentials inside
the git repository, which allows other clones to also access them. This is the git repository, which allows other clones to also access them. This is