The failure to set a HEAD ref, due to quourum, during a fetch should not fail
the fetch entirely.
Instead, log the success and failure, or return an error in other cases.
In fact, any failure to set the head could have resulted in notifications not
being sent, nor caching to occur.
Ensure that remote branches can be delete via the `-d` flag. This
includes the fact that one can delete the `refs/heads/patches`
branches, as long as they are owned by the current operator.
This is meant to record in Radicle that automated "jobs" have been run
on a repository. The job might be, for example, a CI run that builds
the software and runs its tests. The recording is done in a "job COB",
which can be in three states:
* fresh -- when the job has been triggered, but has not yet started running
* running -- when it's running
* finished -- when it's finished running
The finished state also records whether the job was successful or if
it failed.
A job COB records the git commit that it runs on, and the "run ID" of
the job. The run ID represents an external identifier, such as one
assigned by a remote CI system. The COB can optionally store a URL
related to the job, such as to the build log from CI.
Add the "rad job" subcommand to create and manage job COBs. For
production use, the COBs should be created and updated using
`heartwood` as a library instead of running "rad job", if at all
possible. However, "rad job list" lists the jobs that have been run on
the repository.
The COB type name is xyz.radicle.beta.job, until we've gained
experience with the COB and its implementation and are ready to
declare it stable.
Signed-off-by: Lars Wirzenius <liw@liw.fi>
Adds `set`, `add`, `remove`, `delete` to `rad config`.
Note that the changes will affect the configuration file, but not the
running instances. For changes to be reflected in the running instances
the node would need to be restarted.
We ensure that a `rad/root` ref is included in the signed refs file
under `rad/sigrefs` for all remotes. This prevents a certain kind of
"grafting" attack where signed refs can be copied between repositories,
by having the peer sign over the identity root together with the data refs.
When verifying signed refs, we ensure that the ref is present and points
to an identity branch root that matches the repository identity containing
the signed refs.
Alternatives: lots of alternatives were considered, but this one doesn't
introduce any changes to the signing. The `rad/id/root` name was
considered but is invalid due to `rad/id`.
Add a fetch refspec to fetch tags from a Radicle remote. The
`--no-tag` option is also included. This is to ensure that it is easy
to collaborate by having tags placed in the remote namespace of
another peer. However, if the namespace is the default `rad` remote,
then tags are expected to be allowed -- this is to pave way for the
feature of canonical tags.
In the tests, the `--tags` option is removed -- and is generally
recommended that it is not used. This is to ensure that it does not
override the `--no-tag` option.
When pushing to the default branch and updating the canonical head,
check to see if any merged patches are reverted due to this change.
If so, make sure the COB cache reflects this.
The `rad issue edit` and `rad issue comment` subcommands were not included in
the announce check. Since these are considered write commands, they should also
announce when executed.
Add the `rad unblock` command for reversing the effect of blocking an NID or RID.
In both cases, the entry is removed from the DB, if the policy was set to block
-- otherwise it is a no-op.
This adds an option to `rad init` to initialize a working copy with
an existing radicle repository in storage:
rad init --existing <rid>
This sets up the remote(s) and configures the repo for you.
If a peer had created any references but was also missing the
canonical branch, the `rad id update` command will fail when adding
that peer as a delegate.
Instead, missing delegates and missing default branches are tracked
during verification. If the number of missing delegates means the
`threshold` cannot be met, then the errors are returned.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
The patch creation flow would be partially interrupted when creating a
patch via a detached HEAD state. The creation of an upstream branch
would fail since there is no branch to set an upstream for. It would
result in the following error:
✓ Patch 6035d2f582afbe01ff23ea87528ae523d76875b6 opened
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
! [remote rejected] HEAD -> refs/patches (git: reference 'HEAD' is neither a local nor a remote branch.; class=Invalid (3))
error: failed to push some refs to 'rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi'
To fix this, the reference that's resolved is checked to see if it a
local branch. If not, it will return early.
The behaviour is tested in the `rad-patch-detached-head` example.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
The rules for checking the quorum of the remote helper, when pushing to the
canonical branch, can prevent the operator from even attempting to try converge
to a state of agreeance.
Instead, the checking of the quorum rules are relaxed. It is still the case that
if the peer is pushing a diverging commit while in a working state they are
warned and the push does not go through. However, there are two cases where it
is fine to force push a change:
1. When pushing a new tip, as a delegate, there is still a canonical tip and the
new tip still converges with the history, i.e. it is equal to, behind, or
ahead of another delegate tip.
2. If there is no quorum in the current state, for example there were multiple
concurrent pushes, then the peer is free to continue to push to their default
branch in attempt to converge with the other peers.
The example tests ensure that these cases are covered, while also preserving the
old behaviour.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
If a delegate is in a diverged state from the canonical head, ensure
that they can easily reset to another delegate's head to converge
again.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
Gives the same options to `rad seed` as `rad sync --fetch`.
Allows seeding and syncing from specific seeds in one command:
rad seed <rid> --from <nid>
Useful for seeding private repos on public nodes.
Instead of producing an error when there is no update during `rad id
update`, a message that the document is up to date is printed. The
command is considered is considered successful.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
The previous implementation of using the `--allow` option in `rad id
update` would be an absolute list, rather than additive. That is, if
there were existing DIDs not passed in via `--allow` then they would
be remove.
Change this behaviour to check the existing value of the document's
allow list, and add to it if `--allow` is specified.
To enable the user to also remove a DID, the `--disallow` option is
also added.
The correct usage of these options is improved by checking the
validity of the `--visibility` option being used, the current state of
the repository's privacy, and the use of the `--allow` and
`--disallow` options.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
Previously, our advertized inventory was not always correct: when we
stopped seeding a repository, it was still advertised as part of our
inventory until node restart, because the `Storage` type doesn't have
access to seeding policies.
In this change, we remove the concept of inventory from `Storage` and
make the authoritative place for it the routing table in our database.
To make this work, we have to add our node to the database on profile
creation, to not violate the foreign key constraint on the routing
table. Hence, the tests are changed to include our alias which is now
always available.
```
--- Expected
++++ actual: stdout
1 - branch 'master' set up to track 'origin/master'.
1 + Branch 'master' set up to track remote branch 'master' from 'origin'.
Exit status: 0
```
As per @fintohaps' suggestion, this gets the tests passing again on git 2.34.
Co-Authored-By: fintohaps <fintan@monoidal.tech>
Signed-off-by: Yorgos Saslis <yorgos.work@proton.me>
This is a change to the `config.json` file which removes certain options
that are best not touched and changes some options to make them easier
to work with.
1. We change the default journaling mode to "wal" and remove the config
option.
2. We remove the option to set the peer connection "target", as it's not
a good idea to set this to a different value, as it affects the
network.
3. We combine seeding policy & scope, since there's no need to set the
scope when the policy is "block". In that case, we always want to
block "all" remotes. The new policy configuration has the following
schema:
{ seedingPolicy: { default: "block" | "allow", scope?: "all" | "followed" } }
The "scope" key is not used when "default" is set to "block".
4. We add an `extra` field to the node config for options that are not
recognized. We use this to warn the user.
In the case of an out-of-sync local node, we were showing the wrong tip.
Additionally, mark your tip as unannounced if it isn't announced. This
isn't fool-proof, but can be useful to debug certain issues.
* Remove `rad sync --force` flag
* Remove `rad clone --private` flag
These flags are no longer necessary. Simplify specifying which seed
to fetch from with `--seed` is enough.
*Breaking change* The `tor` configuration field is no longer
supported. Users must remove that field from their config.
Allows for a mixed mode, where regular addresses bypass the Tor proxy,
while onion addresses go through it.
When `onion.mode` is set to "forward", Tor connections are fowarded to
the global proxy, and if it isn't set, to the OS's DNS resolution.
For mixed mode, a global proxy simply isn't set, so that IP/DNS is not
proxied.
To ensure that the `rad id` command does not modify the project payload without
it being able to be deserialized into the `Project` type, the command performs
this check throught the `project` method, and returns an error if this fails.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
To improve the user experience of `rad init`, the events listener waits for
upload-pack messages indefinitely. The spinner reports back the upload progress
over time.
This process can be cancelled via Ctrl+C without affecting the announcement,
since that is happening in the background.
To also improve the experience, the remote NIDs that have successfully synced
are reported to the terminal.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
Add a test to confirm that the identity can still be deserialized when an
unknown field is added.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
The rate-limitter gets hit on connect, due to historical gossip messages
being exchanged. This results in a high initial burst that needs to be
accounted for.
Relay now has three values: "always", "never" and "auto".
The first two operate like the previous `true`/`false`. The
new (default) value turns relaying on for nodes with public (external)
addresses and off for nodes without. This should reduce redundant traffic on
the network, that was causing the rate limiters to trigger.
With the increase in traffic on the network after launch, the old
defaults don't make sense anymore.
Longer term, we should look into throttling outgoing messages as well,
prioritizing original messages over relayed messages.
If multiple ids are specified for `rad inbox clear`, it would report
that only 1 item was cleared, when in fact multiple were.
This was found to be due to the SQL code returning a change count of
`1`. This is likely due to the way the statement is being reset each
time. The `sqlite` library does not seem to easily support the usage
of `IN` in a `WHERE` clause. So instead, the `count` is aggregated in
the loop and returned instead.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett