1 import express from 'express'
2 import { body, param } from 'express-validator'
3 import { isUUIDValid } from '@server/helpers/custom-validators/misc'
5 isRunnerJobAbortReasonValid,
6 isRunnerJobErrorMessageValid,
7 isRunnerJobProgressValid,
8 isRunnerJobSuccessPayloadValid,
10 isRunnerJobUpdatePayloadValid
11 } from '@server/helpers/custom-validators/runners/jobs'
12 import { isRunnerTokenValid } from '@server/helpers/custom-validators/runners/runners'
13 import { cleanUpReqFiles } from '@server/helpers/express-utils'
14 import { RunnerJobModel } from '@server/models/runner/runner-job'
15 import { HttpStatusCode, RunnerJobState, RunnerJobSuccessBody, RunnerJobUpdateBody, ServerErrorCode } from '@shared/models'
16 import { areValidationErrors } from '../shared'
18 const tags = [ 'runner' ]
20 export const acceptRunnerJobValidator = [
21 (req: express.Request, res: express.Response, next: express.NextFunction) => {
22 if (res.locals.runnerJob.state !== RunnerJobState.PENDING) {
24 status: HttpStatusCode.BAD_REQUEST_400,
25 message: 'This runner job is not in pending state',
34 export const abortRunnerJobValidator = [
35 body('reason').custom(isRunnerJobAbortReasonValid),
37 (req: express.Request, res: express.Response, next: express.NextFunction) => {
38 if (areValidationErrors(req, res, { tags })) return
44 export const updateRunnerJobValidator = [
45 body('progress').optional().custom(isRunnerJobProgressValid),
47 (req: express.Request, res: express.Response, next: express.NextFunction) => {
48 if (areValidationErrors(req, res, { tags })) return cleanUpReqFiles(req)
50 const body = req.body as RunnerJobUpdateBody
52 if (isRunnerJobUpdatePayloadValid(body.payload, res.locals.runnerJob.type, req.files) !== true) {
56 status: HttpStatusCode.BAD_REQUEST_400,
57 message: 'Payload is invalid',
66 export const errorRunnerJobValidator = [
67 body('message').custom(isRunnerJobErrorMessageValid),
69 (req: express.Request, res: express.Response, next: express.NextFunction) => {
70 if (areValidationErrors(req, res, { tags })) return
76 export const successRunnerJobValidator = [
77 (req: express.Request, res: express.Response, next: express.NextFunction) => {
78 const body = req.body as RunnerJobSuccessBody
80 if (isRunnerJobSuccessPayloadValid(body.payload, res.locals.runnerJob.type, req.files) !== true) {
84 status: HttpStatusCode.BAD_REQUEST_400,
85 message: 'Payload is invalid',
94 export const runnerJobGetValidator = [
95 param('jobUUID').custom(isUUIDValid),
97 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
98 if (areValidationErrors(req, res, { tags })) return
100 const runnerJob = await RunnerJobModel.loadWithRunner(req.params.jobUUID)
104 status: HttpStatusCode.NOT_FOUND_404,
105 message: 'Unknown runner job',
110 res.locals.runnerJob = runnerJob
116 export const jobOfRunnerGetValidator = [
117 param('jobUUID').custom(isUUIDValid),
119 body('runnerToken').custom(isRunnerTokenValid),
120 body('jobToken').custom(isRunnerJobTokenValid),
122 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
123 if (areValidationErrors(req, res, { tags })) return cleanUpReqFiles(req)
125 const runnerJob = await RunnerJobModel.loadByRunnerAndJobTokensWithRunner({
126 uuid: req.params.jobUUID,
127 runnerToken: req.body.runnerToken,
128 jobToken: req.body.jobToken
135 status: HttpStatusCode.NOT_FOUND_404,
136 message: 'Unknown runner job',
141 if (runnerJob.state !== RunnerJobState.PROCESSING) {
145 status: HttpStatusCode.BAD_REQUEST_400,
146 type: ServerErrorCode.RUNNER_JOB_NOT_IN_PROCESSING_STATE,
147 message: 'Job is not in "processing" state',
152 res.locals.runnerJob = runnerJob