Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Let the CLI cancel a run, not only the browser

deb024d49d894a5a51b1a5bdc07e66c672f113ab · Keenan Nemetz · 6d ago · parent 0c14f078

Let the CLI cancel a run, not only the browser

#168 promised the same account the same actions through either transport, and
canceling a running run had just become a browser-only action. The queue is
instance-side, so the CLI asks over the key it already pushes with:
`vole run cancel <id>` retires a queued run or asks a running one to stop, checks
the same maintainer capability the page checks, and writes the same audit record.
The server verb takes one repository and one run id and answers one line; the id
is the 26-character one in the run page URL.

The audit action is now `run.cancel` for both transports, because it is the same
action: an operator looking for canceled runs should not have to know which
surface asked.

Part of #162.

client/remote.go +25

@@ -9,6 +9,8 @@ import (
9 9 "os/exec"
10 10 "sort"
11 11 "strings"
12
13 voleid "github.com/rodent-software/vole/core/id"
12 14 )
13 15
14 16 // HostKeys is how this process verifies the SSH host key of the instance it talks
@@ -317,6 +319,29 @@ func MergeChange(gitDir, remote, id string) (string, error) {
317 319 return strings.TrimSpace(out), nil
318 320 }
319 321
322 // CancelRun cancels one queued run, or asks a running one to stop. The queue lives
323 // on the instance, so the CLI asks over the key it pushes with; the server checks the
324 // maintainer capability, records the audit line, and says which of the two happened.
325 // The id is the 26-character one the run page shows in its URL.
326 func CancelRun(gitDir, remote, runID string) (string, error) {
327 runID = strings.ToUpper(strings.TrimSpace(runID))
328 if !voleid.Valid(runID) {
329 return "", fmt.Errorf("%q is not a run id; use the 26-character id from the run page", runID)
330 }
331 host, port, path, err := SSHTarget(gitDir, remote)
332 if err != nil {
333 return "", err
334 }
335 if RepoNameFromPath(path) == "" {
336 return "", fmt.Errorf("%s does not name a repository", remote)
337 }
338 out, err := RunSSH(host, port, "vole-run-cancel "+quoteSSHArg(path)+" "+quoteSSHArg(runID))
339 if err != nil {
340 return "", err
341 }
342 return strings.TrimSpace(out), nil
343 }
344
320 345 // DispatchWorkflow queues a manual run of a workflow that declares
321 346 // workflow_dispatch. It is a write to the instance's queue, so the CLI asks over
322 347 // the same key-authenticated channel it pushes with; the server resolves the