mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-26 03:41:01 +00:00
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:
parent
5f818e933b
commit
71d6c03ca7
7 changed files with 28 additions and 19 deletions
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
18
web/components.d.ts
vendored
|
@ -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']
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -9,4 +9,5 @@ export type Agent = {
|
|||
backend: string;
|
||||
capacity: number;
|
||||
version: string;
|
||||
no_schedule: boolean;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue