When a merge is applied to a patch, we check whether the threshold
of delegates has been reached, at which point we set the patch status
to `merged`.
This requires threading the identity document oid through the "apply"
process.
Revision IDs are globally unique. Users will be able to use the
Revision ID in place of its patch ID.
Make `rad merge` refuse to merge an older revision unless the `--force`
option is given.
Using LWWReg::from will always set the clock value to the default,
which can end up being used wrong.
Instead, introduce a constructor method `initial` to indicate that it
should be used on initial construction, while `new` should be used for
newer values of the register.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
Support users with systemd integration by providing a systemd service
file. The file includes basic instructions for how to adapt to the
users context.
There are two scenarios it would be run in, as a system service, or as a
user service. The scenario as a user service is problematic.
`radicle-node` relies on ssh-agent or a clear text RAD_PASSPHRASE.
This fixes an issue that came up in tests where we would be reading
and writing to the database at the same time, and it would fail with
an error due to the lock being contended on.
Replaces pub accessors to struct fields with methods
Also creates some methods to compute necessary information
Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
The One variant caused many paint points for fetching logic, where it
was not necessary. It was only constructed in one place, which could
be replaced by using the variant that holds a set of keys.
Remove the Namespaces::One variant and rename Namespaces::Many to
Namespaces::Trusted.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
When a repository does not yet exist during a fetch, i.e. a clone,
then only delegates are being fetched.
Augment Namespaces::Many to hold the trusted and optional delegate peers
separately. Doing so allows the construction of the variant without
the repository existing, but tracking relationships existing.
This variant can then be used to build refspecs for both the trusted
peers and delegates when doing a cloning fetch.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
Previously, if a peer created a project which was replicated and then
moved to another setup, ultimately deleting that project, then they
would not be able to fetch it again since their remote namespace would
be excluded from the fetch.
This test confirms that a peer can remove their project and clone it
again from a peer that has replicated the project. This is simulated
by directly removing the project directory in the test and fetching
the project from the other peer.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
With the latest fetch updates, the test for fetching trusted remotes
can be enabled.
The caveat is that its expected behaviour is to fetch the delegate
upon a clone and fetch all trusted peers on a subsequent
fetch. Fetching all trusted peers is left as a follow-up task.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
The previous fetching logic had some pitfalls regarding its logic:
* Fetched 'rad' references could end up not being verifiable and leaving
the storage in a corrupt state
* Forced pushes would be prohibited, since they would be rejected by
the client side due to the refspecs being used.
The new approach is to stage a fetch in 2 steps. The first step is to
fetch the relevant `rad/id` and `rad/sigrefs` for verification. For
all remotes that are verified, fetch all references listed in their
respective `rad/sigrefs`, using the `+` marker in the refspec,
allowing to update for any force pushes -- note that this becomes a
safe operation since the `sigrefs` are signed by the remote that
created them.
To prevent unverifiable 'rad' references from polluting storage, all
fetch negotiations are done in a staging repository set up in a
temporary directory. All successful fetches are then transferred,
using the 'file://' protocol, from the temporary directory into the
radicle storage.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
Add a helper function for creating the `RefString`,
`refs/namespaces/<public key>`, for a given `PublicKey`.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
To be able to change the description of a patch revision, without the
need to create a new revision.
Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
Using LWWReg::from was giving subsequent actions
the same clock value as their predecessors.
This resulted in a Reject not being able
to turn into an Accept on a second review of a patch.
The solution is to use the clock value that was produced for the Op
and pass that into new, avoiding the call to from.
Co-authored-by: Fintan Halpenny <fintan.halpenny@gmail.com>
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
Introduce a canonical reference for refs/rad/id to aid in discovering
information about a repository without knowing a peer -- e.g. if a
peer wants to clone a new repository it needs to find out which peers
are delegates for that project, but does not know what their NIDs are
up front.
The approach mirrors the canonical `head` for a repository and
introduces useful constructors for `Doc`/`DocAt`.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
The tracked nodes include nodes marked tracked in the db, and
the delegates and `Namespaces::All` if it is a new repo.
Signed-off-by: Han Xu <keepsimple@gmail.com>
First, we make sure to always attempt reconnection to persistent peers,
no matter the reason.
Second, we don't re-attempt connections when an inbound peer
disconnects. This minimizes the chance of connections crossing.
Third, we clean up `session::Error`, and don't use it to signal a
missing session, since it doesn't really belong there.