Regenerate Swagger, fix tests, cleanup

This commit is contained in:
Jan Eitzinger 2024-11-26 07:02:53 +01:00
parent adb11b3ed0
commit 28539e60b0
6 changed files with 254 additions and 482 deletions

View File

@ -595,88 +595,6 @@
} }
} }
}, },
"/jobs/stop_job/{id}": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Job to stop is specified by database ID. Only stopTime and final state are required in request body.\nReturns full job resource information according to 'JobMeta' scheme.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Job add and modify"
],
"summary": "Marks job as completed and triggers archiving",
"parameters": [
{
"type": "integer",
"description": "Database ID of Job",
"name": "id",
"in": "path",
"required": true
},
{
"description": "stopTime and final state in request body",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.StopJobApiRequest"
}
}
],
"responses": {
"200": {
"description": "Job resource",
"schema": {
"$ref": "#/definitions/schema.JobMeta"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"404": {
"description": "Resource not found",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"422": {
"description": "Unprocessable Entity: finding job failed: sql: no rows in result set",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
}
}
}
},
"/jobs/tag_job/{id}": { "/jobs/tag_job/{id}": {
"post": { "post": {
"security": [ "security": [
@ -684,7 +602,7 @@
"ApiKeyAuth": [] "ApiKeyAuth": []
} }
], ],
"description": "Adds tag(s) to a job specified by DB ID. Name and Type of Tag(s) can be chosen freely.\nIf tagged job is already finished: Tag will be written directly to respective archive files.", "description": "Adds tag(s) to a job specified by DB ID. Name and Type of Tag(s) can be chosen freely.\nTag Scope for frontend visibility will default to \"global\" if none entered, other options: \"admin\" or specific username.\nIf tagged job is already finished: Tag will be written directly to respective archive files.",
"consumes": [ "consumes": [
"application/json" "application/json"
], ],
@ -1277,6 +1195,11 @@
"type": "string", "type": "string",
"example": "Testjob" "example": "Testjob"
}, },
"scope": {
"description": "Tag Scope for Frontend Display",
"type": "string",
"example": "global"
},
"type": { "type": {
"description": "Tag Type", "description": "Tag Type",
"type": "string", "type": "string",
@ -1404,9 +1327,8 @@
"api.StartJobApiResponse": { "api.StartJobApiResponse": {
"type": "object", "type": "object",
"properties": { "properties": {
"id": { "msg": {
"description": "Database ID of new job", "type": "string"
"type": "integer"
} }
} }
}, },
@ -1418,17 +1340,14 @@
], ],
"properties": { "properties": {
"cluster": { "cluster": {
"description": "Cluster of job",
"type": "string", "type": "string",
"example": "fritz" "example": "fritz"
}, },
"jobId": { "jobId": {
"description": "Cluster Job ID of job",
"type": "integer", "type": "integer",
"example": 123000 "example": 123000
}, },
"jobState": { "jobState": {
"description": "Final job state",
"allOf": [ "allOf": [
{ {
"$ref": "#/definitions/schema.JobState" "$ref": "#/definitions/schema.JobState"
@ -1437,12 +1356,10 @@
"example": "completed" "example": "completed"
}, },
"startTime": { "startTime": {
"description": "Start Time of job as epoch",
"type": "integer", "type": "integer",
"example": 1649723812 "example": 1649723812
}, },
"stopTime": { "stopTime": {
"description": "Stop Time of job as epoch",
"type": "integer", "type": "integer",
"example": 1649763839 "example": 1649763839
} }
@ -1487,12 +1404,10 @@
"type": "object", "type": "object",
"properties": { "properties": {
"arrayJobId": { "arrayJobId": {
"description": "The unique identifier of an array job",
"type": "integer", "type": "integer",
"example": 123000 "example": 123000
}, },
"cluster": { "cluster": {
"description": "The unique identifier of a cluster",
"type": "string", "type": "string",
"example": "fritz" "example": "fritz"
}, },
@ -1500,33 +1415,39 @@
"$ref": "#/definitions/schema.JobLinkResultList" "$ref": "#/definitions/schema.JobLinkResultList"
}, },
"duration": { "duration": {
"description": "Duration of job in seconds (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 43200 "example": 43200
}, },
"energy": {
"type": "number"
},
"energyFootprint": {
"type": "object",
"additionalProperties": {
"type": "number"
}
},
"exclusive": { "exclusive": {
"description": "Specifies how nodes are shared: 0 - Shared among multiple jobs of multiple users, 1 - Job exclusive (Default), 2 - Shared among multiple jobs of same user",
"type": "integer", "type": "integer",
"maximum": 2, "maximum": 2,
"minimum": 0, "minimum": 0,
"example": 1 "example": 1
}, },
"flopsAnyAvg": { "footprint": {
"description": "FlopsAnyAvg as Float64", "type": "object",
"type": "number" "additionalProperties": {
"type": "number"
}
}, },
"id": { "id": {
"description": "The unique identifier of a job in the database",
"type": "integer" "type": "integer"
}, },
"jobId": { "jobId": {
"description": "The unique identifier of a job",
"type": "integer", "type": "integer",
"example": 123000 "example": 123000
}, },
"jobState": { "jobState": {
"description": "Final state of job",
"enum": [ "enum": [
"completed", "completed",
"failed", "failed",
@ -1542,95 +1463,69 @@
], ],
"example": "completed" "example": "completed"
}, },
"loadAvg": {
"description": "LoadAvg as Float64",
"type": "number"
},
"memBwAvg": {
"description": "MemBwAvg as Float64",
"type": "number"
},
"memUsedMax": {
"description": "MemUsedMax as Float64",
"type": "number"
},
"metaData": { "metaData": {
"description": "Additional information about the job",
"type": "object", "type": "object",
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
} }
}, },
"monitoringStatus": { "monitoringStatus": {
"description": "State of monitoring system during job run: 0 - Disabled, 1 - Running or Archiving (Default), 2 - Archiving Failed, 3 - Archiving Successfull",
"type": "integer", "type": "integer",
"maximum": 3, "maximum": 3,
"minimum": 0, "minimum": 0,
"example": 1 "example": 1
}, },
"numAcc": { "numAcc": {
"description": "Number of accelerators used (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 2 "example": 2
}, },
"numHwthreads": { "numHwthreads": {
"description": "NumCores int32 `json:\"numCores\" db:\"num_cores\" example:\"20\" minimum:\"1\"` // Number of HWThreads used (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 20 "example": 20
}, },
"numNodes": { "numNodes": {
"description": "Number of nodes used (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 2 "example": 2
}, },
"partition": { "partition": {
"description": "The Slurm partition to which the job was submitted",
"type": "string", "type": "string",
"example": "main" "example": "main"
}, },
"project": { "project": {
"description": "The unique identifier of a project",
"type": "string", "type": "string",
"example": "abcd200" "example": "abcd200"
}, },
"resources": { "resources": {
"description": "Resources used by job",
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/schema.Resource" "$ref": "#/definitions/schema.Resource"
} }
}, },
"smt": { "smt": {
"description": "SMT threads used by job",
"type": "integer", "type": "integer",
"example": 4 "example": 4
}, },
"startTime": { "startTime": {
"description": "Start time as 'time.Time' data type",
"type": "string" "type": "string"
}, },
"subCluster": { "subCluster": {
"description": "The unique identifier of a sub cluster",
"type": "string", "type": "string",
"example": "main" "example": "main"
}, },
"tags": { "tags": {
"description": "List of tags",
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/schema.Tag" "$ref": "#/definitions/schema.Tag"
} }
}, },
"user": { "user": {
"description": "The unique identifier of a user",
"type": "string", "type": "string",
"example": "abcd100h" "example": "abcd100h"
}, },
"walltime": { "walltime": {
"description": "Requested walltime of job in seconds (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 86400 "example": 86400
@ -1667,12 +1562,10 @@
"type": "object", "type": "object",
"properties": { "properties": {
"arrayJobId": { "arrayJobId": {
"description": "The unique identifier of an array job",
"type": "integer", "type": "integer",
"example": 123000 "example": 123000
}, },
"cluster": { "cluster": {
"description": "The unique identifier of a cluster",
"type": "string", "type": "string",
"example": "fritz" "example": "fritz"
}, },
@ -1680,29 +1573,39 @@
"$ref": "#/definitions/schema.JobLinkResultList" "$ref": "#/definitions/schema.JobLinkResultList"
}, },
"duration": { "duration": {
"description": "Duration of job in seconds (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 43200 "example": 43200
}, },
"energy": {
"type": "number"
},
"energyFootprint": {
"type": "object",
"additionalProperties": {
"type": "number"
}
},
"exclusive": { "exclusive": {
"description": "Specifies how nodes are shared: 0 - Shared among multiple jobs of multiple users, 1 - Job exclusive (Default), 2 - Shared among multiple jobs of same user",
"type": "integer", "type": "integer",
"maximum": 2, "maximum": 2,
"minimum": 0, "minimum": 0,
"example": 1 "example": 1
}, },
"footprint": {
"type": "object",
"additionalProperties": {
"type": "number"
}
},
"id": { "id": {
"description": "The unique identifier of a job in the database",
"type": "integer" "type": "integer"
}, },
"jobId": { "jobId": {
"description": "The unique identifier of a job",
"type": "integer", "type": "integer",
"example": 123000 "example": 123000
}, },
"jobState": { "jobState": {
"description": "Final state of job",
"enum": [ "enum": [
"completed", "completed",
"failed", "failed",
@ -1719,91 +1622,76 @@
"example": "completed" "example": "completed"
}, },
"metaData": { "metaData": {
"description": "Additional information about the job",
"type": "object", "type": "object",
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
} }
}, },
"monitoringStatus": { "monitoringStatus": {
"description": "State of monitoring system during job run: 0 - Disabled, 1 - Running or Archiving (Default), 2 - Archiving Failed, 3 - Archiving Successfull",
"type": "integer", "type": "integer",
"maximum": 3, "maximum": 3,
"minimum": 0, "minimum": 0,
"example": 1 "example": 1
}, },
"numAcc": { "numAcc": {
"description": "Number of accelerators used (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 2 "example": 2
}, },
"numHwthreads": { "numHwthreads": {
"description": "NumCores int32 `json:\"numCores\" db:\"num_cores\" example:\"20\" minimum:\"1\"` // Number of HWThreads used (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 20 "example": 20
}, },
"numNodes": { "numNodes": {
"description": "Number of nodes used (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 2 "example": 2
}, },
"partition": { "partition": {
"description": "The Slurm partition to which the job was submitted",
"type": "string", "type": "string",
"example": "main" "example": "main"
}, },
"project": { "project": {
"description": "The unique identifier of a project",
"type": "string", "type": "string",
"example": "abcd200" "example": "abcd200"
}, },
"resources": { "resources": {
"description": "Resources used by job",
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/schema.Resource" "$ref": "#/definitions/schema.Resource"
} }
}, },
"smt": { "smt": {
"description": "SMT threads used by job",
"type": "integer", "type": "integer",
"example": 4 "example": 4
}, },
"startTime": { "startTime": {
"description": "Start epoch time stamp in seconds (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 1649723812 "example": 1649723812
}, },
"statistics": { "statistics": {
"description": "Metric statistics of job",
"type": "object", "type": "object",
"additionalProperties": { "additionalProperties": {
"$ref": "#/definitions/schema.JobStatistics" "$ref": "#/definitions/schema.JobStatistics"
} }
}, },
"subCluster": { "subCluster": {
"description": "The unique identifier of a sub cluster",
"type": "string", "type": "string",
"example": "main" "example": "main"
}, },
"tags": { "tags": {
"description": "List of tags",
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/schema.Tag" "$ref": "#/definitions/schema.Tag"
} }
}, },
"user": { "user": {
"description": "The unique identifier of a user",
"type": "string", "type": "string",
"example": "abcd100h" "example": "abcd100h"
}, },
"walltime": { "walltime": {
"description": "Requested walltime of job in seconds (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 86400 "example": 86400
@ -1892,6 +1780,15 @@
"caution": { "caution": {
"type": "number" "type": "number"
}, },
"energy": {
"type": "string"
},
"footprint": {
"type": "string"
},
"lowerIsBetter": {
"type": "boolean"
},
"name": { "name": {
"type": "string" "type": "string"
}, },
@ -1969,22 +1866,18 @@
"type": "object", "type": "object",
"properties": { "properties": {
"accelerators": { "accelerators": {
"description": "List of of accelerator device ids",
"type": "array", "type": "array",
"items": { "items": {
"type": "string" "type": "string"
} }
}, },
"configuration": { "configuration": {
"description": "The configuration options of the node",
"type": "string" "type": "string"
}, },
"hostname": { "hostname": {
"description": "Name of the host (= node)",
"type": "string" "type": "string"
}, },
"hwthreads": { "hwthreads": {
"description": "List of OS processor ids",
"type": "array", "type": "array",
"items": { "items": {
"type": "integer" "type": "integer"
@ -2027,6 +1920,12 @@
"type": "number" "type": "number"
} }
}, },
"median": {
"type": "array",
"items": {
"type": "number"
}
},
"min": { "min": {
"type": "array", "type": "array",
"items": { "items": {
@ -2050,15 +1949,33 @@
"coresPerSocket": { "coresPerSocket": {
"type": "integer" "type": "integer"
}, },
"energyFootprint": {
"type": "array",
"items": {
"type": "string"
}
},
"flopRateScalar": { "flopRateScalar": {
"$ref": "#/definitions/schema.MetricValue" "$ref": "#/definitions/schema.MetricValue"
}, },
"flopRateSimd": { "flopRateSimd": {
"$ref": "#/definitions/schema.MetricValue" "$ref": "#/definitions/schema.MetricValue"
}, },
"footprint": {
"type": "array",
"items": {
"type": "string"
}
},
"memoryBandwidth": { "memoryBandwidth": {
"$ref": "#/definitions/schema.MetricValue" "$ref": "#/definitions/schema.MetricValue"
}, },
"metricConfig": {
"type": "array",
"items": {
"$ref": "#/definitions/schema.MetricConfig"
}
},
"name": { "name": {
"type": "string" "type": "string"
}, },
@ -2088,6 +2005,15 @@
"caution": { "caution": {
"type": "number" "type": "number"
}, },
"energy": {
"type": "string"
},
"footprint": {
"type": "string"
},
"lowerIsBetter": {
"type": "boolean"
},
"name": { "name": {
"type": "string" "type": "string"
}, },
@ -2107,16 +2033,17 @@
"type": "object", "type": "object",
"properties": { "properties": {
"id": { "id": {
"description": "The unique DB identifier of a tag",
"type": "integer" "type": "integer"
}, },
"name": { "name": {
"description": "Tag Name",
"type": "string", "type": "string",
"example": "Testjob" "example": "Testjob"
}, },
"scope": {
"type": "string",
"example": "global"
},
"type": { "type": {
"description": "Tag Type",
"type": "string", "type": "string",
"example": "Debug" "example": "Debug"
} }

View File

@ -23,6 +23,10 @@ definitions:
description: Tag Name description: Tag Name
example: Testjob example: Testjob
type: string type: string
scope:
description: Tag Scope for Frontend Display
example: global
type: string
type: type:
description: Tag Type description: Tag Type
example: Debug example: Debug
@ -110,31 +114,25 @@ definitions:
type: object type: object
api.StartJobApiResponse: api.StartJobApiResponse:
properties: properties:
id: msg:
description: Database ID of new job type: string
type: integer
type: object type: object
api.StopJobApiRequest: api.StopJobApiRequest:
properties: properties:
cluster: cluster:
description: Cluster of job
example: fritz example: fritz
type: string type: string
jobId: jobId:
description: Cluster Job ID of job
example: 123000 example: 123000
type: integer type: integer
jobState: jobState:
allOf: allOf:
- $ref: '#/definitions/schema.JobState' - $ref: '#/definitions/schema.JobState'
description: Final job state
example: completed example: completed
startTime: startTime:
description: Start Time of job as epoch
example: 1649723812 example: 1649723812
type: integer type: integer
stopTime: stopTime:
description: Stop Time of job as epoch
example: 1649763839 example: 1649763839
type: integer type: integer
required: required:
@ -167,42 +165,40 @@ definitions:
description: Information of a HPC job. description: Information of a HPC job.
properties: properties:
arrayJobId: arrayJobId:
description: The unique identifier of an array job
example: 123000 example: 123000
type: integer type: integer
cluster: cluster:
description: The unique identifier of a cluster
example: fritz example: fritz
type: string type: string
concurrentJobs: concurrentJobs:
$ref: '#/definitions/schema.JobLinkResultList' $ref: '#/definitions/schema.JobLinkResultList'
duration: duration:
description: Duration of job in seconds (Min > 0)
example: 43200 example: 43200
minimum: 1 minimum: 1
type: integer type: integer
energy:
type: number
energyFootprint:
additionalProperties:
type: number
type: object
exclusive: exclusive:
description: 'Specifies how nodes are shared: 0 - Shared among multiple jobs
of multiple users, 1 - Job exclusive (Default), 2 - Shared among multiple
jobs of same user'
example: 1 example: 1
maximum: 2 maximum: 2
minimum: 0 minimum: 0
type: integer type: integer
flopsAnyAvg: footprint:
description: FlopsAnyAvg as Float64 additionalProperties:
type: number type: number
type: object
id: id:
description: The unique identifier of a job in the database
type: integer type: integer
jobId: jobId:
description: The unique identifier of a job
example: 123000 example: 123000
type: integer type: integer
jobState: jobState:
allOf: allOf:
- $ref: '#/definitions/schema.JobState' - $ref: '#/definitions/schema.JobState'
description: Final state of job
enum: enum:
- completed - completed
- failed - failed
@ -211,79 +207,53 @@ definitions:
- timeout - timeout
- out_of_memory - out_of_memory
example: completed example: completed
loadAvg:
description: LoadAvg as Float64
type: number
memBwAvg:
description: MemBwAvg as Float64
type: number
memUsedMax:
description: MemUsedMax as Float64
type: number
metaData: metaData:
additionalProperties: additionalProperties:
type: string type: string
description: Additional information about the job
type: object type: object
monitoringStatus: monitoringStatus:
description: 'State of monitoring system during job run: 0 - Disabled, 1 -
Running or Archiving (Default), 2 - Archiving Failed, 3 - Archiving Successfull'
example: 1 example: 1
maximum: 3 maximum: 3
minimum: 0 minimum: 0
type: integer type: integer
numAcc: numAcc:
description: Number of accelerators used (Min > 0)
example: 2 example: 2
minimum: 1 minimum: 1
type: integer type: integer
numHwthreads: numHwthreads:
description: NumCores int32 `json:"numCores" db:"num_cores"
example:"20" minimum:"1"` //
Number of HWThreads used (Min > 0)
example: 20 example: 20
minimum: 1 minimum: 1
type: integer type: integer
numNodes: numNodes:
description: Number of nodes used (Min > 0)
example: 2 example: 2
minimum: 1 minimum: 1
type: integer type: integer
partition: partition:
description: The Slurm partition to which the job was submitted
example: main example: main
type: string type: string
project: project:
description: The unique identifier of a project
example: abcd200 example: abcd200
type: string type: string
resources: resources:
description: Resources used by job
items: items:
$ref: '#/definitions/schema.Resource' $ref: '#/definitions/schema.Resource'
type: array type: array
smt: smt:
description: SMT threads used by job
example: 4 example: 4
type: integer type: integer
startTime: startTime:
description: Start time as 'time.Time' data type
type: string type: string
subCluster: subCluster:
description: The unique identifier of a sub cluster
example: main example: main
type: string type: string
tags: tags:
description: List of tags
items: items:
$ref: '#/definitions/schema.Tag' $ref: '#/definitions/schema.Tag'
type: array type: array
user: user:
description: The unique identifier of a user
example: abcd100h example: abcd100h
type: string type: string
walltime: walltime:
description: Requested walltime of job in seconds (Min > 0)
example: 86400 example: 86400
minimum: 1 minimum: 1
type: integer type: integer
@ -308,39 +278,40 @@ definitions:
description: Meta data information of a HPC job. description: Meta data information of a HPC job.
properties: properties:
arrayJobId: arrayJobId:
description: The unique identifier of an array job
example: 123000 example: 123000
type: integer type: integer
cluster: cluster:
description: The unique identifier of a cluster
example: fritz example: fritz
type: string type: string
concurrentJobs: concurrentJobs:
$ref: '#/definitions/schema.JobLinkResultList' $ref: '#/definitions/schema.JobLinkResultList'
duration: duration:
description: Duration of job in seconds (Min > 0)
example: 43200 example: 43200
minimum: 1 minimum: 1
type: integer type: integer
energy:
type: number
energyFootprint:
additionalProperties:
type: number
type: object
exclusive: exclusive:
description: 'Specifies how nodes are shared: 0 - Shared among multiple jobs
of multiple users, 1 - Job exclusive (Default), 2 - Shared among multiple
jobs of same user'
example: 1 example: 1
maximum: 2 maximum: 2
minimum: 0 minimum: 0
type: integer type: integer
footprint:
additionalProperties:
type: number
type: object
id: id:
description: The unique identifier of a job in the database
type: integer type: integer
jobId: jobId:
description: The unique identifier of a job
example: 123000 example: 123000
type: integer type: integer
jobState: jobState:
allOf: allOf:
- $ref: '#/definitions/schema.JobState' - $ref: '#/definitions/schema.JobState'
description: Final state of job
enum: enum:
- completed - completed
- failed - failed
@ -352,74 +323,56 @@ definitions:
metaData: metaData:
additionalProperties: additionalProperties:
type: string type: string
description: Additional information about the job
type: object type: object
monitoringStatus: monitoringStatus:
description: 'State of monitoring system during job run: 0 - Disabled, 1 -
Running or Archiving (Default), 2 - Archiving Failed, 3 - Archiving Successfull'
example: 1 example: 1
maximum: 3 maximum: 3
minimum: 0 minimum: 0
type: integer type: integer
numAcc: numAcc:
description: Number of accelerators used (Min > 0)
example: 2 example: 2
minimum: 1 minimum: 1
type: integer type: integer
numHwthreads: numHwthreads:
description: NumCores int32 `json:"numCores" db:"num_cores"
example:"20" minimum:"1"` //
Number of HWThreads used (Min > 0)
example: 20 example: 20
minimum: 1 minimum: 1
type: integer type: integer
numNodes: numNodes:
description: Number of nodes used (Min > 0)
example: 2 example: 2
minimum: 1 minimum: 1
type: integer type: integer
partition: partition:
description: The Slurm partition to which the job was submitted
example: main example: main
type: string type: string
project: project:
description: The unique identifier of a project
example: abcd200 example: abcd200
type: string type: string
resources: resources:
description: Resources used by job
items: items:
$ref: '#/definitions/schema.Resource' $ref: '#/definitions/schema.Resource'
type: array type: array
smt: smt:
description: SMT threads used by job
example: 4 example: 4
type: integer type: integer
startTime: startTime:
description: Start epoch time stamp in seconds (Min > 0)
example: 1649723812 example: 1649723812
minimum: 1 minimum: 1
type: integer type: integer
statistics: statistics:
additionalProperties: additionalProperties:
$ref: '#/definitions/schema.JobStatistics' $ref: '#/definitions/schema.JobStatistics'
description: Metric statistics of job
type: object type: object
subCluster: subCluster:
description: The unique identifier of a sub cluster
example: main example: main
type: string type: string
tags: tags:
description: List of tags
items: items:
$ref: '#/definitions/schema.Tag' $ref: '#/definitions/schema.Tag'
type: array type: array
user: user:
description: The unique identifier of a user
example: abcd100h example: abcd100h
type: string type: string
walltime: walltime:
description: Requested walltime of job in seconds (Min > 0)
example: 86400 example: 86400
minimum: 1 minimum: 1
type: integer type: integer
@ -486,6 +439,12 @@ definitions:
type: number type: number
caution: caution:
type: number type: number
energy:
type: string
footprint:
type: string
lowerIsBetter:
type: boolean
name: name:
type: string type: string
normal: normal:
@ -541,18 +500,14 @@ definitions:
description: A resource used by a job description: A resource used by a job
properties: properties:
accelerators: accelerators:
description: List of of accelerator device ids
items: items:
type: string type: string
type: array type: array
configuration: configuration:
description: The configuration options of the node
type: string type: string
hostname: hostname:
description: Name of the host (= node)
type: string type: string
hwthreads: hwthreads:
description: List of OS processor ids
items: items:
type: integer type: integer
type: array type: array
@ -580,6 +535,10 @@ definitions:
items: items:
type: number type: number
type: array type: array
median:
items:
type: number
type: array
min: min:
items: items:
type: number type: number
@ -595,12 +554,24 @@ definitions:
properties: properties:
coresPerSocket: coresPerSocket:
type: integer type: integer
energyFootprint:
items:
type: string
type: array
flopRateScalar: flopRateScalar:
$ref: '#/definitions/schema.MetricValue' $ref: '#/definitions/schema.MetricValue'
flopRateSimd: flopRateSimd:
$ref: '#/definitions/schema.MetricValue' $ref: '#/definitions/schema.MetricValue'
footprint:
items:
type: string
type: array
memoryBandwidth: memoryBandwidth:
$ref: '#/definitions/schema.MetricValue' $ref: '#/definitions/schema.MetricValue'
metricConfig:
items:
$ref: '#/definitions/schema.MetricConfig'
type: array
name: name:
type: string type: string
nodes: nodes:
@ -620,6 +591,12 @@ definitions:
type: number type: number
caution: caution:
type: number type: number
energy:
type: string
footprint:
type: string
lowerIsBetter:
type: boolean
name: name:
type: string type: string
normal: normal:
@ -633,14 +610,14 @@ definitions:
description: Defines a tag using name and type. description: Defines a tag using name and type.
properties: properties:
id: id:
description: The unique DB identifier of a tag
type: integer type: integer
name: name:
description: Tag Name
example: Testjob example: Testjob
type: string type: string
scope:
example: global
type: string
type: type:
description: Tag Type
example: Debug example: Debug
type: string type: string
type: object type: object
@ -1197,68 +1174,13 @@ paths:
summary: Marks job as completed and triggers archiving summary: Marks job as completed and triggers archiving
tags: tags:
- Job add and modify - Job add and modify
/jobs/stop_job/{id}:
post:
consumes:
- application/json
description: |-
Job to stop is specified by database ID. Only stopTime and final state are required in request body.
Returns full job resource information according to 'JobMeta' scheme.
parameters:
- description: Database ID of Job
in: path
name: id
required: true
type: integer
- description: stopTime and final state in request body
in: body
name: request
required: true
schema:
$ref: '#/definitions/api.StopJobApiRequest'
produces:
- application/json
responses:
"200":
description: Job resource
schema:
$ref: '#/definitions/schema.JobMeta'
"400":
description: Bad Request
schema:
$ref: '#/definitions/api.ErrorResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/api.ErrorResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/api.ErrorResponse'
"404":
description: Resource not found
schema:
$ref: '#/definitions/api.ErrorResponse'
"422":
description: 'Unprocessable Entity: finding job failed: sql: no rows in
result set'
schema:
$ref: '#/definitions/api.ErrorResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/api.ErrorResponse'
security:
- ApiKeyAuth: []
summary: Marks job as completed and triggers archiving
tags:
- Job add and modify
/jobs/tag_job/{id}: /jobs/tag_job/{id}:
post: post:
consumes: consumes:
- application/json - application/json
description: |- description: |-
Adds tag(s) to a job specified by DB ID. Name and Type of Tag(s) can be chosen freely. Adds tag(s) to a job specified by DB ID. Name and Type of Tag(s) can be chosen freely.
Tag Scope for frontend visibility will default to "global" if none entered, other options: "admin" or specific username.
If tagged job is already finished: Tag will be written directly to respective archive files. If tagged job is already finished: Tag will be written directly to respective archive files.
parameters: parameters:
- description: Job Database ID - description: Job Database ID

View File

@ -14,9 +14,9 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
"strconv"
"strings" "strings"
"testing" "testing"
"time"
"github.com/ClusterCockpit/cc-backend/internal/api" "github.com/ClusterCockpit/cc-backend/internal/api"
"github.com/ClusterCockpit/cc-backend/internal/archiver" "github.com/ClusterCockpit/cc-backend/internal/archiver"
@ -200,6 +200,10 @@ func TestRestApi(t *testing.T) {
r.StrictSlash(true) r.StrictSlash(true)
restapi.MountApiRoutes(r) restapi.MountApiRoutes(r)
var TestJobId int64 = 123
var TestClusterName string = "testcluster"
var TestStartTime int64 = 123456789
const startJobBody string = `{ const startJobBody string = `{
"jobId": 123, "jobId": 123,
"user": "testuser", "user": "testuser",
@ -225,7 +229,6 @@ func TestRestApi(t *testing.T) {
"startTime": 123456789 "startTime": 123456789
}` }`
var dbid int64
const contextUserKey repository.ContextKey = "user" const contextUserKey repository.ContextKey = "user"
contextUserValue := &schema.User{ contextUserValue := &schema.User{
Username: "testuser", Username: "testuser",
@ -247,13 +250,10 @@ func TestRestApi(t *testing.T) {
t.Fatal(response.Status, recorder.Body.String()) t.Fatal(response.Status, recorder.Body.String())
} }
var res api.StartJobApiResponse time.Sleep(1 * time.Second)
if err := json.Unmarshal(recorder.Body.Bytes(), &res); err != nil {
t.Fatal(err)
}
resolver := graph.GetResolverInstance() resolver := graph.GetResolverInstance()
job, err := resolver.Query().Job(ctx, strconv.Itoa(int(res.DBID))) job, err := restapi.JobRepository.Find(&TestJobId, &TestClusterName, &TestStartTime)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -285,8 +285,6 @@ func TestRestApi(t *testing.T) {
if len(job.Tags) != 1 || job.Tags[0].Type != "testTagType" || job.Tags[0].Name != "testTagName" || job.Tags[0].Scope != "testuser" { if len(job.Tags) != 1 || job.Tags[0].Type != "testTagType" || job.Tags[0].Name != "testTagName" || job.Tags[0].Scope != "testuser" {
t.Fatalf("unexpected tags: %#v", job.Tags) t.Fatalf("unexpected tags: %#v", job.Tags)
} }
dbid = res.DBID
}); !ok { }); !ok {
return return
} }
@ -314,8 +312,7 @@ func TestRestApi(t *testing.T) {
} }
archiver.WaitForArchiving() archiver.WaitForArchiving()
resolver := graph.GetResolverInstance() job, err := restapi.JobRepository.Find(&TestJobId, &TestClusterName, &TestStartTime)
job, err := resolver.Query().Job(ctx, strconv.Itoa(int(dbid)))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -404,8 +401,10 @@ func TestRestApi(t *testing.T) {
t.Fatal("subtest failed") t.Fatal("subtest failed")
} }
time.Sleep(1 * time.Second)
const stopJobBodyFailed string = `{ const stopJobBodyFailed string = `{
"jobId": 12345, "jobId": 12345,
"cluster": "testcluster", "cluster": "testcluster",
"jobState": "failed", "jobState": "failed",

View File

@ -601,88 +601,6 @@ const docTemplate = `{
} }
} }
}, },
"/jobs/stop_job/{id}": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Job to stop is specified by database ID. Only stopTime and final state are required in request body.\nReturns full job resource information according to 'JobMeta' scheme.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Job add and modify"
],
"summary": "Marks job as completed and triggers archiving",
"parameters": [
{
"type": "integer",
"description": "Database ID of Job",
"name": "id",
"in": "path",
"required": true
},
{
"description": "stopTime and final state in request body",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.StopJobApiRequest"
}
}
],
"responses": {
"200": {
"description": "Job resource",
"schema": {
"$ref": "#/definitions/schema.JobMeta"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"404": {
"description": "Resource not found",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"422": {
"description": "Unprocessable Entity: finding job failed: sql: no rows in result set",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
}
}
}
},
"/jobs/tag_job/{id}": { "/jobs/tag_job/{id}": {
"post": { "post": {
"security": [ "security": [
@ -690,7 +608,7 @@ const docTemplate = `{
"ApiKeyAuth": [] "ApiKeyAuth": []
} }
], ],
"description": "Adds tag(s) to a job specified by DB ID. Name and Type of Tag(s) can be chosen freely.\nIf tagged job is already finished: Tag will be written directly to respective archive files.", "description": "Adds tag(s) to a job specified by DB ID. Name and Type of Tag(s) can be chosen freely.\nTag Scope for frontend visibility will default to \"global\" if none entered, other options: \"admin\" or specific username.\nIf tagged job is already finished: Tag will be written directly to respective archive files.",
"consumes": [ "consumes": [
"application/json" "application/json"
], ],
@ -1283,6 +1201,11 @@ const docTemplate = `{
"type": "string", "type": "string",
"example": "Testjob" "example": "Testjob"
}, },
"scope": {
"description": "Tag Scope for Frontend Display",
"type": "string",
"example": "global"
},
"type": { "type": {
"description": "Tag Type", "description": "Tag Type",
"type": "string", "type": "string",
@ -1410,9 +1333,8 @@ const docTemplate = `{
"api.StartJobApiResponse": { "api.StartJobApiResponse": {
"type": "object", "type": "object",
"properties": { "properties": {
"id": { "msg": {
"description": "Database ID of new job", "type": "string"
"type": "integer"
} }
} }
}, },
@ -1424,17 +1346,14 @@ const docTemplate = `{
], ],
"properties": { "properties": {
"cluster": { "cluster": {
"description": "Cluster of job",
"type": "string", "type": "string",
"example": "fritz" "example": "fritz"
}, },
"jobId": { "jobId": {
"description": "Cluster Job ID of job",
"type": "integer", "type": "integer",
"example": 123000 "example": 123000
}, },
"jobState": { "jobState": {
"description": "Final job state",
"allOf": [ "allOf": [
{ {
"$ref": "#/definitions/schema.JobState" "$ref": "#/definitions/schema.JobState"
@ -1443,12 +1362,10 @@ const docTemplate = `{
"example": "completed" "example": "completed"
}, },
"startTime": { "startTime": {
"description": "Start Time of job as epoch",
"type": "integer", "type": "integer",
"example": 1649723812 "example": 1649723812
}, },
"stopTime": { "stopTime": {
"description": "Stop Time of job as epoch",
"type": "integer", "type": "integer",
"example": 1649763839 "example": 1649763839
} }
@ -1493,12 +1410,10 @@ const docTemplate = `{
"type": "object", "type": "object",
"properties": { "properties": {
"arrayJobId": { "arrayJobId": {
"description": "The unique identifier of an array job",
"type": "integer", "type": "integer",
"example": 123000 "example": 123000
}, },
"cluster": { "cluster": {
"description": "The unique identifier of a cluster",
"type": "string", "type": "string",
"example": "fritz" "example": "fritz"
}, },
@ -1506,33 +1421,39 @@ const docTemplate = `{
"$ref": "#/definitions/schema.JobLinkResultList" "$ref": "#/definitions/schema.JobLinkResultList"
}, },
"duration": { "duration": {
"description": "Duration of job in seconds (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 43200 "example": 43200
}, },
"energy": {
"type": "number"
},
"energyFootprint": {
"type": "object",
"additionalProperties": {
"type": "number"
}
},
"exclusive": { "exclusive": {
"description": "Specifies how nodes are shared: 0 - Shared among multiple jobs of multiple users, 1 - Job exclusive (Default), 2 - Shared among multiple jobs of same user",
"type": "integer", "type": "integer",
"maximum": 2, "maximum": 2,
"minimum": 0, "minimum": 0,
"example": 1 "example": 1
}, },
"flopsAnyAvg": { "footprint": {
"description": "FlopsAnyAvg as Float64", "type": "object",
"type": "number" "additionalProperties": {
"type": "number"
}
}, },
"id": { "id": {
"description": "The unique identifier of a job in the database",
"type": "integer" "type": "integer"
}, },
"jobId": { "jobId": {
"description": "The unique identifier of a job",
"type": "integer", "type": "integer",
"example": 123000 "example": 123000
}, },
"jobState": { "jobState": {
"description": "Final state of job",
"enum": [ "enum": [
"completed", "completed",
"failed", "failed",
@ -1548,95 +1469,69 @@ const docTemplate = `{
], ],
"example": "completed" "example": "completed"
}, },
"loadAvg": {
"description": "LoadAvg as Float64",
"type": "number"
},
"memBwAvg": {
"description": "MemBwAvg as Float64",
"type": "number"
},
"memUsedMax": {
"description": "MemUsedMax as Float64",
"type": "number"
},
"metaData": { "metaData": {
"description": "Additional information about the job",
"type": "object", "type": "object",
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
} }
}, },
"monitoringStatus": { "monitoringStatus": {
"description": "State of monitoring system during job run: 0 - Disabled, 1 - Running or Archiving (Default), 2 - Archiving Failed, 3 - Archiving Successfull",
"type": "integer", "type": "integer",
"maximum": 3, "maximum": 3,
"minimum": 0, "minimum": 0,
"example": 1 "example": 1
}, },
"numAcc": { "numAcc": {
"description": "Number of accelerators used (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 2 "example": 2
}, },
"numHwthreads": { "numHwthreads": {
"description": "NumCores int32 ` + "`" + `json:\"numCores\" db:\"num_cores\" example:\"20\" minimum:\"1\"` + "`" + ` // Number of HWThreads used (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 20 "example": 20
}, },
"numNodes": { "numNodes": {
"description": "Number of nodes used (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 2 "example": 2
}, },
"partition": { "partition": {
"description": "The Slurm partition to which the job was submitted",
"type": "string", "type": "string",
"example": "main" "example": "main"
}, },
"project": { "project": {
"description": "The unique identifier of a project",
"type": "string", "type": "string",
"example": "abcd200" "example": "abcd200"
}, },
"resources": { "resources": {
"description": "Resources used by job",
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/schema.Resource" "$ref": "#/definitions/schema.Resource"
} }
}, },
"smt": { "smt": {
"description": "SMT threads used by job",
"type": "integer", "type": "integer",
"example": 4 "example": 4
}, },
"startTime": { "startTime": {
"description": "Start time as 'time.Time' data type",
"type": "string" "type": "string"
}, },
"subCluster": { "subCluster": {
"description": "The unique identifier of a sub cluster",
"type": "string", "type": "string",
"example": "main" "example": "main"
}, },
"tags": { "tags": {
"description": "List of tags",
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/schema.Tag" "$ref": "#/definitions/schema.Tag"
} }
}, },
"user": { "user": {
"description": "The unique identifier of a user",
"type": "string", "type": "string",
"example": "abcd100h" "example": "abcd100h"
}, },
"walltime": { "walltime": {
"description": "Requested walltime of job in seconds (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 86400 "example": 86400
@ -1673,12 +1568,10 @@ const docTemplate = `{
"type": "object", "type": "object",
"properties": { "properties": {
"arrayJobId": { "arrayJobId": {
"description": "The unique identifier of an array job",
"type": "integer", "type": "integer",
"example": 123000 "example": 123000
}, },
"cluster": { "cluster": {
"description": "The unique identifier of a cluster",
"type": "string", "type": "string",
"example": "fritz" "example": "fritz"
}, },
@ -1686,29 +1579,39 @@ const docTemplate = `{
"$ref": "#/definitions/schema.JobLinkResultList" "$ref": "#/definitions/schema.JobLinkResultList"
}, },
"duration": { "duration": {
"description": "Duration of job in seconds (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 43200 "example": 43200
}, },
"energy": {
"type": "number"
},
"energyFootprint": {
"type": "object",
"additionalProperties": {
"type": "number"
}
},
"exclusive": { "exclusive": {
"description": "Specifies how nodes are shared: 0 - Shared among multiple jobs of multiple users, 1 - Job exclusive (Default), 2 - Shared among multiple jobs of same user",
"type": "integer", "type": "integer",
"maximum": 2, "maximum": 2,
"minimum": 0, "minimum": 0,
"example": 1 "example": 1
}, },
"footprint": {
"type": "object",
"additionalProperties": {
"type": "number"
}
},
"id": { "id": {
"description": "The unique identifier of a job in the database",
"type": "integer" "type": "integer"
}, },
"jobId": { "jobId": {
"description": "The unique identifier of a job",
"type": "integer", "type": "integer",
"example": 123000 "example": 123000
}, },
"jobState": { "jobState": {
"description": "Final state of job",
"enum": [ "enum": [
"completed", "completed",
"failed", "failed",
@ -1725,91 +1628,76 @@ const docTemplate = `{
"example": "completed" "example": "completed"
}, },
"metaData": { "metaData": {
"description": "Additional information about the job",
"type": "object", "type": "object",
"additionalProperties": { "additionalProperties": {
"type": "string" "type": "string"
} }
}, },
"monitoringStatus": { "monitoringStatus": {
"description": "State of monitoring system during job run: 0 - Disabled, 1 - Running or Archiving (Default), 2 - Archiving Failed, 3 - Archiving Successfull",
"type": "integer", "type": "integer",
"maximum": 3, "maximum": 3,
"minimum": 0, "minimum": 0,
"example": 1 "example": 1
}, },
"numAcc": { "numAcc": {
"description": "Number of accelerators used (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 2 "example": 2
}, },
"numHwthreads": { "numHwthreads": {
"description": "NumCores int32 ` + "`" + `json:\"numCores\" db:\"num_cores\" example:\"20\" minimum:\"1\"` + "`" + ` // Number of HWThreads used (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 20 "example": 20
}, },
"numNodes": { "numNodes": {
"description": "Number of nodes used (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 2 "example": 2
}, },
"partition": { "partition": {
"description": "The Slurm partition to which the job was submitted",
"type": "string", "type": "string",
"example": "main" "example": "main"
}, },
"project": { "project": {
"description": "The unique identifier of a project",
"type": "string", "type": "string",
"example": "abcd200" "example": "abcd200"
}, },
"resources": { "resources": {
"description": "Resources used by job",
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/schema.Resource" "$ref": "#/definitions/schema.Resource"
} }
}, },
"smt": { "smt": {
"description": "SMT threads used by job",
"type": "integer", "type": "integer",
"example": 4 "example": 4
}, },
"startTime": { "startTime": {
"description": "Start epoch time stamp in seconds (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 1649723812 "example": 1649723812
}, },
"statistics": { "statistics": {
"description": "Metric statistics of job",
"type": "object", "type": "object",
"additionalProperties": { "additionalProperties": {
"$ref": "#/definitions/schema.JobStatistics" "$ref": "#/definitions/schema.JobStatistics"
} }
}, },
"subCluster": { "subCluster": {
"description": "The unique identifier of a sub cluster",
"type": "string", "type": "string",
"example": "main" "example": "main"
}, },
"tags": { "tags": {
"description": "List of tags",
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/schema.Tag" "$ref": "#/definitions/schema.Tag"
} }
}, },
"user": { "user": {
"description": "The unique identifier of a user",
"type": "string", "type": "string",
"example": "abcd100h" "example": "abcd100h"
}, },
"walltime": { "walltime": {
"description": "Requested walltime of job in seconds (Min \u003e 0)",
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
"example": 86400 "example": 86400
@ -1898,6 +1786,15 @@ const docTemplate = `{
"caution": { "caution": {
"type": "number" "type": "number"
}, },
"energy": {
"type": "string"
},
"footprint": {
"type": "string"
},
"lowerIsBetter": {
"type": "boolean"
},
"name": { "name": {
"type": "string" "type": "string"
}, },
@ -1975,22 +1872,18 @@ const docTemplate = `{
"type": "object", "type": "object",
"properties": { "properties": {
"accelerators": { "accelerators": {
"description": "List of of accelerator device ids",
"type": "array", "type": "array",
"items": { "items": {
"type": "string" "type": "string"
} }
}, },
"configuration": { "configuration": {
"description": "The configuration options of the node",
"type": "string" "type": "string"
}, },
"hostname": { "hostname": {
"description": "Name of the host (= node)",
"type": "string" "type": "string"
}, },
"hwthreads": { "hwthreads": {
"description": "List of OS processor ids",
"type": "array", "type": "array",
"items": { "items": {
"type": "integer" "type": "integer"
@ -2033,6 +1926,12 @@ const docTemplate = `{
"type": "number" "type": "number"
} }
}, },
"median": {
"type": "array",
"items": {
"type": "number"
}
},
"min": { "min": {
"type": "array", "type": "array",
"items": { "items": {
@ -2056,15 +1955,33 @@ const docTemplate = `{
"coresPerSocket": { "coresPerSocket": {
"type": "integer" "type": "integer"
}, },
"energyFootprint": {
"type": "array",
"items": {
"type": "string"
}
},
"flopRateScalar": { "flopRateScalar": {
"$ref": "#/definitions/schema.MetricValue" "$ref": "#/definitions/schema.MetricValue"
}, },
"flopRateSimd": { "flopRateSimd": {
"$ref": "#/definitions/schema.MetricValue" "$ref": "#/definitions/schema.MetricValue"
}, },
"footprint": {
"type": "array",
"items": {
"type": "string"
}
},
"memoryBandwidth": { "memoryBandwidth": {
"$ref": "#/definitions/schema.MetricValue" "$ref": "#/definitions/schema.MetricValue"
}, },
"metricConfig": {
"type": "array",
"items": {
"$ref": "#/definitions/schema.MetricConfig"
}
},
"name": { "name": {
"type": "string" "type": "string"
}, },
@ -2094,6 +2011,15 @@ const docTemplate = `{
"caution": { "caution": {
"type": "number" "type": "number"
}, },
"energy": {
"type": "string"
},
"footprint": {
"type": "string"
},
"lowerIsBetter": {
"type": "boolean"
},
"name": { "name": {
"type": "string" "type": "string"
}, },
@ -2113,16 +2039,17 @@ const docTemplate = `{
"type": "object", "type": "object",
"properties": { "properties": {
"id": { "id": {
"description": "The unique DB identifier of a tag",
"type": "integer" "type": "integer"
}, },
"name": { "name": {
"description": "Tag Name",
"type": "string", "type": "string",
"example": "Testjob" "example": "Testjob"
}, },
"scope": {
"type": "string",
"example": "global"
},
"type": { "type": {
"description": "Tag Type",
"type": "string", "type": "string",
"example": "Debug" "example": "Debug"
} }

View File

@ -124,8 +124,7 @@ func (api *RestApi) MountFrontendApiRoutes(r *mux.Router) {
// StartJobApiResponse model // StartJobApiResponse model
type StartJobApiResponse struct { type StartJobApiResponse struct {
// Database ID of new job Message string `json:"msg"`
DBID int64 `json:"id"`
} }
// DeleteJobApiResponse model // DeleteJobApiResponse model
@ -806,25 +805,10 @@ func (api *RestApi) startJob(rw http.ResponseWriter, r *http.Request) {
repository.TriggerJobStart(repository.JobWithUser{Job: &req, User: repository.GetUserFromContext(r.Context())}) repository.TriggerJobStart(repository.JobWithUser{Job: &req, User: repository.GetUserFromContext(r.Context())})
id, err := api.JobRepository.Start(&req)
if err != nil {
handleError(fmt.Errorf("insert into database failed: %w", err), http.StatusInternalServerError, rw)
return
}
for _, tag := range req.Tags {
if _, err := api.JobRepository.AddTagOrCreate(repository.GetUserFromContext(r.Context()), id, tag.Type, tag.Name, tag.Scope); err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
handleError(fmt.Errorf("adding tag to new job %d failed: %w", id, err), http.StatusInternalServerError, rw)
return
}
}
log.Printf("new job (id: %d): cluster=%s, jobId=%d, user=%s, startTime=%d", id, req.Cluster, req.JobID, req.User, req.StartTime)
rw.Header().Add("Content-Type", "application/json") rw.Header().Add("Content-Type", "application/json")
rw.WriteHeader(http.StatusCreated) rw.WriteHeader(http.StatusCreated)
json.NewEncoder(rw).Encode(StartJobApiResponse{ json.NewEncoder(rw).Encode(StartJobApiResponse{
DBID: id, Message: fmt.Sprintf("Successfully triggered job start"),
}) })
} }

View File

@ -6,6 +6,7 @@ package repository
import ( import (
"sync" "sync"
"time"
"github.com/ClusterCockpit/cc-backend/pkg/log" "github.com/ClusterCockpit/cc-backend/pkg/log"
"github.com/ClusterCockpit/cc-backend/pkg/schema" "github.com/ClusterCockpit/cc-backend/pkg/schema"
@ -36,18 +37,30 @@ func jobStartWorker() {
break break
} }
jobRepo := GetJobRepository() jobRepo := GetJobRepository()
var id int64
id, err := jobRepo.Start(req.Job) for i := 0; i < 5; i++ {
if err != nil { var err error
log.Errorf("insert into database failed: %v", err)
id, err = jobRepo.Start(req.Job)
if err != nil {
log.Errorf("Attempt %d: insert into database failed: %v", i, err)
} else {
break
}
time.Sleep(1 * time.Second)
} }
for _, tag := range req.Job.Tags { for _, tag := range req.Job.Tags {
if _, err := jobRepo.AddTagOrCreate(req.User, id, tag.Type, tag.Name, tag.Scope); err != nil { if _, err := jobRepo.AddTagOrCreate(req.User, id,
tag.Type, tag.Name, tag.Scope); err != nil {
log.Errorf("adding tag to new job %d failed: %v", id, err) log.Errorf("adding tag to new job %d failed: %v", id, err)
} }
} }
log.Printf("new job (id: %d): cluster=%s, jobId=%d, user=%s, startTime=%d",
id, req.Job.Cluster, req.Job.JobID, req.Job.User, req.Job.StartTime)
jobStartPending.Done() jobStartPending.Done()
} }
} }