2013-12-26 22:14:52 +00:00
|
|
|
Communication between git-annex and a program implementing an external
|
|
|
|
special remote uses this protocol.
|
2013-12-11 17:31:11 +00:00
|
|
|
|
2013-12-26 22:14:52 +00:00
|
|
|
[[!toc]]
|
|
|
|
|
|
|
|
## starting the program
|
2013-12-11 17:31:11 +00:00
|
|
|
|
2013-12-11 21:20:34 +00:00
|
|
|
The external special remote program has a name like
|
2013-12-26 22:14:52 +00:00
|
|
|
`git-annex-remote-$bar`. When
|
|
|
|
`git annex initremote foo type=external externaltype=$bar` is run,
|
2013-12-11 21:20:34 +00:00
|
|
|
git-annex finds the appropriate program in PATH.
|
2013-12-11 17:31:11 +00:00
|
|
|
|
|
|
|
The program is started by git-annex when it needs to access the special
|
|
|
|
remote, and may be left running for a long period of time. This allows
|
|
|
|
it to perform expensive setup tasks, etc. Note that git-annex may choose to
|
|
|
|
start multiple instances of the program (eg, when multiple git-annex
|
|
|
|
commands are run concurrently in a repository).
|
|
|
|
|
2013-12-11 21:20:34 +00:00
|
|
|
## protocol overview
|
|
|
|
|
|
|
|
Communication is via stdin and stdout. Therefore, the external special
|
|
|
|
remote must avoid doing any prompting, or outputting anything like eg,
|
|
|
|
progress to stdout. (Such stuff can be sent to stderr instead.)
|
2013-12-11 17:31:11 +00:00
|
|
|
|
|
|
|
The protocol is line based. Messages are sent in either direction, from
|
2013-12-11 21:20:34 +00:00
|
|
|
git-annex to the special remote, and from the special remote to git-annex.
|
|
|
|
|
2013-12-16 15:36:19 +00:00
|
|
|
In order to avoid confusing interactions, one or the other has control
|
|
|
|
at any given time, and is responsible for sending requests, while the other
|
|
|
|
only sends replies to the requests.
|
|
|
|
|
2013-12-27 16:04:51 +00:00
|
|
|
Each protocol line starts with a command, which is followed by the
|
|
|
|
command's parameters (a fixed number per command), each separated by a
|
|
|
|
single space. The last parameter may contain spaces. Parameters may be
|
|
|
|
empty, but the separating spaces are still required in that case.
|
|
|
|
|
2013-12-11 21:20:34 +00:00
|
|
|
## example session
|
|
|
|
|
|
|
|
The special remote is responsible for sending the first message, indicating
|
|
|
|
the version of the protocol it is using.
|
|
|
|
|
2013-12-26 22:14:52 +00:00
|
|
|
VERSION 1
|
2013-12-11 21:20:34 +00:00
|
|
|
|
2018-02-07 19:02:12 +00:00
|
|
|
Recent versions of git-annex respond with a message indicating
|
|
|
|
protocol extensions that it supports. Older versions of
|
2020-08-11 20:42:09 +00:00
|
|
|
git-annex do not send this message.
|
2018-02-07 19:02:12 +00:00
|
|
|
|
2021-01-26 16:42:47 +00:00
|
|
|
EXTENSIONS INFO ASYNC GETGITREMOTENAME
|
2018-02-07 19:02:12 +00:00
|
|
|
|
2020-08-11 20:42:09 +00:00
|
|
|
The special remote can respond to that with its own EXTENSIONS message, listing
|
|
|
|
any extensions it wants to use.
|
2018-02-07 19:02:12 +00:00
|
|
|
(It's also fine to reply with UNSUPPORTED-REQUEST.)
|
|
|
|
|
|
|
|
EXTENSIONS
|
|
|
|
|
|
|
|
Next, git-annex will generally send a message telling the special
|
add LISTCONFIGS to external special remote protocol
Special remote programs that use GETCONFIG/SETCONFIG are recommended
to implement it.
The description is not yet used, but will be useful later when adding a way
to make initremote list all accepted configs.
configParser now takes a RemoteConfig parameter. Normally, that's not
needed, because configParser returns a parter, it does not parse it
itself. But, it's needed to look at externaltype and work out what
external remote program to run for LISTCONFIGS.
Note that, while externalUUID is changed to a Maybe UUID, checkExportSupported
used to use NoUUID. The code that now checks for Nothing used to behave
in some undefined way if the external program made requests that
triggered it.
Also, note that in externalSetup, once it generates external,
it parses the RemoteConfig strictly. That generates a
ParsedRemoteConfig, which is thrown away. The reason it's ok to throw
that away, is that, if the strict parse succeeded, the result must be
the same as the earlier, lenient parse.
initremote of an external special remote now runs the program three
times. First for LISTCONFIGS, then EXPORTSUPPORTED, and again
LISTCONFIGS+INITREMOTE. It would not be hard to eliminate at least
one of those, and it should be possible to only run the program once.
2020-01-17 19:30:14 +00:00
|
|
|
remote to start up. (Or it might send an INITREMOTE or EXPORTSUPPORTED or
|
|
|
|
LISTCONFIGS, or perhaps other things in the future, so don't hardcode this
|
|
|
|
order.)
|
2013-12-11 21:20:34 +00:00
|
|
|
|
|
|
|
PREPARE
|
2013-12-11 17:31:11 +00:00
|
|
|
|
2013-12-11 21:20:34 +00:00
|
|
|
The special remote can now ask git-annex for its configuration, as needed,
|
|
|
|
and check that it's valid. git-annex responds with the configuration values
|
2013-12-11 17:56:59 +00:00
|
|
|
|
2013-12-11 21:20:34 +00:00
|
|
|
GETCONFIG directory
|
2013-12-16 14:30:28 +00:00
|
|
|
VALUE /media/usbdrive/repo
|
2013-12-11 21:20:34 +00:00
|
|
|
GETCONFIG automount
|
2013-12-16 14:30:28 +00:00
|
|
|
VALUE true
|
2013-12-11 17:31:11 +00:00
|
|
|
|
2013-12-11 21:20:34 +00:00
|
|
|
Once the special remote is satisfied with its configuration and is
|
2016-09-26 23:19:32 +00:00
|
|
|
ready to go, it tells git-annex that it's done with the PREPARE step:
|
2013-12-11 17:31:11 +00:00
|
|
|
|
2013-12-11 21:20:34 +00:00
|
|
|
PREPARE-SUCCESS
|
2013-12-11 17:31:11 +00:00
|
|
|
|
2016-09-26 23:19:32 +00:00
|
|
|
Now git-annex will make a request. Let's suppose it wants to store a key.
|
2013-12-11 17:31:11 +00:00
|
|
|
|
2013-12-11 21:20:34 +00:00
|
|
|
TRANSFER STORE somekey tmpfile
|
2013-12-11 18:02:49 +00:00
|
|
|
|
2016-09-26 23:19:32 +00:00
|
|
|
The special remote can then start reading the tmpfile and storing it.
|
|
|
|
While it's doing that, the special remote can send messages back to
|
|
|
|
git-annex to indicate what it's doing, or ask for other information.
|
|
|
|
It will typically send progress messages, indicating how many
|
2013-12-11 21:20:34 +00:00
|
|
|
bytes have been sent:
|
2013-12-11 18:02:49 +00:00
|
|
|
|
2013-12-26 20:18:38 +00:00
|
|
|
PROGRESS 10240
|
|
|
|
PROGRESS 20480
|
2013-12-11 17:31:11 +00:00
|
|
|
|
2013-12-11 21:20:34 +00:00
|
|
|
Once the key has been stored, the special remote tells git-annex the result:
|
2013-12-11 17:31:11 +00:00
|
|
|
|
2013-12-11 21:20:34 +00:00
|
|
|
TRANSFER-SUCCESS STORE somekey
|
|
|
|
|
2016-09-26 23:19:32 +00:00
|
|
|
Now git-annex will send its next request.
|
|
|
|
|
2013-12-11 21:20:34 +00:00
|
|
|
Once git-annex is done with the special remote, it will close its stdin.
|
|
|
|
The special remote program can then exit.
|
|
|
|
|
2019-05-28 18:00:05 +00:00
|
|
|
## git-annex request messages and replies
|
2013-12-11 21:20:34 +00:00
|
|
|
|
2013-12-27 06:08:29 +00:00
|
|
|
These are messages git-annex sends to the special remote program.
|
2013-12-11 21:20:34 +00:00
|
|
|
|
|
|
|
Once the special remote has finished performing the request, it should
|
2019-05-28 18:00:05 +00:00
|
|
|
send one of the listed replies.
|
2013-12-11 21:20:34 +00:00
|
|
|
|
2013-12-27 06:08:29 +00:00
|
|
|
The following requests *must* all be supported by the special remote.
|
2013-12-26 00:04:31 +00:00
|
|
|
|
2013-12-11 17:31:11 +00:00
|
|
|
* `INITREMOTE`
|
2014-12-05 03:25:00 +00:00
|
|
|
Requests the remote to initialize itself. This is where any one-time
|
2013-12-11 21:20:34 +00:00
|
|
|
setup tasks can be done, for example creating an Amazon S3 bucket.
|
2013-12-27 06:49:10 +00:00
|
|
|
Note: This may be run repeatedly over time, as a remote is initialized in
|
2013-12-11 17:31:11 +00:00
|
|
|
different repositories, or as the configuration of a remote is changed.
|
2013-12-29 17:44:39 +00:00
|
|
|
(Both `git annex initremote` and `git-annex enableremote` run this.)
|
2013-12-11 21:20:34 +00:00
|
|
|
So any one-time setup tasks should be done idempotently.
|
2019-05-28 18:00:05 +00:00
|
|
|
* `INITREMOTE-SUCCESS`
|
|
|
|
Indicates the INITREMOTE succeeded and the remote is ready to use.
|
|
|
|
* `INITREMOTE-FAILURE ErrorMsg`
|
|
|
|
Indicates that INITREMOTE failed.
|
2013-12-27 06:49:10 +00:00
|
|
|
* `PREPARE`
|
2014-12-05 03:25:00 +00:00
|
|
|
Tells the remote that it's time to prepare itself to be used.
|
add LISTCONFIGS to external special remote protocol
Special remote programs that use GETCONFIG/SETCONFIG are recommended
to implement it.
The description is not yet used, but will be useful later when adding a way
to make initremote list all accepted configs.
configParser now takes a RemoteConfig parameter. Normally, that's not
needed, because configParser returns a parter, it does not parse it
itself. But, it's needed to look at externaltype and work out what
external remote program to run for LISTCONFIGS.
Note that, while externalUUID is changed to a Maybe UUID, checkExportSupported
used to use NoUUID. The code that now checks for Nothing used to behave
in some undefined way if the external program made requests that
triggered it.
Also, note that in externalSetup, once it generates external,
it parses the RemoteConfig strictly. That generates a
ParsedRemoteConfig, which is thrown away. The reason it's ok to throw
that away, is that, if the strict parse succeeded, the result must be
the same as the earlier, lenient parse.
initremote of an external special remote now runs the program three
times. First for LISTCONFIGS, then EXPORTSUPPORTED, and again
LISTCONFIGS+INITREMOTE. It would not be hard to eliminate at least
one of those, and it should be possible to only run the program once.
2020-01-17 19:30:14 +00:00
|
|
|
Only a few requests for details about the remote can come before this
|
|
|
|
(EXTENSIONS, INITREMOTE, EXPORTSUPPORTED, and LISTCONFIGS,
|
|
|
|
but others may be added later).
|
2019-05-28 18:00:05 +00:00
|
|
|
* `PREPARE-SUCCESS`
|
|
|
|
Sent as a response to PREPARE once the special remote is ready for use.
|
|
|
|
* `PREPARE-FAILURE ErrorMsg`
|
|
|
|
Sent as a response to PREPARE if the special remote cannot be used.
|
2013-12-11 17:53:21 +00:00
|
|
|
* `TRANSFER STORE|RETRIEVE Key File`
|
2021-10-11 16:40:16 +00:00
|
|
|
Requests the transfer of a key. This is the main thing a special remote
|
|
|
|
does. For STORE, the File contains the content to upload;
|
|
|
|
for RETRIEVE the File is where to store the content you download.
|
|
|
|
When retrieving, the File may already exist, if its retieval was
|
|
|
|
interrupted before. That lets the remote resume downloading, if it's able
|
|
|
|
to.
|
|
|
|
Note that the File should not influence the filename used on the remote;
|
|
|
|
that filename should be based on the Key.
|
|
|
|
Note that in some cases, the File's name may include whitespace or other
|
|
|
|
special characters.
|
2019-05-28 18:00:05 +00:00
|
|
|
While the transfer is running, the remote can send any number of
|
2020-08-11 20:42:09 +00:00
|
|
|
`PROGRESS` messages to indicate its progress. It can also send any of the
|
|
|
|
other special remote messages. Once the transfer is done, it finishes by
|
|
|
|
sending one of these replies:
|
2019-05-28 18:00:05 +00:00
|
|
|
* `TRANSFER-SUCCESS STORE|RETRIEVE Key`
|
|
|
|
Indicates the transfer completed successfully.
|
|
|
|
* `TRANSFER-FAILURE STORE|RETRIEVE Key ErrorMsg`
|
|
|
|
Indicates the transfer failed.
|
2013-12-13 19:31:45 +00:00
|
|
|
* `CHECKPRESENT Key`
|
2021-10-11 16:40:16 +00:00
|
|
|
Requests the remote to check if a key is present in it.
|
|
|
|
It's important that, while a key is being transferred to a remote,
|
|
|
|
`CHECKPRESENT` not indicate it's present in the remote until all
|
|
|
|
the data has been sent.
|
2019-05-28 18:00:05 +00:00
|
|
|
* `CHECKPRESENT-SUCCESS Key`
|
|
|
|
Indicates that a key has been positively verified to be present in the
|
|
|
|
remote.
|
|
|
|
* `CHECKPRESENT-FAILURE Key`
|
|
|
|
Indicates that a key has been positively verified to not be present in the
|
|
|
|
remote.
|
|
|
|
* `CHECKPRESENT-UNKNOWN Key ErrorMsg`
|
|
|
|
Indicates that it is not currently possible to verify if the key is
|
|
|
|
present in the remote. (Perhaps the remote cannot be contacted.)
|
2013-12-11 17:31:11 +00:00
|
|
|
* `REMOVE Key`
|
2014-12-05 17:40:44 +00:00
|
|
|
Requests the remote to remove a key's contents.
|
2019-05-28 18:00:05 +00:00
|
|
|
* `REMOVE-SUCCESS Key`
|
|
|
|
Indicates the key has been removed from the remote. May be returned if
|
|
|
|
the remote didn't have the key at the point removal was requested.
|
|
|
|
* `REMOVE-FAILURE Key ErrorMsg`
|
|
|
|
Indicates that the key was unable to be removed from the remote.
|
2013-12-11 17:31:11 +00:00
|
|
|
|
2019-05-28 20:16:17 +00:00
|
|
|
Special remotes can optionally support tree exports and imports,
|
|
|
|
which makes the [[git-annex-export]] and [[git-annex-import]] commands
|
|
|
|
work with them. See the [[export_and_import_appendix]] for
|
|
|
|
additional requests that git-annex will make when using special remotes in
|
|
|
|
this way.
|
|
|
|
|
2019-05-28 18:00:05 +00:00
|
|
|
The following requests can optionally be supported. If not supported,
|
|
|
|
the special remote can reply with `UNSUPPORTED-REQUEST`.
|
2013-12-27 06:08:29 +00:00
|
|
|
|
2018-02-07 19:02:12 +00:00
|
|
|
* `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.
|
2020-08-11 20:42:09 +00:00
|
|
|
See the section on extensions below for details.
|
2019-05-28 18:00:05 +00:00
|
|
|
* `EXTENSIONS List`
|
2020-08-11 20:42:09 +00:00
|
|
|
Sent in response to a EXTENSIONS request, to indicate the protocol
|
|
|
|
extensions that the special remote is using.
|
add LISTCONFIGS to external special remote protocol
Special remote programs that use GETCONFIG/SETCONFIG are recommended
to implement it.
The description is not yet used, but will be useful later when adding a way
to make initremote list all accepted configs.
configParser now takes a RemoteConfig parameter. Normally, that's not
needed, because configParser returns a parter, it does not parse it
itself. But, it's needed to look at externaltype and work out what
external remote program to run for LISTCONFIGS.
Note that, while externalUUID is changed to a Maybe UUID, checkExportSupported
used to use NoUUID. The code that now checks for Nothing used to behave
in some undefined way if the external program made requests that
triggered it.
Also, note that in externalSetup, once it generates external,
it parses the RemoteConfig strictly. That generates a
ParsedRemoteConfig, which is thrown away. The reason it's ok to throw
that away, is that, if the strict parse succeeded, the result must be
the same as the earlier, lenient parse.
initremote of an external special remote now runs the program three
times. First for LISTCONFIGS, then EXPORTSUPPORTED, and again
LISTCONFIGS+INITREMOTE. It would not be hard to eliminate at least
one of those, and it should be possible to only run the program once.
2020-01-17 19:30:14 +00:00
|
|
|
* `LISTCONFIGS`
|
|
|
|
Requests the remote to return a list of settings it uses (with
|
|
|
|
`GETCONFIG` and `SETCONFIG`). Providing a list makes `git annex initremote`
|
|
|
|
work better, because it can check the user's input, and can also display
|
|
|
|
a list of settings with descriptions. Note that the user is not required
|
|
|
|
to provided all the settings listed here. A block of responses
|
2020-11-30 00:11:16 +00:00
|
|
|
can be made to this, which must always end with `CONFIGEND`.
|
2021-01-26 16:42:47 +00:00
|
|
|
(Do not include settings like "encryption" that are common to all external
|
2020-03-09 16:34:13 +00:00
|
|
|
special remotes.)
|
add LISTCONFIGS to external special remote protocol
Special remote programs that use GETCONFIG/SETCONFIG are recommended
to implement it.
The description is not yet used, but will be useful later when adding a way
to make initremote list all accepted configs.
configParser now takes a RemoteConfig parameter. Normally, that's not
needed, because configParser returns a parter, it does not parse it
itself. But, it's needed to look at externaltype and work out what
external remote program to run for LISTCONFIGS.
Note that, while externalUUID is changed to a Maybe UUID, checkExportSupported
used to use NoUUID. The code that now checks for Nothing used to behave
in some undefined way if the external program made requests that
triggered it.
Also, note that in externalSetup, once it generates external,
it parses the RemoteConfig strictly. That generates a
ParsedRemoteConfig, which is thrown away. The reason it's ok to throw
that away, is that, if the strict parse succeeded, the result must be
the same as the earlier, lenient parse.
initremote of an external special remote now runs the program three
times. First for LISTCONFIGS, then EXPORTSUPPORTED, and again
LISTCONFIGS+INITREMOTE. It would not be hard to eliminate at least
one of those, and it should be possible to only run the program once.
2020-01-17 19:30:14 +00:00
|
|
|
* `CONFIG Name Description`
|
|
|
|
Indicates the name and description of a config setting. The description
|
|
|
|
should be reasonably short. Example:
|
|
|
|
"CONFIG directory store data here"
|
|
|
|
* `CONFIGEND`
|
|
|
|
Indicates the end of the response block.
|
2013-12-27 06:08:29 +00:00
|
|
|
* `GETCOST`
|
2014-12-05 03:25:00 +00:00
|
|
|
Requests the remote to return a use cost. Higher costs are more expensive.
|
2013-12-27 06:08:29 +00:00
|
|
|
(See Config/Cost.hs for some standard costs.)
|
2019-05-28 18:00:05 +00:00
|
|
|
* `COST Int`
|
|
|
|
Indicates the cost of the remote.
|
2020-07-20 18:05:49 +00:00
|
|
|
* `GETAVAILABILITY`
|
2019-05-28 18:00:05 +00:00
|
|
|
Asks the remote if it is locally or globally available.
|
|
|
|
(Ie stored in the cloud vs on a local disk.)
|
2014-01-13 18:41:10 +00:00
|
|
|
If the remote replies with `UNSUPPORTED-REQUEST`, its availability
|
2014-12-05 03:25:00 +00:00
|
|
|
is assumed to be global. So, only remotes that are only reachable
|
2014-01-13 18:41:10 +00:00
|
|
|
locally need to worry about implementing this.
|
2019-05-28 18:00:05 +00:00
|
|
|
* `AVAILABILITY GLOBAL|LOCAL`
|
|
|
|
Indicates if the remote is globally or only locally available.
|
2014-12-08 23:14:24 +00:00
|
|
|
* `CLAIMURL Url`
|
2014-12-08 17:57:13 +00:00
|
|
|
Asks the remote if it wishes to claim responsibility for downloading
|
2019-05-28 18:00:05 +00:00
|
|
|
an url.
|
|
|
|
* `CLAIMURL-SUCCESS`
|
|
|
|
Indicates that the CLAIMURL url will be handled by this remote.
|
|
|
|
* `CLAIMURL-FAILURE`
|
|
|
|
Indicates that the CLAIMURL url wil not be handled by this remote.
|
2014-12-08 23:14:24 +00:00
|
|
|
* `CHECKURL Url`
|
|
|
|
Asks the remote to check if the url's content can currently be downloaded
|
2019-05-28 18:00:05 +00:00
|
|
|
(without downloading it).
|
|
|
|
* `CHECKURL-CONTENTS Size|UNKNOWN Filename`
|
|
|
|
Indicates that the requested url has been verified to exist.
|
|
|
|
The Size is the size in bytes, or use "UNKNOWN" if the size could not be
|
|
|
|
determined.
|
|
|
|
The Filename can be empty (in which case a default is used),
|
|
|
|
or can specify a filename that is suggested to be used for this url.
|
|
|
|
* `CHECKURL-MULTI Url1 Size1|UNKNOWN Filename1 Url2 Size2|UNKNOWN Filename2 ...`
|
|
|
|
Indicates that the requested url has been verified to exist,
|
|
|
|
and contains multiple files, which can each be accessed using
|
|
|
|
their own url. Each triplet of url, size, and filename should be listed,
|
|
|
|
one after the other.
|
|
|
|
Note that since a list is returned, neither the Url nor the Filename
|
|
|
|
can contain spaces.
|
2020-09-18 15:58:18 +00:00
|
|
|
* `CHECKURL-FAILURE ErrorMsg`
|
2019-05-28 18:00:05 +00:00
|
|
|
Indicates that the requested url could not be accessed.
|
2020-07-20 18:05:49 +00:00
|
|
|
* `WHEREIS Key`
|
2015-09-09 21:09:48 +00:00
|
|
|
Asks the remote to provide additional information about ways to access
|
2015-08-13 21:26:09 +00:00
|
|
|
the content of a key stored in it, such as eg, public urls.
|
2019-05-28 18:00:05 +00:00
|
|
|
This will be displayed to the user by eg, `git annex whereis`.
|
2015-08-13 21:26:09 +00:00
|
|
|
Note that users expect `git annex whereis` to run fast, without eg,
|
|
|
|
network access.
|
2019-05-28 18:00:05 +00:00
|
|
|
* `WHEREIS-SUCCESS String`
|
|
|
|
Indicates a location of a key. Typically an url, the string can
|
|
|
|
be anything that it makes sense to display to the user about content
|
|
|
|
stored in the special remote.
|
|
|
|
* `WHEREIS-FAILURE`
|
|
|
|
Indicates that no location is known for a key.
|
|
|
|
This is not needed when `SETURIPRESENT` is used, since such uris are
|
|
|
|
automatically displayed by `git annex whereis`.
|
2018-06-08 15:52:20 +00:00
|
|
|
* `GETINFO`
|
|
|
|
Requests the remote to send some information describing its
|
2019-05-28 18:00:05 +00:00
|
|
|
configuration, for display by `git annex info`. A block of responses
|
|
|
|
can be made to this, which must always end with `INFOEND`.
|
|
|
|
* `INFOFIELD Name`
|
|
|
|
Gives the name of an info field. The name can be anything you want to
|
|
|
|
be displayed to the user. Must be immediately followed by `INFOVALUE`.
|
|
|
|
* `INFOVALUE Value`
|
|
|
|
Gives the value of an info field.
|
|
|
|
* `INFOEND`
|
|
|
|
Indicates the end of the response block.
|
2013-12-27 06:08:29 +00:00
|
|
|
|
|
|
|
More optional requests may be added, without changing the protocol version,
|
2019-05-28 18:00:05 +00:00
|
|
|
so if an unknown request is seen, don't crash, just reply with
|
|
|
|
`UNSUPPORTED-REQUEST`.
|
2013-12-11 17:31:11 +00:00
|
|
|
|
2013-12-11 21:20:34 +00:00
|
|
|
## special remote messages
|
|
|
|
|
2013-12-16 15:36:19 +00:00
|
|
|
These messages may be sent by the special remote at any time that it's
|
2016-09-26 23:19:32 +00:00
|
|
|
handling a request.
|
2013-12-11 21:20:34 +00:00
|
|
|
|
|
|
|
* `VERSION Int`
|
2013-12-26 22:14:52 +00:00
|
|
|
Supported protocol version. Current version is 1. Must be sent first
|
2013-12-11 21:20:34 +00:00
|
|
|
thing at startup, as until it sees this git-annex does not know how to
|
2016-05-23 19:11:39 +00:00
|
|
|
talk with the special remote program!
|
|
|
|
(git-annex does not send a reply to this message, but may give up if it
|
|
|
|
doesn't support the necessary protocol version.)
|
2013-12-26 20:18:38 +00:00
|
|
|
* `PROGRESS Int`
|
2021-10-11 16:40:16 +00:00
|
|
|
Indicates the current progress of the transfer. The Int is the
|
|
|
|
number of bytes from the beginning of the file that have been
|
|
|
|
transferred.
|
|
|
|
May be repeated any number of times during the transfer
|
|
|
|
process, but it's wasteful to update the progress too frequently.
|
|
|
|
Bear in mind that this is used both
|
2020-12-11 22:24:21 +00:00
|
|
|
to display a progress meter for the user, and for annex.stalldetection.
|
|
|
|
So, sending an update on each 1% of the file may not be frequent enough,
|
|
|
|
as it could appear to be a stall when transferring a large file.
|
2021-10-11 16:40:16 +00:00
|
|
|
This is highly recommended for STORE.
|
|
|
|
(It is optional but good for RETRIEVE; git-annex will fall back to
|
|
|
|
tracking the size of the file as it grows.)
|
2013-12-16 15:36:19 +00:00
|
|
|
(git-annex does not send a reply to this message.)
|
2013-12-11 21:20:34 +00:00
|
|
|
* `DIRHASH Key`
|
2022-09-30 17:33:59 +00:00
|
|
|
Gets a two level hash associated with a Key. Something like "aB/Cd/".
|
2013-12-11 21:20:34 +00:00
|
|
|
This is always the same for any given Key, so can be used for eg,
|
2016-05-03 17:36:59 +00:00
|
|
|
creating hash directory structures to store Keys in. This is the same
|
|
|
|
directory hash that git-annex uses inside `.git/annex/objects/`
|
|
|
|
(git-annex replies with VALUE followed by the value.)
|
2016-05-03 18:10:11 +00:00
|
|
|
* `DIRHASH-LOWER Key`
|
2016-05-03 17:36:59 +00:00
|
|
|
Gets a two level hash associated with a Key, using only lower-case.
|
2022-09-30 17:33:59 +00:00
|
|
|
Something like "abc/def/".
|
2016-05-03 17:36:59 +00:00
|
|
|
This is always the same for any given Key, so can be used for eg,
|
|
|
|
creating hash directory structures to store Keys in. This is the same
|
|
|
|
directory hash that is used by eg, the directory special remote.
|
2016-05-23 19:03:05 +00:00
|
|
|
(git-annex replies with VALUE followed by the value.)
|
2014-02-11 01:11:48 +00:00
|
|
|
* `SETCONFIG Setting Value`
|
2013-12-27 16:37:23 +00:00
|
|
|
Sets one of the special remote's configuration settings.
|
|
|
|
Normally this is sent during INITREMOTE, which allows these settings
|
|
|
|
to be stored in the git-annex branch, so will be available if the same
|
|
|
|
special remote is used elsewhere. (If sent after INITREMOTE, the changed
|
2016-05-23 19:11:39 +00:00
|
|
|
configuration will only be available while the remote is running.)
|
2021-01-26 16:42:47 +00:00
|
|
|
See also `GETGITREMOTENAME` for a way to access git configuration of the
|
|
|
|
remote.
|
2016-05-23 19:11:39 +00:00
|
|
|
(git-annex does not send a reply to this message.)
|
2013-12-25 21:53:24 +00:00
|
|
|
* `GETCONFIG Setting`
|
2013-12-27 16:37:23 +00:00
|
|
|
Gets one of the special remote's configuration settings, which can have
|
|
|
|
been passed by the user when running `git annex initremote`, or
|
|
|
|
can have been set by a previous SETCONFIG. Can be run at any time.
|
add LISTCONFIGS to external special remote protocol
Special remote programs that use GETCONFIG/SETCONFIG are recommended
to implement it.
The description is not yet used, but will be useful later when adding a way
to make initremote list all accepted configs.
configParser now takes a RemoteConfig parameter. Normally, that's not
needed, because configParser returns a parter, it does not parse it
itself. But, it's needed to look at externaltype and work out what
external remote program to run for LISTCONFIGS.
Note that, while externalUUID is changed to a Maybe UUID, checkExportSupported
used to use NoUUID. The code that now checks for Nothing used to behave
in some undefined way if the external program made requests that
triggered it.
Also, note that in externalSetup, once it generates external,
it parses the RemoteConfig strictly. That generates a
ParsedRemoteConfig, which is thrown away. The reason it's ok to throw
that away, is that, if the strict parse succeeded, the result must be
the same as the earlier, lenient parse.
initremote of an external special remote now runs the program three
times. First for LISTCONFIGS, then EXPORTSUPPORTED, and again
LISTCONFIGS+INITREMOTE. It would not be hard to eliminate at least
one of those, and it should be possible to only run the program once.
2020-01-17 19:30:14 +00:00
|
|
|
It's recommended that special remotes that use this implement
|
2020-03-09 16:34:13 +00:00
|
|
|
LISTCONFIGS.
|
2013-12-27 16:37:23 +00:00
|
|
|
(git-annex replies with VALUE followed by the value. If the setting is
|
|
|
|
not set, the value will be empty.)
|
2013-12-27 20:01:43 +00:00
|
|
|
* `SETCREDS Setting User Password`
|
|
|
|
When some form of user and password is needed to access a special remote,
|
|
|
|
this can be used to securely store them for later use.
|
|
|
|
(Like SETCONFIG, this is normally sent only during INITREMOTE.)
|
|
|
|
The Setting indicates which value in a remote's configuration can be
|
|
|
|
used to store the creds.
|
|
|
|
Note that creds are normally only stored in the remote's configuration
|
|
|
|
when it's surely safe to do so; when gpg encryption is used, in which
|
|
|
|
case the creds will be encrypted using it. If creds are not stored in
|
|
|
|
the configuration, they'll only be stored in a local file.
|
|
|
|
(embedcreds can be set to yes by the user or by SETCONFIG to force
|
2016-05-23 19:11:39 +00:00
|
|
|
the creds to be stored in the remote's configuration).
|
|
|
|
(git-annex does not send a reply to this message.)
|
2013-12-27 20:01:43 +00:00
|
|
|
* `GETCREDS Setting`
|
|
|
|
Gets any creds that were previously stored in the remote's configuration
|
|
|
|
or a file.
|
|
|
|
(git-annex replies with "CREDS User Password". If no creds are found,
|
|
|
|
User and Password are both empty.)
|
2013-12-31 17:50:18 +00:00
|
|
|
* `GETUUID`
|
|
|
|
Queries for the UUID of the special remote being used.
|
|
|
|
(git-annex replies with VALUE followed by the UUID.)
|
2014-01-13 18:00:09 +00:00
|
|
|
* `GETGITDIR`
|
|
|
|
Queries for the path to the git directory of the repository that
|
|
|
|
is using the external special remote.
|
|
|
|
(git-annex replies with VALUE followed by the path.)
|
2021-01-26 16:42:47 +00:00
|
|
|
* `GETGITREMOTENAME`
|
|
|
|
Gets the name of the git remote that represents this special remote.
|
|
|
|
This can be used, for example, to look up git configuration belonging
|
|
|
|
to that git remote. This name will often be the same as what is
|
|
|
|
passed to `git-annex initremote` and `enableremote`, but it is possible
|
|
|
|
for git remotes to be renamed, and this will provide the remote's current
|
|
|
|
name.
|
|
|
|
(git-annex replies with VALUE followed by the name.)
|
|
|
|
This message is a protocol extension; it's only safe to send it to
|
|
|
|
git-annex after it sent an EXTENSIONS that included GETGITREMOTENAME.
|
2014-01-02 00:12:20 +00:00
|
|
|
* `SETWANTED PreferredContentExpression`
|
|
|
|
Can be used to set the preferred content of a repository. Normally
|
|
|
|
this is not configured by a special remote, but it may make sense
|
|
|
|
in some situations to hint at the kind of content that should be stored
|
|
|
|
in the special remote. Note that if a unparsable expression is set,
|
2016-05-23 19:11:39 +00:00
|
|
|
git-annex will ignore it.
|
|
|
|
(git-annex does not send a reply to this message.)
|
2014-01-02 00:12:20 +00:00
|
|
|
* `GETWANTED`
|
|
|
|
Gets the current preferred content setting of the repository.
|
|
|
|
(git-annex replies with VALUE followed by the preferred content
|
|
|
|
expression.)
|
add remote state logs
This allows a remote to store a piece of arbitrary state associated with a
key. This is needed to support Tahoe, where the file-cap is calculated from
the data stored in it, and used to retrieve a key later. Glacier also would
be much improved by using this.
GETSTATE and SETSTATE are added to the external special remote protocol.
Note that the state is left as-is even when a key is removed from a remote.
It's up to the remote to decide when it wants to clear the state.
The remote state log, $KEY.log.rmt, is a UUID-based log. However,
rather than using the old UUID-based log format, I created a new variant
of that format. The new varient is more space efficient (since it lacks the
"timestamp=" hack, and easier to parse (and the parser doesn't mess with
whitespace in the value), and avoids compatability cruft in the old one.
This seemed worth cleaning up for these new files, since there could be a
lot of them, while before UUID-based logs were only used for a few log
files at the top of the git-annex branch. The transition code has also
been updated to handle these new UUID-based logs.
This commit was sponsored by Daniel Hofer.
2014-01-03 20:35:57 +00:00
|
|
|
* `SETSTATE Key Value`
|
|
|
|
Can be used to store some form of state for a Key. The state stored
|
|
|
|
can be anything this remote needs to store, in any format.
|
|
|
|
It is stored in the git-annex branch. Note that this means that if
|
|
|
|
multiple repositories are using the same special remote, and store
|
|
|
|
different state, whichever one stored the state last will win. Also,
|
|
|
|
it's best to avoid storing much state, since this will bloat the
|
2016-05-23 19:11:39 +00:00
|
|
|
git-annex branch. Most remotes will not need to store any state.
|
|
|
|
(git-annex does not send a reply to this message.)
|
add remote state logs
This allows a remote to store a piece of arbitrary state associated with a
key. This is needed to support Tahoe, where the file-cap is calculated from
the data stored in it, and used to retrieve a key later. Glacier also would
be much improved by using this.
GETSTATE and SETSTATE are added to the external special remote protocol.
Note that the state is left as-is even when a key is removed from a remote.
It's up to the remote to decide when it wants to clear the state.
The remote state log, $KEY.log.rmt, is a UUID-based log. However,
rather than using the old UUID-based log format, I created a new variant
of that format. The new varient is more space efficient (since it lacks the
"timestamp=" hack, and easier to parse (and the parser doesn't mess with
whitespace in the value), and avoids compatability cruft in the old one.
This seemed worth cleaning up for these new files, since there could be a
lot of them, while before UUID-based logs were only used for a few log
files at the top of the git-annex branch. The transition code has also
been updated to handle these new UUID-based logs.
This commit was sponsored by Daniel Hofer.
2014-01-03 20:35:57 +00:00
|
|
|
* `GETSTATE Key`
|
|
|
|
Gets any state that has been stored for the key.
|
|
|
|
(git-annex replies with VALUE followed by the state.)
|
2014-12-08 23:14:24 +00:00
|
|
|
* `SETURLPRESENT Key Url`
|
2015-08-11 16:55:25 +00:00
|
|
|
Records an URL where the Key can be downloaded from.
|
|
|
|
Note that this does not make git-annex think that the url is present on
|
2015-08-14 18:13:49 +00:00
|
|
|
the web special remote.
|
|
|
|
Keep in mind that this stores the url in the git-annex branch. This can
|
|
|
|
result in bloat to the branch if the url is large and/or does not delta
|
|
|
|
pack well with other information (such as the names of keys) already
|
2016-05-23 19:11:39 +00:00
|
|
|
stored in the branch.
|
|
|
|
(git-annex does not send a reply to this message.)
|
2014-12-08 23:14:24 +00:00
|
|
|
* `SETURLMISSING Key Url`
|
2014-12-08 17:32:27 +00:00
|
|
|
Records that the key can no longer be downloaded from the specified
|
2016-05-23 19:11:39 +00:00
|
|
|
URL.
|
|
|
|
(git-annex does not send a reply to this message.)
|
2015-03-05 17:50:15 +00:00
|
|
|
* `SETURIPRESENT Key Uri`
|
2020-05-21 15:58:57 +00:00
|
|
|
Records an URI where the Key can be downloaded from. Use with uris
|
|
|
|
that cannot be downloaded with http.
|
2016-05-23 19:11:39 +00:00
|
|
|
(git-annex does not send a reply to this message.)
|
2015-03-05 17:50:15 +00:00
|
|
|
* `SETURIMISSING Key Uri`
|
|
|
|
Records that the key can no longer be downloaded from the specified
|
2016-05-23 19:11:39 +00:00
|
|
|
URI.
|
|
|
|
(git-annex does not send a reply to this message.)
|
2014-12-08 23:14:24 +00:00
|
|
|
* `GETURLS Key Prefix`
|
2014-12-08 17:32:27 +00:00
|
|
|
Gets the recorded urls where a Key can be downloaded from.
|
2014-12-08 23:14:24 +00:00
|
|
|
Only urls that start with the Prefix will be returned. The Prefix
|
2014-12-08 17:32:27 +00:00
|
|
|
may be empty to get all urls.
|
|
|
|
(git-annex replies one or more times with VALUE for each url.
|
|
|
|
The final VALUE has an empty value, indicating the end of the url list.)
|
2020-07-27 15:31:00 +00:00
|
|
|
* `DEBUG message`
|
2018-02-06 17:03:55 +00:00
|
|
|
Tells git-annex to display the message if --debug is enabled.
|
2016-05-23 19:03:05 +00:00
|
|
|
(git-annex does not send a reply to this message.)
|
2018-02-06 17:03:55 +00:00
|
|
|
* `INFO message`
|
|
|
|
Tells git-annex to display the message to the user.
|
|
|
|
When git-annex is in --json mode, the message will be emitted immediately
|
|
|
|
in its own json object, with an "info" field.
|
2020-08-11 20:42:09 +00:00
|
|
|
This message is a protocol extension; it's only safe to send it to
|
|
|
|
git-annex after it sent an EXTENSIONS that included INFO.
|
2018-02-06 17:03:55 +00:00
|
|
|
(git-annex does not send a reply to this message.)
|
2013-12-16 15:36:19 +00:00
|
|
|
|
|
|
|
## general messages
|
2013-12-11 21:20:34 +00:00
|
|
|
|
2013-12-16 15:36:19 +00:00
|
|
|
These messages can be sent at any time by either git-annex or the special
|
|
|
|
remote.
|
|
|
|
|
|
|
|
* `ERROR ErrorMsg`
|
2013-12-26 00:04:31 +00:00
|
|
|
Generic error. Can be sent at any time if things get too messed up
|
|
|
|
to continue. When possible, use a more specific reply from the list above.
|
|
|
|
The special remote program should exit after sending this, as
|
2013-12-16 15:36:19 +00:00
|
|
|
git-annex will not talk to it any further. If the program receives
|
2013-12-26 00:04:31 +00:00
|
|
|
an ERROR from git-annex, it can exit with its own ERROR.
|
2013-12-16 14:30:28 +00:00
|
|
|
|
2020-08-11 20:42:09 +00:00
|
|
|
## extensions
|
|
|
|
|
|
|
|
These protocol extensions are currently supported.
|
|
|
|
|
|
|
|
* `INFO`
|
|
|
|
This makes the `INFO` message available to use.
|
|
|
|
* `ASYNC`
|
|
|
|
This lets multiple actions be performed at the same time by
|
|
|
|
a single external special remote program, rather than starting multiple
|
|
|
|
programs. See the [[async_appendix]] for details.
|
2021-01-26 16:42:47 +00:00
|
|
|
* `GETGITREMOTENAME`
|
|
|
|
This makes the `GETGITREMOTENAME` message available to use.
|
2020-08-11 20:42:09 +00:00
|
|
|
|
async exception safety for external special remote processes
Since an external process can be in the middle of some operation when an
async exception is received, it has to be shut down then. Using
cleanupProcess will close its IO handles and send it a SIGTERM.
If a special remote choses to catch SIGTERM, it's fine for it to do some
cleanup then, but until it finishes, git-annex will be blocked waiting
for it. If a special remote blocked SIGTERM, it would cause a hang.
Mentioned in docs.
Also, in passing, fixed a FD leak, it was not closing the error handle
when shutting down the external. In practice that didn't matter before because
it was only run when git-annex was itself shutting down, but now that it
can run on exception, it would have been a problem.
2020-06-09 16:13:06 +00:00
|
|
|
## signals
|
|
|
|
|
|
|
|
The external special remote program should not block SIGINT, or SIGTERM.
|
|
|
|
Doing so may cause git-annex to hang waiting on it to exit.
|
|
|
|
Of course it's ok to catch those signals and do some necessary cleanup
|
|
|
|
before exiting.
|
|
|
|
|
2014-01-06 21:06:55 +00:00
|
|
|
## long running network connections
|
|
|
|
|
|
|
|
Since an external special remote is started only when git-annex needs to
|
|
|
|
access the remote, and then left running, it's ok to open a network
|
|
|
|
connection in the PREPARE stage, and continue to use that network
|
|
|
|
connection as requests are made.
|
|
|
|
|
|
|
|
If you're unable to open a network connection, or the connection closes,
|
|
|
|
perhaps because the network is down, it's ok to fail to perform any
|
|
|
|
requests. Or you can try to reconnect when a new request is made.
|
|
|
|
|
|
|
|
Note that the external special remote program may be left running for
|
|
|
|
quite a long time, especially when the git-annex assistant is using it.
|
|
|
|
The assistant will detect when the system connects to a network, and will
|
|
|
|
start a new process the next time it needs to use a remote.
|
|
|
|
|
2020-05-21 15:58:57 +00:00
|
|
|
## claiming custom uri schemes for use with git-annex addurl
|
|
|
|
|
|
|
|
If a special remote has its own uri scheme, or some other way to identify a
|
|
|
|
particular url as being content that is stored in the special remote,
|
|
|
|
and can be downloaded by it, it can implement CLAIMURL and CHECKURL.
|
|
|
|
This lets git-annex addurl be used with such urls.
|
|
|
|
|
|
|
|
For example, the ipfs special remote implements CLAIMURL and CHECKURL
|
|
|
|
for "ipfs:ADDRESS" uris. And the bittorrent special remote implements them
|
|
|
|
for http urls ending in ".torrent".
|
|
|
|
|
|
|
|
When a special remote has claimed an url, commands like git-annex addurl
|
|
|
|
will use TRANSFER RETRIEVE to request it download the content of a key.
|
|
|
|
To find out what url to download, the special remote can use GETURLS
|
|
|
|
to find out what urls are recorded for the key.
|
|
|
|
|
|
|
|
For example, the ipfs special remote sends "GETURLS $KEY ipfs:",
|
|
|
|
in order to get only the "ipfs:" uris.
|
|
|
|
|
|
|
|
The special remote can also use SETURIPRESENT or SETURLPRESENT,
|
|
|
|
eg after transferring content to the remote it might know the uri or url
|
|
|
|
that can be used to download it. And SETURIMISSING or SETURLMISSING
|
|
|
|
can be used after removing content from the remote. This information can
|
|
|
|
then be looked up using GETURLS. But it's not necessary to do this in order
|
|
|
|
to simply claim an url, because git-annex addurl takes care of it.
|
|
|
|
|
|
|
|
For example, the ipfs special remote sends "SETURIPRESENT $KEY ipfs:ADDRESS"
|
|
|
|
after storing each key in ipfs. It can later look up that uri when
|
|
|
|
downloading the key, and the ipfs uri is also displayed by git-annex
|
|
|
|
whereis.
|
|
|
|
|
|
|
|
## readonly mode for http downloads
|
2015-08-14 21:38:54 +00:00
|
|
|
|
|
|
|
Some storage services allow downloading the content of a file using a
|
|
|
|
regular http connection, with no authentication. An external special remote
|
|
|
|
for such a storage service can support a readonly mode of operation.
|
|
|
|
|
|
|
|
It works like this:
|
|
|
|
|
|
|
|
* When a key's content is stored on the remote, use SETURLPRESENT to
|
|
|
|
tell git-annex the public url from which it can be downloaded.
|
|
|
|
* When a key's content is removed from the remote, use SETURLMISSING.
|
|
|
|
* Document that this external special remote can be used in readonly mode.
|
|
|
|
|
|
|
|
The user doesn't even need to install your external special remote
|
|
|
|
program to use such a remote! All they need to do is run:
|
|
|
|
`git annex enableremote $remotename readonly=true`
|
|
|
|
|
|
|
|
* The readonly=true parameter makes git-annex download content from the
|
|
|
|
urls recorded earlier by SETURLPRESENT.
|
|
|
|
|
2013-12-11 17:31:11 +00:00
|
|
|
## TODO
|
|
|
|
|
2013-12-27 16:04:51 +00:00
|
|
|
* When storing encrypted files stream the file up/down the pipe, rather
|
|
|
|
than using a temp file. Will probably involve less space and disk IO,
|
|
|
|
and makes the progress display better, since the encryption can happen
|
|
|
|
concurrently with the transfer. Also, no need to use PROGRESS in this
|
|
|
|
scenario, since git-annex can see how much data it has sent/received from
|
|
|
|
the remote. However, \n and probably \0 need to be escaped somehow in the
|
|
|
|
file data, which adds complication.
|
|
|
|
* uuid discovery during INITREMOTE.
|
2013-12-27 20:37:58 +00:00
|
|
|
* Hook into webapp. Needs a way to provide some kind of prompt to the user
|
|
|
|
in the webapp, etc.
|