Add agent no-schedule flag (#1567)

This flag allows an agent owner / admin to stop the agent from taking
new workflows / pipelines.
This commit is contained in:
Anbraten 2023-01-30 20:18:48 +01:00 committed by GitHub
parent 5f818e933b
commit 71d6c03ca7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 28 additions and 19 deletions

View file

@ -73,6 +73,7 @@ func PatchAgent(c *gin.Context) {
return
}
agent.Name = in.Name
agent.NoSchedule = in.NoSchedule
err = _store.AgentUpdate(agent)
if err != nil {
@ -96,6 +97,7 @@ func PostAgent(c *gin.Context) {
agent := &model.Agent{
Name: in.Name,
NoSchedule: in.NoSchedule,
OwnerID: user.ID,
Token: base32.StdEncoding.EncodeToString(
securecookie.GenerateRandomKey(32),

View file

@ -70,6 +70,13 @@ func (s *RPC) Next(c context.Context, agentFilter rpc.Filter) (*rpc.Pipeline, er
return nil, err
}
for {
agent, err := s.getAgentFromContext(c)
if err != nil {
return nil, err
} else if agent.NoSchedule {
return nil, nil
}
task, err := s.queue.Poll(c, fn)
if err != nil {
return nil, err
@ -82,6 +89,7 @@ func (s *RPC) Next(c context.Context, agentFilter rpc.Filter) (*rpc.Pipeline, er
err = json.Unmarshal(task.Data, pipeline)
return pipeline, err
}
if err := s.Done(c, task.ID, rpc.State{}); err != nil {
log.Error().Err(err).Msgf("mark task '%s' done failed", task.ID)
}

View file

@ -26,6 +26,7 @@ type Agent struct {
Backend string `json:"backend" xorm:"VARCHAR(100)"`
Capacity int32 `json:"capacity"`
Version string `json:"version"`
NoSchedule bool `json:"no_schedule"`
}
// TableName return database table name for xorm

18
web/components.d.ts vendored
View file

@ -21,10 +21,8 @@ declare module '@vue/runtime-core' {
FluidContainer: typeof import('./src/components/layout/FluidContainer.vue')['default']
GeneralTab: typeof import('./src/components/repo/settings/GeneralTab.vue')['default']
Header: typeof import('./src/components/layout/scaffold/Header.vue')['default']
IBiCheckCircle: typeof import('~icons/bi/check-circle')['default']
IBiCheckCircleFill: typeof import('~icons/bi/check-circle-fill')['default']
IBiCircle: typeof import('~icons/bi/circle')['default']
IBiPauseCircleFill: typeof import('~icons/bi/pause-circle-fill')['default']
IBiPlayCircleFill: typeof import('~icons/bi/play-circle-fill')['default']
IBiSlashCircleFill: typeof import('~icons/bi/slash-circle-fill')['default']
IBiStopCircleFill: typeof import('~icons/bi/stop-circle-fill')['default']
@ -33,13 +31,9 @@ declare module '@vue/runtime-core' {
ICarbonCloseOutline: typeof import('~icons/carbon/close-outline')['default']
ICarbonInProgress: typeof import('~icons/carbon/in-progress')['default']
IClarityDeployLine: typeof import('~icons/clarity/deploy-line')['default']
IClarityNoAccessSolid: typeof import('~icons/clarity/no-access-solid')['default']
IClaritySettingsSolid: typeof import('~icons/clarity/settings-solid')['default']
IClaritySuccessStandardSolid: typeof import('~icons/clarity/success-standard-solid')['default']
IClarityTimesCircleSolid: typeof import('~icons/clarity/times-circle-solid')['default']
Icon: typeof import('./src/components/atomic/Icon.vue')['default']
IconButton: typeof import('./src/components/atomic/IconButton.vue')['default']
IEntypoDotsTwoVertical: typeof import('~icons/entypo/dots-two-vertical')['default']
IGgTrash: typeof import('~icons/gg/trash')['default']
IIcBaselineDarkMode: typeof import('~icons/ic/baseline-dark-mode')['default']
IIcBaselineDownloadForOffline: typeof import('~icons/ic/baseline-download-for-offline')['default']
@ -67,24 +61,14 @@ declare module '@vue/runtime-core' {
IMdiSync: typeof import('~icons/mdi/sync')['default']
IMdiTagOutline: typeof import('~icons/mdi/tag-outline')['default']
InputField: typeof import('./src/components/form/InputField.vue')['default']
IOcticonSkip24: typeof import('~icons/octicon/skip24')['default']
IPhCheckCircle: typeof import('~icons/ph/check-circle')['default']
IPhGitlabLogoSimpleFill: typeof import('~icons/ph/gitlab-logo-simple-fill')['default']
IPhHand: typeof import('~icons/ph/hand')['default']
IPhHourglass: typeof import('~icons/ph/hourglass')['default']
IPhProhibit: typeof import('~icons/ph/prohibit')['default']
IPhWarning: typeof import('~icons/ph/warning')['default']
IPhXCircle: typeof import('~icons/ph/x-circle')['default']
ISimpleIconsGitea: typeof import('~icons/simple-icons/gitea')['default']
ITeenyiconsGitSolid: typeof import('~icons/teenyicons/git-solid')['default']
IUiwCircleCheck: typeof import('~icons/uiw/circle-check')['default']
IUiwCircleClose: typeof import('~icons/uiw/circle-close')['default']
IUiwStop: typeof import('~icons/uiw/stop')['default']
ITeenyiconsRefreshOutline: typeof import('~icons/teenyicons/refresh-outline')['default']
IVaadinQuestionCircleO: typeof import('~icons/vaadin/question-circle-o')['default']
ListItem: typeof import('./src/components/atomic/ListItem.vue')['default']
ManualPipelinePopup: typeof import('./src/components/layout/popups/ManualPipelinePopup.vue')['default']
Navbar: typeof import('./src/components/layout/header/Navbar.vue')['default']
NavbarIcon: typeof import('./src/components/layout/header/NavbarIcon.vue')['default']
NumberField: typeof import('./src/components/form/NumberField.vue')['default']
OrgSecretsTab: typeof import('./src/components/org/settings/OrgSecretsTab.vue')['default']
Panel: typeof import('./src/components/layout/Panel.vue')['default']

View file

@ -336,6 +336,10 @@
"name": "Name",
"placeholder": "Name of the agent"
},
"no_schedule": {
"name": "Disable agent",
"placeholder": "Stop agent from taking new tasks"
},
"token": "Token",
"platform": "Platform",
"backend": "Backend",

View file

@ -43,6 +43,14 @@
/>
</InputField>
<InputField :label="$t('admin.settings.agents.no_schedule.name')">
<Checkbox
:model-value="selectedAgent.no_schedule || false"
:label="$t('admin.settings.agents.no_schedule.placeholder')"
@update:model-value="selectedAgent!.no_schedule = $event"
/>
</InputField>
<template v-if="isEditingAgent">
<InputField :label="$t('admin.settings.agents.token')">
<TextField v-model="selectedAgent.token" :placeholder="$t('admin.settings.agents.token')" disabled />
@ -97,6 +105,7 @@ import { useI18n } from 'vue-i18n';
import Button from '~/components/atomic/Button.vue';
import ListItem from '~/components/atomic/ListItem.vue';
import Checkbox from '~/components/form/Checkbox.vue';
import InputField from '~/components/form/InputField.vue';
import TextField from '~/components/form/TextField.vue';
import Panel from '~/components/layout/Panel.vue';

View file

@ -9,4 +9,5 @@ export type Agent = {
backend: string;
capacity: number;
version: string;
no_schedule: boolean;
};