Merge branch 'EXTENSIONS'
This commit is contained in:
commit
ed3b03184f
4 changed files with 63 additions and 34 deletions
|
@ -2,6 +2,7 @@ git-annex (6.20180113) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
* inprogress: Avoid showing failures for files not in progress.
|
* inprogress: Avoid showing failures for files not in progress.
|
||||||
* Added INFO to external special remote protocol.
|
* Added INFO to external special remote protocol.
|
||||||
|
* Added EXTENSIONS to external special remote protocol.
|
||||||
|
|
||||||
-- Joey Hess <id@joeyh.name> Wed, 24 Jan 2018 20:42:55 -0400
|
-- Joey Hess <id@joeyh.name> Wed, 24 Jan 2018 20:42:55 -0400
|
||||||
|
|
||||||
|
|
|
@ -505,7 +505,8 @@ withExternalState external = bracket alloc dealloc
|
||||||
|
|
||||||
dealloc st = liftIO $ atomically $ modifyTVar' v (st:)
|
dealloc st = liftIO $ atomically $ modifyTVar' v (st:)
|
||||||
|
|
||||||
{- Starts an external remote process running, and checks VERSION. -}
|
{- Starts an external remote process running, and checks VERSION and
|
||||||
|
- exchanges EXTENSIONS. -}
|
||||||
startExternal :: External -> Annex ExternalState
|
startExternal :: External -> Annex ExternalState
|
||||||
startExternal external = do
|
startExternal external = do
|
||||||
errrelayer <- mkStderrRelayer
|
errrelayer <- mkStderrRelayer
|
||||||
|
@ -514,6 +515,18 @@ startExternal external = do
|
||||||
(const Nothing)
|
(const Nothing)
|
||||||
(checkVersion st external)
|
(checkVersion st external)
|
||||||
(const Nothing)
|
(const Nothing)
|
||||||
|
sendMessage st external (EXTENSIONS supportedExtensionList)
|
||||||
|
-- It responds with a EXTENSIONS_RESPONSE; that extensions list
|
||||||
|
-- is reserved for future expansion. UNSUPPORTED_REQUEST is also
|
||||||
|
-- accepted.
|
||||||
|
receiveMessage st external
|
||||||
|
(\resp -> case resp of
|
||||||
|
EXTENSIONS_RESPONSE _ -> Just (return ())
|
||||||
|
UNSUPPORTED_REQUEST -> Just (return ())
|
||||||
|
_ -> Nothing
|
||||||
|
)
|
||||||
|
(const Nothing)
|
||||||
|
(const Nothing)
|
||||||
return st
|
return st
|
||||||
where
|
where
|
||||||
start errrelayer g = liftIO $ do
|
start errrelayer g = liftIO $ do
|
||||||
|
|
24
Remote/External/Types.hs
vendored
24
Remote/External/Types.hs
vendored
|
@ -1,6 +1,6 @@
|
||||||
{- External special remote data types.
|
{- External special remote data types.
|
||||||
-
|
-
|
||||||
- Copyright 2013 Joey Hess <id@joeyh.name>
|
- Copyright 2013-2018 Joey Hess <id@joeyh.name>
|
||||||
-
|
-
|
||||||
- Licensed under the GNU GPL version 3 or higher.
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
@ -14,6 +14,7 @@ module Remote.External.Types (
|
||||||
ExternalType,
|
ExternalType,
|
||||||
ExternalState(..),
|
ExternalState(..),
|
||||||
PrepareStatus(..),
|
PrepareStatus(..),
|
||||||
|
supportedExtensionList,
|
||||||
Proto.parseMessage,
|
Proto.parseMessage,
|
||||||
Proto.Sendable(..),
|
Proto.Sendable(..),
|
||||||
Proto.Receivable(..),
|
Proto.Receivable(..),
|
||||||
|
@ -80,6 +81,14 @@ data ExternalState = ExternalState
|
||||||
|
|
||||||
type PID = Int
|
type PID = Int
|
||||||
|
|
||||||
|
-- List of extensions to the protocol.
|
||||||
|
newtype ExtensionList = ExtensionList [String]
|
||||||
|
deriving (Show)
|
||||||
|
|
||||||
|
-- When adding a new RemoteRequest, also add it to the list here.
|
||||||
|
supportedExtensionList :: ExtensionList
|
||||||
|
supportedExtensionList = ExtensionList ["INFO"]
|
||||||
|
|
||||||
data PrepareStatus = Unprepared | Prepared | FailedPrepare ErrorMsg
|
data PrepareStatus = Unprepared | Prepared | FailedPrepare ErrorMsg
|
||||||
|
|
||||||
-- The protocol does not support keys with spaces in their names;
|
-- The protocol does not support keys with spaces in their names;
|
||||||
|
@ -107,7 +116,8 @@ instance Proto.Serializable SafeKey where
|
||||||
|
|
||||||
-- Messages that can be sent to the external remote to request it do something.
|
-- Messages that can be sent to the external remote to request it do something.
|
||||||
data Request
|
data Request
|
||||||
= PREPARE
|
= EXTENSIONS ExtensionList
|
||||||
|
| PREPARE
|
||||||
| INITREMOTE
|
| INITREMOTE
|
||||||
| GETCOST
|
| GETCOST
|
||||||
| GETAVAILABILITY
|
| GETAVAILABILITY
|
||||||
|
@ -129,11 +139,13 @@ data Request
|
||||||
-- Does PREPARE need to have been sent before this request?
|
-- Does PREPARE need to have been sent before this request?
|
||||||
needsPREPARE :: Request -> Bool
|
needsPREPARE :: Request -> Bool
|
||||||
needsPREPARE PREPARE = False
|
needsPREPARE PREPARE = False
|
||||||
|
needsPREPARE (EXTENSIONS _) = False
|
||||||
needsPREPARE INITREMOTE = False
|
needsPREPARE INITREMOTE = False
|
||||||
needsPREPARE EXPORTSUPPORTED = False
|
needsPREPARE EXPORTSUPPORTED = False
|
||||||
needsPREPARE _ = True
|
needsPREPARE _ = True
|
||||||
|
|
||||||
instance Proto.Sendable Request where
|
instance Proto.Sendable Request where
|
||||||
|
formatMessage (EXTENSIONS l) = ["EXTENSIONS", Proto.serialize l]
|
||||||
formatMessage PREPARE = ["PREPARE"]
|
formatMessage PREPARE = ["PREPARE"]
|
||||||
formatMessage INITREMOTE = ["INITREMOTE"]
|
formatMessage INITREMOTE = ["INITREMOTE"]
|
||||||
formatMessage GETCOST = ["GETCOST"]
|
formatMessage GETCOST = ["GETCOST"]
|
||||||
|
@ -172,7 +184,8 @@ instance Proto.Sendable Request where
|
||||||
|
|
||||||
-- Responses the external remote can make to requests.
|
-- Responses the external remote can make to requests.
|
||||||
data Response
|
data Response
|
||||||
= PREPARE_SUCCESS
|
= EXTENSIONS_RESPONSE ExtensionList
|
||||||
|
| PREPARE_SUCCESS
|
||||||
| PREPARE_FAILURE ErrorMsg
|
| PREPARE_FAILURE ErrorMsg
|
||||||
| TRANSFER_SUCCESS Direction Key
|
| TRANSFER_SUCCESS Direction Key
|
||||||
| TRANSFER_FAILURE Direction Key ErrorMsg
|
| TRANSFER_FAILURE Direction Key ErrorMsg
|
||||||
|
@ -202,6 +215,7 @@ data Response
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
instance Proto.Receivable Response where
|
instance Proto.Receivable Response where
|
||||||
|
parseCommand "EXTENSIONS" = Proto.parse1 EXTENSIONS_RESPONSE
|
||||||
parseCommand "PREPARE-SUCCESS" = Proto.parse0 PREPARE_SUCCESS
|
parseCommand "PREPARE-SUCCESS" = Proto.parse0 PREPARE_SUCCESS
|
||||||
parseCommand "PREPARE-FAILURE" = Proto.parse1 PREPARE_FAILURE
|
parseCommand "PREPARE-FAILURE" = Proto.parse1 PREPARE_FAILURE
|
||||||
parseCommand "TRANSFER-SUCCESS" = Proto.parse2 TRANSFER_SUCCESS
|
parseCommand "TRANSFER-SUCCESS" = Proto.parse2 TRANSFER_SUCCESS
|
||||||
|
@ -366,3 +380,7 @@ instance Proto.Serializable ExportLocation where
|
||||||
instance Proto.Serializable ExportDirectory where
|
instance Proto.Serializable ExportDirectory where
|
||||||
serialize = fromExportDirectory
|
serialize = fromExportDirectory
|
||||||
deserialize = Just . mkExportDirectory
|
deserialize = Just . mkExportDirectory
|
||||||
|
|
||||||
|
instance Proto.Serializable ExtensionList where
|
||||||
|
serialize (ExtensionList l) = unwords l
|
||||||
|
deserialize = Just . ExtensionList . words
|
||||||
|
|
|
@ -41,9 +41,20 @@ the version of the protocol it is using.
|
||||||
|
|
||||||
VERSION 1
|
VERSION 1
|
||||||
|
|
||||||
Once it knows the version, git-annex will generally
|
Recent versions of git-annex respond with a message indicating
|
||||||
send a message telling the special remote to start up.
|
protocol extensions that it supports. Older versions of
|
||||||
(Or it might send an INITREMOTE or EXPORTSUPPORTED,
|
git-annex do not send this message.
|
||||||
|
|
||||||
|
EXTENSIONS INFO
|
||||||
|
|
||||||
|
The special remote can respond to that with its own EXTENSIONS message, which
|
||||||
|
could have its own protocol extension details, but none are currently used.
|
||||||
|
(It's also fine to reply with UNSUPPORTED-REQUEST.)
|
||||||
|
|
||||||
|
EXTENSIONS
|
||||||
|
|
||||||
|
Next, git-annex will generally send a message telling the special
|
||||||
|
remote to start up. (Or it might send an INITREMOTE or EXPORTSUPPORTED,
|
||||||
so don't hardcode this order.)
|
so don't hardcode this order.)
|
||||||
|
|
||||||
PREPARE
|
PREPARE
|
||||||
|
@ -103,7 +114,7 @@ The following requests *must* all be supported by the special remote.
|
||||||
So any one-time setup tasks should be done idempotently.
|
So any one-time setup tasks should be done idempotently.
|
||||||
* `PREPARE`
|
* `PREPARE`
|
||||||
Tells the remote that it's time to prepare itself to be used.
|
Tells the remote that it's time to prepare itself to be used.
|
||||||
Only INITREMOTE or EXPORTSUPPORTED can come before this.
|
Only EXTENSIONS and INITREMOTE or EXPORTSUPPORTED can come before this.
|
||||||
* `TRANSFER STORE|RETRIEVE Key File`
|
* `TRANSFER STORE|RETRIEVE Key File`
|
||||||
Requests the transfer of a key. For STORE, the File is the file to upload;
|
Requests the transfer of a key. For STORE, the File is the file to upload;
|
||||||
for RETRIEVE the File is where to store the download.
|
for RETRIEVE the File is where to store the download.
|
||||||
|
@ -119,6 +130,10 @@ The following requests *must* all be supported by the special remote.
|
||||||
The following requests can optionally be supported. If not handled,
|
The following requests can optionally be supported. If not handled,
|
||||||
replying with `UNSUPPORTED-REQUEST` is acceptable.
|
replying with `UNSUPPORTED-REQUEST` is acceptable.
|
||||||
|
|
||||||
|
* `EXTENSIONS List`
|
||||||
|
Sent to indicate protocol extensions which git-annex is capable
|
||||||
|
of using. The list is a space-delimited list of protocol extension
|
||||||
|
keywords. The remote can reply to this with its own EXTENSIONS list.
|
||||||
* `GETCOST`
|
* `GETCOST`
|
||||||
Requests the remote to return a use cost. Higher costs are more expensive.
|
Requests the remote to return a use cost. Higher costs are more expensive.
|
||||||
(See Config/Cost.hs for some standard costs.)
|
(See Config/Cost.hs for some standard costs.)
|
||||||
|
@ -229,6 +244,10 @@ while it's handling a request.
|
||||||
the remote didn't have the key at the point removal was requested.
|
the remote didn't have the key at the point removal was requested.
|
||||||
* `REMOVE-FAILURE Key ErrorMsg`
|
* `REMOVE-FAILURE Key ErrorMsg`
|
||||||
Indicates that the key was unable to be removed from the remote.
|
Indicates that the key was unable to be removed from the remote.
|
||||||
|
* `EXTENSIONS List`
|
||||||
|
Sent in response to a EXTENSIONS request, the List could be used to indicate
|
||||||
|
protocol extensions that the special remote uses, but there are currently
|
||||||
|
no such extensions, so the List is empty.
|
||||||
* `COST Int`
|
* `COST Int`
|
||||||
Indicates the cost of the remote.
|
Indicates the cost of the remote.
|
||||||
* `AVAILABILITY GLOBAL|LOCAL`
|
* `AVAILABILITY GLOBAL|LOCAL`
|
||||||
|
@ -402,13 +421,15 @@ handling a request.
|
||||||
* `DEBUG message`
|
* `DEBUG message`
|
||||||
Tells git-annex to display the message if --debug is enabled.
|
Tells git-annex to display the message if --debug is enabled.
|
||||||
(git-annex does not send a reply to this message.)
|
(git-annex does not send a reply to this message.)
|
||||||
|
|
||||||
|
These messages are protocol extensions; it's only safe to send them to
|
||||||
|
git-annex after it sent a EXTENSIONS that included the name of the message.
|
||||||
|
|
||||||
* `INFO message`
|
* `INFO message`
|
||||||
Tells git-annex to display the message to the user.
|
Tells git-annex to display the message to the user.
|
||||||
When git-annex is in --json mode, the message will be emitted immediately
|
When git-annex is in --json mode, the message will be emitted immediately
|
||||||
in its own json object, with an "info" field.
|
in its own json object, with an "info" field.
|
||||||
(git-annex does not send a reply to this message.)
|
(git-annex does not send a reply to this message.)
|
||||||
This message was first supported by git-annex version
|
|
||||||
6.20180206
|
|
||||||
|
|
||||||
## general messages
|
## general messages
|
||||||
|
|
||||||
|
@ -470,27 +491,3 @@ It works like this:
|
||||||
* uuid discovery during INITREMOTE.
|
* uuid discovery during INITREMOTE.
|
||||||
* Hook into webapp. Needs a way to provide some kind of prompt to the user
|
* Hook into webapp. Needs a way to provide some kind of prompt to the user
|
||||||
in the webapp, etc.
|
in the webapp, etc.
|
||||||
|
|
||||||
* When a new "special remote message" is added to this protocol, and a
|
|
||||||
program wants to use it, an old version of git-annex will reject the
|
|
||||||
message as unknown, and fail to use the remote with a protocol error.
|
|
||||||
|
|
||||||
The program can check `git-annex version`, but that's not very
|
|
||||||
satisfactory. Version comparison can be hard and
|
|
||||||
PATH might not point to the same git-annex that's running the program.
|
|
||||||
|
|
||||||
One way to fix this would be to make git-annex reply to VERSION
|
|
||||||
with a PROTOCOLKEYWORDS message listing all the keywords in the
|
|
||||||
protocol that it knows.
|
|
||||||
The program could then check if the new message it wants to send is on
|
|
||||||
the list. PROTOCOLKEYWORDS would be ignored by any program that doesn't
|
|
||||||
care/know about it; programs are required to send UNSUPPORTED-REQUEST.
|
|
||||||
|
|
||||||
I worry that some special remote programs might expect to get only
|
|
||||||
PREPARE or INITREMOTE after VERSION, so this change would break them.
|
|
||||||
I mean, they shouldn't.. But a quickly/badly written one might.
|
|
||||||
Probably want to review all the linked external special remote programs
|
|
||||||
before doing this. Update: Reviewed them all, all are ok.
|
|
||||||
However, datalad's datalad's customremotes/base.py reacts to an unknown
|
|
||||||
request by calling self.error and so seems it would crash if git-annex
|
|
||||||
sent PROTOCOLKEYWORDS..
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue