aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortechknowlogick <techknowlogick@gitea.io>2023-04-17 13:07:13 -0400
committerGitHub <noreply@github.com>2023-04-17 13:07:13 -0400
commit4014200021a1997283c779a815fe9e5febf1fda1 (patch)
tree1ef45d3e316cfc1fd31a35fcf69aa88c230f931a
parent1819c4b59b81ba4db2a38d3b3dc81f29102fde51 (diff)
downloadgitea-4014200021a1997283c779a815fe9e5febf1fda1.tar.gz
gitea-4014200021a1997283c779a815fe9e5febf1fda1.zip
add CLI command to register runner tokens (#23762)
This is a CLI command to generate new tokens for the runners to register with Fix https://github.com/go-gitea/gitea/issues/23643 --------- Co-authored-by: delvh <dev.lh@web.de>
-rw-r--r--cmd/actions.go56
-rw-r--r--docs/content/doc/administration/command-line.en-us.md25
-rw-r--r--main.go1
-rw-r--r--modules/private/actions.go27
-rw-r--r--routers/private/actions.go91
-rw-r--r--routers/private/internal.go1
6 files changed, 201 insertions, 0 deletions
diff --git a/cmd/actions.go b/cmd/actions.go
new file mode 100644
index 0000000000..66ad336da5
--- /dev/null
+++ b/cmd/actions.go
@@ -0,0 +1,56 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package cmd
+
+import (
+ "fmt"
+
+ "code.gitea.io/gitea/modules/private"
+ "code.gitea.io/gitea/modules/setting"
+
+ "github.com/urfave/cli"
+)
+
+var (
+ // CmdActions represents the available actions sub-commands.
+ CmdActions = cli.Command{
+ Name: "actions",
+ Usage: "",
+ Description: "Commands for managing Gitea Actions",
+ Subcommands: []cli.Command{
+ subcmdActionsGenRunnerToken,
+ },
+ }
+
+ subcmdActionsGenRunnerToken = cli.Command{
+ Name: "generate-runner-token",
+ Usage: "Generate a new token for a runner to use to register with the server",
+ Action: runGenerateActionsRunnerToken,
+ Aliases: []string{"grt"},
+ Flags: []cli.Flag{
+ cli.StringFlag{
+ Name: "scope, s",
+ Value: "",
+ Usage: "{owner}[/{repo}] - leave empty for a global runner",
+ },
+ },
+ }
+)
+
+func runGenerateActionsRunnerToken(c *cli.Context) error {
+ ctx, cancel := installSignals()
+ defer cancel()
+
+ setting.InitProviderFromExistingFile()
+ setting.LoadCommonSettings()
+
+ scope := c.String("scope")
+
+ respText, extra := private.GenerateActionsRunnerToken(ctx, scope)
+ if extra.HasError() {
+ return handleCliResponseExtra(extra)
+ }
+ _, _ = fmt.Printf("%s\n", respText)
+ return nil
+}
diff --git a/docs/content/doc/administration/command-line.en-us.md b/docs/content/doc/administration/command-line.en-us.md
index d3362e5731..4d01d6e640 100644
--- a/docs/content/doc/administration/command-line.en-us.md
+++ b/docs/content/doc/administration/command-line.en-us.md
@@ -551,3 +551,28 @@ Restore-repo restore repository data from disk dir:
- `--owner_name lunny`: Restore destination owner name
- `--repo_name tango`: Restore destination repository name
- `--units <units>`: Which items will be restored, one or more units should be separated as comma. wiki, issues, labels, releases, release_assets, milestones, pull_requests, comments are allowed. Empty means all units.
+
+### actions generate-runner-token
+
+Generate a new token for a runner to use to register with the server
+
+- Options:
+ - `--scope {owner}[/{repo}]`, `-s {owner}[/{repo}]`: To limit the scope of the runner, no scope means the runner can be used for all repos, but you can also limit it to a specific repo or owner
+
+To register a global runner:
+
+```
+gitea actions generate-runner-token
+```
+
+To register a runner for a specific organization, in this case `org`:
+
+```
+gitea actions generate-runner-token -s org
+```
+
+To register a runner for a specific repo, in this case `username/test-repo`:
+
+```
+gitea actions generate-runner-token -s username/test-repo
+```
diff --git a/main.go b/main.go
index eeedf54c27..1589fa97db 100644
--- a/main.go
+++ b/main.go
@@ -75,6 +75,7 @@ arguments - which can alternatively be run by running the subcommand web.`
cmd.CmdDocs,
cmd.CmdDumpRepository,
cmd.CmdRestoreRepository,
+ cmd.CmdActions,
}
// Now adjust these commands to add our global configuration options
diff --git a/modules/private/actions.go b/modules/private/actions.go
new file mode 100644
index 0000000000..be24e16d3f
--- /dev/null
+++ b/modules/private/actions.go
@@ -0,0 +1,27 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package private
+
+import (
+ "context"
+
+ "code.gitea.io/gitea/modules/setting"
+)
+
+// Email structure holds a data for sending general emails
+type GenerateTokenRequest struct {
+ Scope string
+}
+
+// GenerateActionsRunnerToken calls the internal GenerateActionsRunnerToken function
+func GenerateActionsRunnerToken(ctx context.Context, scope string) (string, ResponseExtra) {
+ reqURL := setting.LocalURL + "api/internal/actions/generate_actions_runner_token"
+
+ req := newInternalRequest(ctx, reqURL, "POST", GenerateTokenRequest{
+ Scope: scope,
+ })
+
+ resp, extra := requestJSONResp(req, &responseText{})
+ return resp.Text, extra
+}
diff --git a/routers/private/actions.go b/routers/private/actions.go
new file mode 100644
index 0000000000..b7e416f56a
--- /dev/null
+++ b/routers/private/actions.go
@@ -0,0 +1,91 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package private
+
+import (
+ "errors"
+ "fmt"
+ "net/http"
+ "strings"
+
+ actions_model "code.gitea.io/gitea/models/actions"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/context"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/private"
+ "code.gitea.io/gitea/modules/util"
+)
+
+// GenerateActionsRunnerToken generates a new runner token for a given scope
+func GenerateActionsRunnerToken(ctx *context.PrivateContext) {
+ var genRequest private.GenerateTokenRequest
+ rd := ctx.Req.Body
+ defer rd.Close()
+
+ if err := json.NewDecoder(rd).Decode(&genRequest); err != nil {
+ log.Error("%v", err)
+ ctx.JSON(http.StatusInternalServerError, private.Response{
+ Err: err.Error(),
+ })
+ return
+ }
+
+ owner, repo, err := parseScope(ctx, genRequest.Scope)
+ if err != nil {
+ log.Error("%v", err)
+ ctx.JSON(http.StatusInternalServerError, private.Response{
+ Err: err.Error(),
+ })
+ }
+
+ token, err := actions_model.GetUnactivatedRunnerToken(ctx, owner, repo)
+ if errors.Is(err, util.ErrNotExist) {
+ token, err = actions_model.NewRunnerToken(ctx, owner, repo)
+ if err != nil {
+ err := fmt.Sprintf("error while creating runner token: %v", err)
+ log.Error("%v", err)
+ ctx.JSON(http.StatusInternalServerError, private.Response{
+ Err: err,
+ })
+ return
+ }
+ } else if err != nil {
+ err := fmt.Sprintf("could not get unactivated runner token: %v", err)
+ log.Error("%v", err)
+ ctx.JSON(http.StatusInternalServerError, private.Response{
+ Err: err,
+ })
+ return
+ }
+
+ ctx.PlainText(http.StatusOK, token.Token)
+}
+
+func parseScope(ctx *context.PrivateContext, scope string) (ownerID, repoID int64, err error) {
+ ownerID = 0
+ repoID = 0
+ if scope == "" {
+ return ownerID, repoID, nil
+ }
+
+ ownerName, repoName, found := strings.Cut(scope, "/")
+
+ u, err := user_model.GetUserByName(ctx, ownerName)
+ if err != nil {
+ return ownerID, repoID, err
+ }
+
+ if !found {
+ return u.ID, repoID, nil
+ }
+
+ r, err := repo_model.GetRepositoryByName(u.ID, repoName)
+ if err != nil {
+ return ownerID, repoID, err
+ }
+ repoID = r.ID
+ return ownerID, repoID, nil
+}
diff --git a/routers/private/internal.go b/routers/private/internal.go
index 4acede3370..b4d32c37a6 100644
--- a/routers/private/internal.go
+++ b/routers/private/internal.go
@@ -77,6 +77,7 @@ func Routes() *web.Route {
r.Get("/manager/processes", Processes)
r.Post("/mail/send", SendEmail)
r.Post("/restore_repo", RestoreRepo)
+ r.Post("/actions/generate_actions_runner_token", GenerateActionsRunnerToken)
return r
}