From f633ec97041c1c29e6ce39dc6bd5b2ee27e2e7ff Mon Sep 17 00:00:00 2001 From: fuxiaohei <fuxiaohei@vip.qq.com> Date: Mon, 17 Oct 2022 21:21:43 +0800 Subject: [PATCH] feat(runner): create new token for creating new runner --- models/bots/runner_token.go | 32 +++++++++++++++++++++------ options/locale/locale_en-US.ini | 26 ++++++++++++++++++++++ routers/web/admin/runners.go | 38 +++++++++++++++++++++++++++----- routers/web/web.go | 1 + templates/admin/runner/edit.tmpl | 10 ++++----- templates/admin/runner/list.tmpl | 33 +++++++++++++++++++++++---- web_src/less/_runner.less | 9 ++++++++ 7 files changed, 128 insertions(+), 21 deletions(-) diff --git a/models/bots/runner_token.go b/models/bots/runner_token.go index a97d47cd47..097bc79bca 100644 --- a/models/bots/runner_token.go +++ b/models/bots/runner_token.go @@ -49,13 +49,6 @@ func init() { db.RegisterModel(new(RunnerToken)) } -// NewRunnerToken creates new runner token. -func NewRunnerToken(t *RunnerToken) error { - t.Token = base.EncodeSha1(gouuid.New().String()) - _, err := db.GetEngine(db.DefaultContext).Insert(t) - return err -} - // GetRunnerByToken returns a bot runner via token func GetRunnerToken(token string) (*RunnerToken, error) { var runnerToken RunnerToken @@ -81,3 +74,28 @@ func UpdateRunnerToken(ctx context.Context, r *RunnerToken, cols ...string) (err } return err } + +// NewRunnerToken creates a new runner token +func NewRunnerToken(ownerID, repoID int64) (*RunnerToken, error) { + runnerToken := &RunnerToken{ + OwnerID: ownerID, + RepoID: repoID, + IsActive: false, + // FIXME: why token is 36 chars? + Token: base.EncodeSha1(gouuid.New().String())[:36], + } + _, err := db.GetEngine(db.DefaultContext).Insert(runnerToken) + return runnerToken, err +} + +// GetUnactivatedRunnerToken returns a unactivated runner token +func GetUnactivatedRunnerToken(ownerID, repoID int64) (*RunnerToken, error) { + var runnerToken RunnerToken + has, err := db.GetEngine(db.DefaultContext).Where("owner_id=? AND repo_id=? AND is_active=0", ownerID, repoID).OrderBy("id DESC").Get(&runnerToken) + if err != nil { + return nil, err + } else if !has { + return nil, ErrRunnerTokenNotExist{} + } + return &runnerToken, nil +} diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 7cfaac0efd..5c9266050f 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3005,6 +3005,32 @@ notices.desc = Description notices.op = Op. notices.delete_success = The system notices have been deleted. +runners = Runners +runners.runner_manage_panel = Runners Management +runners.new = Create new Runner +runners.new_notice = Show runner installation documentation +runners.status = Status +runners.id = ID +runners.owner_type = Type +runners.description = Description +runners.labels = Labels +runners.latest_online = Last Online Time +runners.agent_labels = Agent Labels +runners.custom_labels = Custom Labels +runners.custom_labels_helper = Custom labels are labels that are not automatically added by the agent. They are added by the administrator. Use comma separated. +runners.runner_title = Runner +runners.task_list = Recent jobs on this runner +runners.edit_runner = Edit Runner +runners.update_runner = Update Changes +runners.update_runner_success = Runner updated successfully +runners.update_runner_failed = Failed to update runner +runners.delete_runner = Delete this runner +runners.delete_runner_success = Runner deleted successfully +runners.delete_runner_failed = Failed to delete runner +runners.delete_runner_header = Confirm to delete this runner +runners.delete_runner_notice = If job is running on this runner, it will be terminated and mark as failed. It may break building workflow. +runners.delete_runner_confirm = Delete this runner + [action] create_repo = created repository <a href="%s">%s</a> rename_repo = renamed repository from <code>%[1]s</code> to <a href="%[2]s">%[3]s</a> diff --git a/routers/web/admin/runners.go b/routers/web/admin/runners.go index cf7bddd291..65ebf5cc23 100644 --- a/routers/web/admin/runners.go +++ b/routers/web/admin/runners.go @@ -63,9 +63,26 @@ func Runners(ctx *context.Context) { return } + // ownid=0,repo_id=0,means this token is used for global + var token *bots_model.RunnerToken + token, err = bots_model.GetUnactivatedRunnerToken(0, 0) + if _, ok := err.(bots_model.ErrRunnerTokenNotExist); ok { + token, err = bots_model.NewRunnerToken(0, 0) + if err != nil { + ctx.ServerError("CreateRunnerToken", err) + return + } + } else { + if err != nil { + ctx.ServerError("GetUnactivatedRunnerToken", err) + return + } + } + ctx.Data["Keyword"] = opts.Filter ctx.Data["Runners"] = runners ctx.Data["Total"] = count + ctx.Data["RegistrationToken"] = token.Token pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5) ctx.Data["Page"] = pager @@ -75,7 +92,7 @@ func Runners(ctx *context.Context) { // EditRunner show editing runner page func EditRunner(ctx *context.Context) { - ctx.Data["Title"] = ctx.Tr("admin.runners.edit") + ctx.Data["Title"] = ctx.Tr("admin.runners.edit_runner") ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminRunners"] = true @@ -107,7 +124,7 @@ func EditRunnerPost(ctx *context.Context) { err = bots_model.UpdateRunner(ctx, runner, "description", "custom_labels") if err != nil { log.Warn("EditRunnerPost.UpdateRunner failed: %v, url: %s", err, ctx.Req.URL) - ctx.Flash.Warning(ctx.Tr("admin.runners.edit_failed")) + ctx.Flash.Warning(ctx.Tr("admin.runners.update_runner_failed")) ctx.Redirect(setting.AppSubURL + "/admin/runners/" + url.PathEscape(ctx.Params(":runnerid"))) return } @@ -118,7 +135,7 @@ func EditRunnerPost(ctx *context.Context) { log.Debug("EditRunnerPost success: %s", ctx.Req.URL) - ctx.Flash.Success(ctx.Tr("admin.runners.edit_success")) + ctx.Flash.Success(ctx.Tr("admin.runners.update_runner_success")) ctx.Redirect(setting.AppSubURL + "/admin/runners/" + url.PathEscape(ctx.Params(":runnerid"))) } @@ -134,14 +151,25 @@ func DeleteRunnerPost(ctx *context.Context) { err = bots_model.DeleteRunner(ctx, runner) if err != nil { log.Warn("DeleteRunnerPost.UpdateRunner failed: %v, url: %s", err, ctx.Req.URL) - ctx.Flash.Warning(ctx.Tr("admin.runners.delete_failed")) + ctx.Flash.Warning(ctx.Tr("admin.runners.delete_runner_failed")) ctx.Redirect(setting.AppSubURL + "/admin/runners/" + url.PathEscape(ctx.Params(":runnerid"))) return } log.Info("DeleteRunnerPost success: %s", ctx.Req.URL) - ctx.Flash.Success(ctx.Tr("admin.runners.deletion_success")) + ctx.Flash.Success(ctx.Tr("admin.runners.delete_runner_success")) + ctx.Redirect(setting.AppSubURL + "/admin/runners/") +} + +func ResetRunnerRegistrationToken(ctx *context.Context) { + _, err := bots_model.NewRunnerToken(0, 0) + if err != nil { + ctx.ServerError("ResetRunnerRegistrationToken", err) + return + } + + ctx.Flash.Success(ctx.Tr("admin.runners.reset_registration_token_success")) ctx.Redirect(setting.AppSubURL + "/admin/runners/") } diff --git a/routers/web/web.go b/routers/web/web.go index b8e72d14eb..2dbaf26538 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -627,6 +627,7 @@ func RegisterRoutes(m *web.Route) { m.Group("/runners", func() { m.Get("", admin.Runners) + m.Get("/reset_registration_token", admin.ResetRunnerRegistrationToken) m.Combo("/{runnerid}").Get(admin.EditRunner).Post(bindIgnErr(forms.AdminEditRunnerForm{}), admin.EditRunnerPost) m.Post("/{runnerid}/delete", admin.DeleteRunnerPost) }) diff --git a/templates/admin/runner/edit.tmpl b/templates/admin/runner/edit.tmpl index 023114185d..6a46eed8f4 100644 --- a/templates/admin/runner/edit.tmpl +++ b/templates/admin/runner/edit.tmpl @@ -16,7 +16,7 @@ <span class="runner-status-{{.Runner.StatusType}}">{{.Runner.StatusType}}</span> </div> <div class="field dib"> - <label>{{.locale.Tr "admin.runners.last_online"}}</label> + <label>{{.locale.Tr "admin.runners.latest_online"}}</label> <span>{{TimeSinceUnix .Runner.LastOnline $.locale}}</span> </div> <div class="field dib"> @@ -56,7 +56,7 @@ </div> <h4 class="ui top attached header"> - {{.locale.Tr "admin.runner.task_list"}} + {{.locale.Tr "admin.runners.task_list"}} </h4> <div class="ui attached segment"> Comming soon @@ -66,18 +66,18 @@ <div class="ui small modal" id="runner-delete-modal"> <div class="header"> - {{.locale.Tr "admin.runners.delete_header"}} + {{.locale.Tr "admin.runners.delete_runner_header"}} </div> <div class="content"> <div class="ui warning message text left"> - {{.locale.Tr "admin.runnners.delete_notice" | Safe}} + {{.locale.Tr "admin.runners.delete_runner_notice" | Safe}} </div> <form class="ui form" action="{{.Link}}/delete" method="post"> {{.CsrfTokenHtml}} <input type="hidden" name="action" value="delete"> <div class="text right actions"> <div class="ui cancel button">{{.locale.Tr "settings.cancel"}}</div> - <button class="ui red button">{{.locale.Tr "admin.runners.delete_confirm"}}</button> + <button class="ui red button">{{.locale.Tr "admin.runners.delete_runner_confirm"}}</button> </div> </form> </div> diff --git a/templates/admin/runner/list.tmpl b/templates/admin/runner/list.tmpl index 0752cf6506..84cf11801f 100644 --- a/templates/admin/runner/list.tmpl +++ b/templates/admin/runner/list.tmpl @@ -6,7 +6,32 @@ <h4 class="ui top attached header"> {{.locale.Tr "admin.runners.runner_manage_panel"}} ({{.locale.Tr "admin.total" .Total}}) <div class="ui right"> - <a class="ui primary tiny button" href="{{AppSubUrl}}/admin/runners/new">{{.locale.Tr "admin.runners.new"}}</a> + <!--<a class="ui primary tiny button" href="{{AppSubUrl}}/admin/runners/new">{{.locale.Tr "admin.runners.new"}}</a>--> + + <div class="ui top right pointing dropdown button primary" id="runner-new"> + <span class="text runner-new-text">{{.locale.Tr "admin.runners.new"}}</span> + <div class="menu runner-new-menu"> + <div class="item"> + <a href="#">{{.locale.Tr "admin.runners.new_notice"}}</a> + </div> + <div class="divider"></div> + <div class="header"> + Registration Token + </div> + <div class="ui input"> + <input type="text" value="{{.RegistrationToken}}"> + <div class="ui basic label button" data-clipboard-text="{{.RegistrationToken}}"> + {{svg "octicon-copy" 14}} + </div> + </div> + <div class="divider"></div> + + <div class="item"> + <a href="{{$.Link}}/reset_registration_token">Reset registration token</a> + </div> + </div> + </div> + </div> </h4> <div class="ui attached segment"> @@ -26,9 +51,9 @@ <th data-sortt-asc="alphabetically"> {{.locale.Tr "admin.runners.id"}} </th> - <th>{{.locale.Tr "admin.runners.own_type"}}</th> - <th>{{.locale.Tr "admin.runners.tags"}}</th> - <th>{{.locale.Tr "admin.runners.latest_contact"}}</th> + <th>{{.locale.Tr "admin.runners.owner_type"}}</th> + <th>{{.locale.Tr "admin.runners.labels"}}</th> + <th>{{.locale.Tr "admin.runners.latest_online"}}</th> <th></th> </tr> </thead> diff --git a/web_src/less/_runner.less b/web_src/less/_runner.less index dacbe94f9e..f6b1a99ec3 100644 --- a/web_src/less/_runner.less +++ b/web_src/less/_runner.less @@ -15,4 +15,13 @@ background-color: var(--color-green); color: var(--color-white); } + .runner-new-text{ + color: var(--color-white) + } + #runner-new:hover .runner-new-text{ + color: var(--color-white) !important; + } + .runner-new-menu{ + width: 300px; + } }