173 lines
5.1 KiB
Markdown
173 lines
5.1 KiB
Markdown
# goals
|
|
|
|
* be configured like a regular git remote, with an unusual url
|
|
or other configuration
|
|
* receive notifications when a remote has received new commits,
|
|
and take some action
|
|
* optionally, do receive-pack and send-pack to a remote that
|
|
is only accessible over an arbitrary network transport
|
|
(like assistant does with XMPP)
|
|
* optionally, send/receive git-annex objects to remote
|
|
over an arbitrary network transport
|
|
|
|
# difficulties
|
|
|
|
* authentication & configuration
|
|
* multiple nodes may be accessible over a single network transport,
|
|
with it desirable to sync with any/all of them. For example, with
|
|
XMPP, there can be multiple friends synced with. This means that
|
|
one git remote can map to multiple remote nodes. Specific to git-annex,
|
|
this means that a set of UUIDs known to be associated with the remote
|
|
needs to be maintained, while currently each remote can only have one
|
|
annex-uuid in .git/config.
|
|
|
|
# payoffs
|
|
|
|
* support [[assistant/telehash]]!
|
|
* Allow running against a normal ssh git remote. This would run
|
|
git-annex-shell on the remote, watching for changes, and so be able to
|
|
notify when a commit was pushed to the remote repo. This would let the
|
|
assistant immediately notice and pull. So the assistant would be fully
|
|
usable with a single ssh remote and no other configuration!
|
|
**do this first**
|
|
* clean up existing XMPP support, make it not a special case, and not
|
|
tightly tied to the assistant
|
|
* git-remote-daemon could be used independantly of git-annex,
|
|
in any git repository.
|
|
|
|
# design
|
|
|
|
Let git-remote-daemon be the name. Or for git-annex,
|
|
`git annex remotedaemon`.
|
|
|
|
It runs in one of two ways:
|
|
|
|
1. Forked to background, using a named pipe for the control protocol.
|
|
2. With --foreground, the control protocol goes over stdio.
|
|
|
|
Either way, behavior is the same:
|
|
|
|
* Get a list of remotes to act on by looking at .git/config
|
|
* Automatically notices when a remote has changes to branches
|
|
matching remote.$name.fetch, and pulls them down to the appropriate
|
|
location.
|
|
* When the control protocol informs it about a new ref that's available,
|
|
it offers the ref to any interested remotes.
|
|
|
|
# control protocol
|
|
|
|
This is an asynchronous protocol. Ie, either side can send any message
|
|
at any time, and the other side does not send a reply.
|
|
|
|
It is line based and intended to be low volume and not used for large data.
|
|
|
|
TODO: Expand with commands for sending/receiving git-annex objects, and
|
|
progress during transfer.
|
|
|
|
TODO: Will probably need to add something for whatever pairing is done by
|
|
the webapp.
|
|
|
|
## emitted messages
|
|
|
|
* `CONNECTED uri`
|
|
|
|
Sent when a connection has been made with a remote.
|
|
|
|
* `DISCONNECTED uri`
|
|
|
|
Sent when connection with a remote has been lost.
|
|
|
|
* `SYNCING uri`
|
|
|
|
Indicates that a pull or a push with a remote is in progress.
|
|
Always followed by DONESYNCING.
|
|
|
|
* `DONESYNCING uri 1|0`
|
|
|
|
Indicates that syncing with a remote is done, and either succeeded
|
|
(1) or failed (0).
|
|
|
|
* `WARNING uri string`
|
|
|
|
A message to display to the user about a remote.
|
|
|
|
## consumed messages
|
|
|
|
* `PAUSE`
|
|
|
|
The user has requested a pause.
|
|
git-remote-daemon should close connections and idle.
|
|
|
|
* `LOSTNET`
|
|
|
|
The network connection has been lost.
|
|
git-remote-daemon should close connections and idle.
|
|
|
|
* `RESUME`
|
|
|
|
Undoes PAUSE or LOSTNET.
|
|
Start back up network connections.
|
|
|
|
* `CHANGED ref ...`
|
|
|
|
Indicates that a ref is new or has changed. These can be offered to peers,
|
|
and peers that are interested in them can pull the content.
|
|
|
|
* `RELOAD`
|
|
|
|
Indicates that configs have changed. Daemon should reload .git/config
|
|
and/or restart.
|
|
|
|
Possible config changes include adding a new remote, removing a remote,
|
|
or setting `remote.<name>.annex-sync` to configure whether to sync with a
|
|
particular remote.
|
|
|
|
* `STOP`
|
|
|
|
Shut down git-remote-daemon
|
|
|
|
(When using stdio, it also should shutdown when it reaches EOF on
|
|
stdin.)
|
|
|
|
# encryption & authentication
|
|
|
|
For simplicity, the network transports have to do their own end-to-end
|
|
encryption. Encryption is not part of this design.
|
|
|
|
(XMPP does not do end-to-end encryption, but might be supported
|
|
transitionally.)
|
|
|
|
Ditto for authentication that we're talking to who we intend to talk to.
|
|
Any public key data etc used for authentication is part of the remote's
|
|
configuration (or hidden away in a secure chmodded file, if necessary).
|
|
This design does not concern itself with authenticating the remote node,
|
|
it just takes the auth token and uses it.
|
|
|
|
For example, in telehash, each node has its own keypair, which is used
|
|
or authentication and encryption, and is all that's needed to route
|
|
messages to that node.
|
|
|
|
# network level protocol
|
|
|
|
How do peers communicate with one another over the network?
|
|
|
|
This seems to need to be network-layer dependant. Telehash will need
|
|
one design, and git-annex-shell on a central ssh server has a very different
|
|
(and much simpler) design.
|
|
|
|
## ssh
|
|
|
|
`git-annex-shell notifychanges` is run, and speaks a simple protocol
|
|
over stdio to inform when refs on the remote have changed.
|
|
|
|
No pushing is done for CHANGED, since git handles ssh natively.
|
|
|
|
This is implemented and seems to work well.
|
|
|
|
## telehash
|
|
|
|
TODO
|
|
|
|
## xmpp
|
|
|
|
Reuse [[assistant/xmpp]]
|