Commit be3e6f28d7
be3e6f28d76c9c775997dea9bddf5047095d0be9
parent: 4cfe0c4c82
Verified · cmc
cmc <hello@cleberg.net> · 2026-09-12 06:00 UTC
control, cli, wiki: admin runners remove, with forget as an alias for one release
Ref #183
.gitbay/wiki/Admin.org
+1 −1
| @@ -434,7 +434,7 @@ podman. A runner without it builds trusted commits only. |
| 434 | 434 | that has polled as a runner: the account, the key's fingerprint, when it |
| 435 | 435 | last polled, the repositories it may claim — its attachments for a runner |
| 436 | 436 | key, the =-repos= it asked for or =any= for an admin key — and the build |
| 437 | | it holds; =admin runners forget <fingerprint>= drops the row for a key |
| 437 | it holds; =admin runners remove <fingerprint>= (=forget= until the next release) drops the row for a key |
| 438 | 438 | that polled by mistake, the key itself untouched. =admin runners= also |
| 439 | 439 | heads the list with the queue: builds |
| 440 | 440 | pending now, and over the last day how many were claimed, how long they |
cmd/gitbay/main.go
+2 −1
| @@ -129,7 +129,8 @@ func newRoot() *cobra.Command { |
| 129 | 129 | pass("invite", "issue a registration invite and mail its code: --email <address>", passOpts{server: []string{"admin", "invite"}}), |
| 130 | 130 | pass("stats", "instance statistics: counts and per-repository disk usage", passOpts{server: []string{"admin", "stats"}}), |
| 131 | 131 | withSub(pass("runners", "the build queue and runner keys: last poll, scope, the build each holds", passOpts{server: []string{"admin", "runners"}}), |
| 132 | | pass("forget", "drop a key's heartbeat row: <fingerprint>", passOpts{server: []string{"admin", "runners", "forget"}})), |
| 132 | pass("remove", "drop a key's heartbeat row: <fingerprint>", passOpts{server: []string{"admin", "runners", "remove"}}), |
| 133 | pass("forget", "alias of remove: <fingerprint>", passOpts{server: []string{"admin", "runners", "forget"}})), |
| 133 | 134 | group("repo", "any repository, for moderation (audited)", |
| 134 | 135 | pass("list", "every repository with size and last push: [--owner o] [--visibility v] [--limit n] [--cursor c]", passOpts{server: []string{"admin", "repo", "list"}}), |
| 135 | 136 | pass("archive", "archive a repository: <owner/name>", passOpts{server: []string{"admin", "repo", "archive"}}), |
internal/control/admin.go
+8 −2
| @@ -33,8 +33,14 @@ func init() { |
| 33 | 33 | Summary: "the build queue and runner accounts: last poll, scope, the build each holds (instance admins)", |
| 34 | 34 | Usage: "admin runners", |
| 35 | 35 | ReadOnly: true, SSHOnly: true, Run: runAdminRunners}) |
| 36 | | register(Command{Path: []string{"admin", "runners", "forget"}, |
| 36 | register(Command{Path: []string{"admin", "runners", "remove"}, |
| 37 | 37 | Summary: "drop a key's runner heartbeat row, e.g. one that polled once by mistake (instance admins)", |
| 38 | Usage: "admin runners remove <fingerprint>", |
| 39 | SSHOnly: true, Run: runAdminRunnersForget}) |
| 40 | // forget is the name this shipped under in v1.18; remove is the verb |
| 41 | // every other noun uses. Both stay for one release. |
| 42 | register(Command{Path: []string{"admin", "runners", "forget"}, |
| 43 | Summary: "alias of admin runners remove", |
| 38 | 44 | Usage: "admin runners forget <fingerprint>", |
| 39 | 45 | SSHOnly: true, Run: runAdminRunnersForget}) |
| 40 | 46 | register(Command{Path: []string{"admin", "repo", "list"}, |
| @@ -62,7 +68,7 @@ func init() { |
| 62 | 68 | // requireInstanceAdmin gates the admin noun. -1 means proceed. |
| 63 | 69 | func requireInstanceAdmin(c *Ctx) int { |
| 64 | 70 | if !c.User.IsAdmin { |
| 65 | | return c.fail(protocol.ExitDenied, "admin commands are for instance admins") |
| 71 | return c.fail(protocol.ExitDenied, "admin commands are for instance admins; ask one") |
| 66 | 72 | } |
| 67 | 73 | return -1 |
| 68 | 74 | } |