break out export and import appending

The import protocol is WiP
This commit is contained in:
Joey Hess 2019-05-28 16:16:17 -04:00
parent 4818e3606c
commit 08aa8e2010
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
2 changed files with 309 additions and 68 deletions

View file

@ -156,6 +156,12 @@ The following requests *must* all be supported by the special remote.
* `REMOVE-FAILURE Key ErrorMsg`
Indicates that the key was unable to be removed from the remote.
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.
The following requests can optionally be supported. If not supported,
the special remote can reply with `UNSUPPORTED-REQUEST`.
@ -230,74 +236,6 @@ the special remote can reply with `UNSUPPORTED-REQUEST`.
Gives the value of an info field.
* `INFOEND`
Indicates the end of the response block.
* `EXPORTSUPPORTED`
Used to check if a special remote supports exports.
Note that this request may be made before or after `PREPARE`.
* `EXPORTSUPPORTED-SUCCESS`
Indicates that it makes sense to use this special remote as an export.
* `EXPORTSUPPORTED-FAILURE`
Indicates that it does not make sense to use this special remote as an
export.
* `EXPORT Name`
Comes immediately before each of the following export-related requests,
specifying the name of the exported file. It will be in the form
of a relative path, and may contain path separators, whitespace,
and other special characters.
No response is made to this message.
* `TRANSFEREXPORT STORE|RETRIEVE Key File`
Requests the transfer of a File on local disk to or from the previously
provided Name on the special remote.
Note that it's important that, while a file is being stored,
CHECKPRESENTEXPORT not indicate it's present until all the data has
been transferred.
While the transfer is running, the remote can send any number of
`PROGRESS` messages. Once the transfer is complete, it finishes by
sending one of these replies:
* `TRANSFER-SUCCESS STORE|RETRIEVE Key`
Indicates the transfer completed successfully.
* `TRANSFER-FAILURE STORE|RETRIEVE Key ErrorMsg`
Indicates the transfer failed.
* `CHECKPRESENTEXPORT Key`
Requests the remote to check if the previously provided Name is present
in it.
* `CHECKPRESENT-SUCCESS Key`
Indicates that a content has been positively verified to be present in the
remote.
* `CHECKPRESENT-FAILURE Key`
Indicates that a contents 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 content is
present in the remote. (Perhaps the remote cannot be contacted.)
* `REMOVEEXPORT Key`
Requests the remote to remove content stored by `TRANSFEREXPORT`
with the previously provided Name.
* `REMOVE-SUCCESS Key`
Indicates the content has been removed from the remote. May be returned when
the content was already not present.
* `REMOVE-FAILURE Key ErrorMsg`
Indicates that the content was unable to be removed from the remote.
* `REMOVEEXPORTDIRECTORY Directory`
Requests the remote remove an exported directory.
If the remote does not use directories, or REMOVEEXPORT cleans up
directories that are empty, this does not need to be implemented.
The directory will be in the form of a relative path, and may contain path
separators, whitespace, and other special characters.
Typically the directory will be empty, but it could possibly contain
files or other directories, and it's ok to remove those.
* `REMOVEEXPORTDIRECTORY-SUCCESS`
Indicates that a `REMOVEEXPORTDIRECTORY` was done successfully.
* `REMOVEEXPORTDIRECTORY-FAILURE`
Indicates that a `REMOVEEXPORTDIRECTORY` failed for whatever reason.
Should not be returned if the directory did not exist.
* `RENAMEEXPORT Key NewName`
Requests the remote rename a file stored on it from the previously
provided Name to the NewName. Remotes that support exports but not
renaming do not need to implement this.
* `RENAMEEXPORT-SUCCESS Key`
Indicates that a `RENAMEEXPORT` was done successfully.
* `RENAMEEXPORT-FAILURE Key`
Indicates that a `RENAMEEXPORT` failed for whatever reason.
More optional requests may be added, without changing the protocol version,
so if an unknown request is seen, don't crash, just reply with

View file

@ -0,0 +1,303 @@
This is an appendix to the [[external_special_remote_protocol]].
Some special remotes interface to a key/value datastore using keys that are
eg hashes, and it won't make sense for them to implement any of this.
When a special remote interfaces with something that looks like a directory
of files, the simple export interface can be implemented to allow the
[[git-annex-export]] command to be used to store file trees on the special
remote.
If other tools can write files to the special remote too, the import/export
interface can be implemented. This allows for both [[git-annex-import]] and
[[git-annex-export]] to be used with the special remote.
[[!toc]]
## simple export interface
git-annex will use this when the special remote is initialized with
exporttree=yes but without importtree=yes and indicates that it supports
exports.
These are requests git-annex sends to the special remote program.
Once the special remote has finished performing a request, it
should send one of the listed replies. Or, if it does not support
a request, it can reply with `UNSUPPORTED-REQUEST`.
* `EXPORTSUPPORTED`
Used to check if a special remote supports exports.
Note that this request may be made before or after `PREPARE`.
* `EXPORTSUPPORTED-SUCCESS`
Indicates that it makes sense to export to this special remote.
* `EXPORTSUPPORTED-FAILURE`
Indicates that it does not make sense to export to this special remote.
* `EXPORT Name`
Comes immediately before each of the following requests,
specifying the name of the exported file. It will be in the form
of a relative path, and may contain path separators, whitespace,
and other special characters.
No response is made to this message.
* `TRANSFEREXPORT STORE|RETRIEVE Key File`
Requests the transfer of a File on local disk to or from the previously
provided Name on the special remote.
Note that it's important that, while a file is being stored,
`CHECKPRESENTEXPORT` not indicate it's present until all the data has
been transferred.
While the transfer is running, the remote can send any number of
`PROGRESS` messages. Once the transfer is complete, it finishes by
sending one of these replies:
* `TRANSFER-SUCCESS STORE|RETRIEVE Key`
Indicates the transfer completed successfully.
* `TRANSFER-FAILURE STORE|RETRIEVE Key ErrorMsg`
Indicates the transfer failed.
* `CHECKPRESENTEXPORT Key`
Requests the remote to check if the previously provided Name is present
in it.
* `CHECKPRESENT-SUCCESS Key`
Indicates that a content has been positively verified to be present in the
remote.
* `CHECKPRESENT-FAILURE Key`
Indicates that a contents 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 content is
present in the remote. (Perhaps the remote cannot be contacted.)
* `REMOVEEXPORT Key`
Requests the remote to remove content stored by `TRANSFEREXPORT`
with the previously provided Name.
* `REMOVE-SUCCESS Key`
Indicates the content has been removed from the remote. May be returned when
the content was already not present.
* `REMOVE-FAILURE Key ErrorMsg`
Indicates that the content was unable to be removed from the remote.
* `REMOVEEXPORTDIRECTORY Directory`
Requests the remote remove an exported directory.
If the remote does not use directories, or `REMOVEEXPORT` cleans up
directories that are empty, this does not need to be implemented.
The directory will be in the form of a relative path, and may contain path
separators, whitespace, and other special characters.
Typically the directory will be empty, but it could possibly contain
files or other directories, and it's ok to remove those.
* `REMOVEEXPORTDIRECTORY-SUCCESS`
Indicates that a `REMOVEEXPORTDIRECTORY` was done successfully.
* `REMOVEEXPORTDIRECTORY-FAILURE`
Indicates that a `REMOVEEXPORTDIRECTORY` failed for whatever reason.
Should not be returned if the directory did not exist.
* `RENAMEEXPORT Key NewName`
Requests the remote rename a file stored on it from the previously
provided Name to the NewName. Remotes that support exports but not
renaming do not need to implement this.
* `RENAMEEXPORT-SUCCESS Key`
Indicates that a `RENAMEEXPORT` was done successfully.
* `RENAMEEXPORT-FAILURE Key`
Indicates that a `RENAMEEXPORT` failed for whatever reason.
## import/export interface
(This part is a draft, not implemented yet.)
git-annex will use this interface when the special remote is
initialized with both exporttree=yes and importtree=yes and indicates
that it supports both imports and exports.
### content identifiers
The special remote needs to have some way to identify a particular version of a
file. This is called a ContentIdentifier. A good ContentIdentifier needs to:
* Be stable, so when a file has not changed, its content identifier
remains the same.
* Change when a file is modified.
* Be as unique as possible, but not necessarily fully unique.
A hash of the content would be ideal.
A (size, mtime, inode) tuple is as good a content identifier as git uses in
its index.
* Be reasonably short, since it will be stored in the git-annex branch.
It's up to the implementor of a external special remote program what
to use for their ContentIdentifier, but not meeting those criteria
will leas to unhappy users, and it's better not to implement this interface if
you can't do it well.
### protocol messages
These are requests that git-annex sends to the special remote
program. Once the special remote has finished performing a request,
it should send one of the listed replies. Or, if it does not
support a request, it can reply with `UNSUPPORTED-REQUEST`.
* `EXPORTSUPPORTED`
Used to check if a special remote supports exports.
Note that this request may be made before or after `PREPARE`.
* `EXPORTSUPPORTED-SUCCESS`
Indicates that it makes sense to use this special remote as an export.
* `EXPORTSUPPORTED-FAILURE`
Indicates that it does not make sense to use this special remote as an
export.
* `IMPORTSUPPORTED`
Used to check if a special remote supports imports.
Note that this request may be made before or after `PREPARE`.
* `IMPORTSUPPORTED-SUCCESS`
Indicates that it makes sense to import from this special remote.
* `IMPORTSUPPORTED-FAILURE`
Indicates that it does not make sense to import from this special remote.
* `LISTIMPORTABLECONTENTS`
Used to get a list of all the files that are stored in the special
remote. A block of responses
can be made to this, which must always end with `END`.
* `CONTENT Size Name`
An file stored in the special remote. The Size is its size
in bytes. The Name is the name of the file on the remote,
in the form of a relative path, and may contain path separators,
whitespace, and other special characters.
Always followed by `CONTENTIDENTIFIER`.
* `CONTENTIDENTIFIER ContentIdentifier`
Provide the ContentIdentifier for the previous `CONTENT`.
* `HISTORY`
When a special remote stores historical versions of files,
this can be used to list those versions. It opens a new
block of responses. This can be repeated any number of times
(indicating a branching history), and histories can also
be nested multiple levels deep.
* `END`
Indicates the end of a block of responses.
* `LOCATION Name`
Comes before each of the following requests,
specifying the name of the file on the remote. It will be in the
form of a relative path, and may contain path separators,
whitespace, and other special characters.
No response is made to this message.
* `EXPECTED ContentIdentifier`
Comes before each of the following requests, specifying the
ContentIdentifier that is expected to be present on the remote.
* `NOTHINGEXPECTED`
If no ContentIdentifier is expected to be present, this is sent
rather than `EXPECTED`.
* `RETRIEVEEXPORTEXPECTED File`
Retrieves the content of a file from the special remote
to the File on local disk. Must take care to only retrieve
content that has the ContentIdentifier specified by
by `EXPECTED`.
While the transfer is running, the remote can send any number of
`PROGRESS` messages. Once the transfer is complete, it finishes by
sending one of these replies:
* `RETRIEVE-SUCCESS`
Indicates that the retrieve was successful.
* `RETRIEVE-FAILURE ErrorMsg`
Indicates the retrieve failed.
* `STOREEXPORTEXPECTED Key File`
Stores the content of File on the local disk to the previously
provided Name on the remote. If the Name already exists on the remote,
must take care to only overwrite it when it has the
ContentIdentifier that was previously provided by `EXPECTED`.
If some other content has been written to the Name,
it should not overwrite it.
While the transfer is running, the remote can send any number of
`PROGRESS` messages. Once the transfer is complete, it finishes by
sending one of these replies:
* `STORE-SUCCESS Key ContentIdentifier`
Indicates that the store was successful. The ContentIdentifier
must be for the content that was stored.
* `STORE-FAILURE Key ErrorMsg`
Indicates the store failed.
* `CHECKPRESENTEXPORTEXPECTED Key`
Requests the remote to check if the previously provided Name
is present in it, and still has the ContentIdentifier that was
previously provided by `EXPECTED`.
* `CHECKPRESENT-SUCCESS Key`
Indicates that a content has been positively verified to be present
in the remote.
* `CHECKPRESENT-FAILURE Key`
Indicates that a content has been positively verified to not be
present in the remote, or does not have the expected
ContentIdentifier.
* `CHECKPRESENT-UNKNOWN Key ErrorMsg`
Indicates that it is not currently possible to verify if content is
present in the remote. (Perhaps the remote cannot be contacted.)
* `REMOVEEXPORTEXPECTED Key`
Requests the remote to remove the content at the previously
provided Name, but only when it matches the ContentIdentifier
that was provided by `EXPECTED`.
* `REMOVE-SUCCESS Key`
Indicates the content has been removed from the remote. May be returned when
the content was already not present.
* `REMOVE-FAILURE Key ErrorMsg`
Indicates that the content was unable to be removed from the remote.
* `REMOVEEXPORTDIRECTORYWHENEMPTY Directory`
Requests the remote remove an exported directory, so long as it's empty.
If the remote does not use directories, or `REMOVEEXPORTEXPECTED`
cleans up directories that are empty, this does not need to be implemented.
The directory will be in the form of a relative path, and may contain path
separators, whitespace, and other special characters.
* `REMOVEEXPORTDIRECTORY-SUCCESS`
Indicates that the directory was removed, or was not empty.
* `REMOVEEXPORTDIRECTORY-FAILURE`
Indicates that the directory was empty, but could not be
removed for some reason.
## protocol example
The protocol starts off with VERSION etc as usual, and
then git-annex asks the special remote if it supports
export and import, which it does:
VERSION 1
EXTENSIONS INFO
EXTENSIONS
PREPARE
EXPORTSUPPORTED
EXPORTSUPPORTED-SUCCESS
IMPORTSUPPORTED
IMPORTSUPPORTED-SUCCESS
git-annex asks for a list of files stored in the special remote:
LISTIMPORTABLECONTENTS
Which in the simple case looks like this:
CONTENT 100 foo
CONTENTIDENTIFIER 100 48511528411921470
CONTENT 200 bar
CONTENTIDENTIFIER 200 48511528411963410
END
Or it could look like this, for a special remote that supports
versions, and has two branches of history, with one branch having
several different versions of the file "foo", and the second
branch having a single version. Here the blocks have been indented to aid
understanding; the real protocol does not include indenation.
CONTENT 100 foo
CONTENTIDENTIFIER 100 48511528411921470
CONTENT 200 bar
CONTENTIDENTIFIER 200 48511528411963410
HISTORY
CONTENT 99 foo
CONTENTIDENTIFIER 99 2113620116963530
HISTORY
CONTENT 1 foo
CONTENTIDENTIFIER 1 2110338579019192
END
END
HISTORY
CONTENT 88 foo
CONTENTIDENTIFIER 88 2104982727272727
END
END
(Note that "bar" is a new file; it was not present in any
of the older versions.)
Next git-annex asks for the content of a file to be retrieved.
LOCATION foo
EXPECTED 100 48511528411921470
RETRIEVEEXPORTEXPECTED tmpfile
But, the file "foo" has been modified and so the
ContentIdentifier no longer matches.
RETRIEVE-FAILURE content has changed