mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-07-01 11:13:50 +02:00
Merge branch 'dev' into migrate_svelte5
This commit is contained in:
commit
a0190f8f40
@ -393,7 +393,6 @@ type TimeRangeOutput {
|
|||||||
input NodeFilter {
|
input NodeFilter {
|
||||||
hostname: StringInput
|
hostname: StringInput
|
||||||
cluster: StringInput
|
cluster: StringInput
|
||||||
subCluster: StringInput
|
|
||||||
nodeState: NodeState
|
nodeState: NodeState
|
||||||
healthState: MonitoringState
|
healthState: MonitoringState
|
||||||
}
|
}
|
||||||
|
273
api/swagger.json
273
api/swagger.json
@ -201,7 +201,7 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "Success message",
|
"description": "Success message",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.DefaultJobApiResponse"
|
"$ref": "#/definitions/api.DefaultApiResponse"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
@ -271,7 +271,7 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "Success message",
|
"description": "Success message",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.DefaultJobApiResponse"
|
"$ref": "#/definitions/api.DefaultApiResponse"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
@ -341,7 +341,7 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "Success message",
|
"description": "Success message",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.DefaultJobApiResponse"
|
"$ref": "#/definitions/api.DefaultApiResponse"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
@ -460,7 +460,7 @@
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Job specified in request body will be saved to database as \"running\" with new DB ID.\nJob specifications follow the 'JobMeta' scheme, API will fail to execute if requirements are not met.",
|
"description": "Job specified in request body will be saved to database as \"running\" with new DB ID.\nJob specifications follow the 'Job' scheme, API will fail to execute if requirements are not met.",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@ -478,7 +478,7 @@
|
|||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/schema.JobMeta"
|
"$ref": "#/definitions/schema.Job"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -486,7 +486,7 @@
|
|||||||
"201": {
|
"201": {
|
||||||
"description": "Job added successfully",
|
"description": "Job added successfully",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.DefaultJobApiResponse"
|
"$ref": "#/definitions/api.DefaultApiResponse"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
@ -529,7 +529,7 @@
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Job to stop is specified by request body. All fields are required in this case.\nReturns full job resource information according to 'JobMeta' scheme.",
|
"description": "Job to stop is specified by request body. All fields are required in this case.\nReturns full job resource information according to 'Job' scheme.",
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@ -552,7 +552,7 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "Success message",
|
"description": "Success message",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/schema.JobMeta"
|
"$ref": "#/definitions/schema.Job"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
@ -674,7 +674,7 @@
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Job to get is specified by database ID\nReturns full job resource information according to 'JobMeta' scheme and all metrics according to 'JobData'.",
|
"description": "Job to get is specified by database ID\nReturns full job resource information according to 'Job' scheme and all metrics according to 'JobData'.",
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@ -748,7 +748,7 @@
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Job to get is specified by database ID\nReturns full job resource information according to 'JobMeta' scheme and all metrics according to 'JobData'.",
|
"description": "Job to get is specified by database ID\nReturns full job resource information according to 'Job' scheme and all metrics according to 'JobData'.",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@ -826,6 +826,66 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/nodestats/": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Returns a JSON-encoded list of users.\nRequired query-parameter defines if all users or only users with additional special roles are returned.",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Nodestates"
|
||||||
|
],
|
||||||
|
"summary": "Deliver updated Slurm node states",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Request body containing nodes and their states",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.UpdateNodeStatesRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success message",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.DefaultApiResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/users/": {
|
"/api/users/": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@ -1074,7 +1134,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"api.DefaultJobApiResponse": {
|
"api.DefaultApiResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"msg": {
|
"msg": {
|
||||||
@ -1168,7 +1228,7 @@
|
|||||||
"description": "Array of jobs",
|
"description": "Array of jobs",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/schema.JobMeta"
|
"$ref": "#/definitions/schema.Job"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"page": {
|
"page": {
|
||||||
@ -1191,6 +1251,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"api.Node": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"hostname": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"states": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"api.StopJobApiRequest": {
|
"api.StopJobApiRequest": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@ -1224,6 +1298,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"api.UpdateNodeStatesRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"cluster": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "fritz"
|
||||||
|
},
|
||||||
|
"nodes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/api.Node"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"schema.Accelerator": {
|
"schema.Accelerator": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -1259,7 +1348,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"schema.Job": {
|
"schema.Job": {
|
||||||
"description": "Information of a HPC job.",
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"arrayJobId": {
|
"arrayJobId": {
|
||||||
@ -1357,6 +1445,12 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"example": "abcd200"
|
"example": "abcd200"
|
||||||
},
|
},
|
||||||
|
"requestedMemory": {
|
||||||
|
"description": "in MB",
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1,
|
||||||
|
"example": 128000
|
||||||
|
},
|
||||||
"resources": {
|
"resources": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
@ -1368,7 +1462,14 @@
|
|||||||
"example": 4
|
"example": 4
|
||||||
},
|
},
|
||||||
"startTime": {
|
"startTime": {
|
||||||
"type": "string"
|
"type": "integer",
|
||||||
|
"example": 1649723812
|
||||||
|
},
|
||||||
|
"statistics": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"$ref": "#/definitions/schema.JobStatistics"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"subCluster": {
|
"subCluster": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@ -1416,147 +1517,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"schema.JobMeta": {
|
|
||||||
"description": "Meta data information of a HPC job.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"arrayJobId": {
|
|
||||||
"type": "integer",
|
|
||||||
"example": 123000
|
|
||||||
},
|
|
||||||
"cluster": {
|
|
||||||
"type": "string",
|
|
||||||
"example": "fritz"
|
|
||||||
},
|
|
||||||
"concurrentJobs": {
|
|
||||||
"$ref": "#/definitions/schema.JobLinkResultList"
|
|
||||||
},
|
|
||||||
"duration": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"example": 43200
|
|
||||||
},
|
|
||||||
"energy": {
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"energyFootprint": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": {
|
|
||||||
"type": "number"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"exclusive": {
|
|
||||||
"type": "integer",
|
|
||||||
"maximum": 2,
|
|
||||||
"minimum": 0,
|
|
||||||
"example": 1
|
|
||||||
},
|
|
||||||
"footprint": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": {
|
|
||||||
"type": "number"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"id": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"jobId": {
|
|
||||||
"type": "integer",
|
|
||||||
"example": 123000
|
|
||||||
},
|
|
||||||
"jobState": {
|
|
||||||
"enum": [
|
|
||||||
"completed",
|
|
||||||
"failed",
|
|
||||||
"cancelled",
|
|
||||||
"stopped",
|
|
||||||
"timeout",
|
|
||||||
"out_of_memory"
|
|
||||||
],
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/schema.JobState"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"example": "completed"
|
|
||||||
},
|
|
||||||
"metaData": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"monitoringStatus": {
|
|
||||||
"type": "integer",
|
|
||||||
"maximum": 3,
|
|
||||||
"minimum": 0,
|
|
||||||
"example": 1
|
|
||||||
},
|
|
||||||
"numAcc": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"example": 2
|
|
||||||
},
|
|
||||||
"numHwthreads": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"example": 20
|
|
||||||
},
|
|
||||||
"numNodes": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"example": 2
|
|
||||||
},
|
|
||||||
"partition": {
|
|
||||||
"type": "string",
|
|
||||||
"example": "main"
|
|
||||||
},
|
|
||||||
"project": {
|
|
||||||
"type": "string",
|
|
||||||
"example": "abcd200"
|
|
||||||
},
|
|
||||||
"resources": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/definitions/schema.Resource"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"smt": {
|
|
||||||
"type": "integer",
|
|
||||||
"example": 4
|
|
||||||
},
|
|
||||||
"startTime": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"example": 1649723812
|
|
||||||
},
|
|
||||||
"statistics": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": {
|
|
||||||
"$ref": "#/definitions/schema.JobStatistics"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"subCluster": {
|
|
||||||
"type": "string",
|
|
||||||
"example": "main"
|
|
||||||
},
|
|
||||||
"tags": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/definitions/schema.Tag"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"user": {
|
|
||||||
"type": "string",
|
|
||||||
"example": "abcd100h"
|
|
||||||
},
|
|
||||||
"walltime": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"example": 86400
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"schema.JobMetric": {
|
"schema.JobMetric": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -1884,6 +1844,9 @@
|
|||||||
},
|
},
|
||||||
"remove": {
|
"remove": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"unit": {
|
||||||
|
"$ref": "#/definitions/schema.Unit"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
201
api/swagger.yaml
201
api/swagger.yaml
@ -31,7 +31,7 @@ definitions:
|
|||||||
example: Debug
|
example: Debug
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
api.DefaultJobApiResponse:
|
api.DefaultApiResponse:
|
||||||
properties:
|
properties:
|
||||||
msg:
|
msg:
|
||||||
type: string
|
type: string
|
||||||
@ -96,7 +96,7 @@ definitions:
|
|||||||
jobs:
|
jobs:
|
||||||
description: Array of jobs
|
description: Array of jobs
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/schema.JobMeta'
|
$ref: '#/definitions/schema.Job'
|
||||||
type: array
|
type: array
|
||||||
page:
|
page:
|
||||||
description: Page id returned
|
description: Page id returned
|
||||||
@ -111,6 +111,15 @@ definitions:
|
|||||||
scope:
|
scope:
|
||||||
$ref: '#/definitions/schema.MetricScope'
|
$ref: '#/definitions/schema.MetricScope'
|
||||||
type: object
|
type: object
|
||||||
|
api.Node:
|
||||||
|
properties:
|
||||||
|
hostname:
|
||||||
|
type: string
|
||||||
|
states:
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
api.StopJobApiRequest:
|
api.StopJobApiRequest:
|
||||||
properties:
|
properties:
|
||||||
cluster:
|
cluster:
|
||||||
@ -133,6 +142,16 @@ definitions:
|
|||||||
- jobState
|
- jobState
|
||||||
- stopTime
|
- stopTime
|
||||||
type: object
|
type: object
|
||||||
|
api.UpdateNodeStatesRequest:
|
||||||
|
properties:
|
||||||
|
cluster:
|
||||||
|
example: fritz
|
||||||
|
type: string
|
||||||
|
nodes:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/api.Node'
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
schema.Accelerator:
|
schema.Accelerator:
|
||||||
properties:
|
properties:
|
||||||
id:
|
id:
|
||||||
@ -156,7 +175,6 @@ definitions:
|
|||||||
type: array
|
type: array
|
||||||
type: object
|
type: object
|
||||||
schema.Job:
|
schema.Job:
|
||||||
description: Information of a HPC job.
|
|
||||||
properties:
|
properties:
|
||||||
arrayJobId:
|
arrayJobId:
|
||||||
example: 123000
|
example: 123000
|
||||||
@ -228,6 +246,11 @@ definitions:
|
|||||||
project:
|
project:
|
||||||
example: abcd200
|
example: abcd200
|
||||||
type: string
|
type: string
|
||||||
|
requestedMemory:
|
||||||
|
description: in MB
|
||||||
|
example: 128000
|
||||||
|
minimum: 1
|
||||||
|
type: integer
|
||||||
resources:
|
resources:
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/schema.Resource'
|
$ref: '#/definitions/schema.Resource'
|
||||||
@ -236,7 +259,12 @@ definitions:
|
|||||||
example: 4
|
example: 4
|
||||||
type: integer
|
type: integer
|
||||||
startTime:
|
startTime:
|
||||||
type: string
|
example: 1649723812
|
||||||
|
type: integer
|
||||||
|
statistics:
|
||||||
|
additionalProperties:
|
||||||
|
$ref: '#/definitions/schema.JobStatistics'
|
||||||
|
type: object
|
||||||
subCluster:
|
subCluster:
|
||||||
example: main
|
example: main
|
||||||
type: string
|
type: string
|
||||||
@ -268,109 +296,6 @@ definitions:
|
|||||||
$ref: '#/definitions/schema.JobLink'
|
$ref: '#/definitions/schema.JobLink'
|
||||||
type: array
|
type: array
|
||||||
type: object
|
type: object
|
||||||
schema.JobMeta:
|
|
||||||
description: Meta data information of a HPC job.
|
|
||||||
properties:
|
|
||||||
arrayJobId:
|
|
||||||
example: 123000
|
|
||||||
type: integer
|
|
||||||
cluster:
|
|
||||||
example: fritz
|
|
||||||
type: string
|
|
||||||
concurrentJobs:
|
|
||||||
$ref: '#/definitions/schema.JobLinkResultList'
|
|
||||||
duration:
|
|
||||||
example: 43200
|
|
||||||
minimum: 1
|
|
||||||
type: integer
|
|
||||||
energy:
|
|
||||||
type: number
|
|
||||||
energyFootprint:
|
|
||||||
additionalProperties:
|
|
||||||
type: number
|
|
||||||
type: object
|
|
||||||
exclusive:
|
|
||||||
example: 1
|
|
||||||
maximum: 2
|
|
||||||
minimum: 0
|
|
||||||
type: integer
|
|
||||||
footprint:
|
|
||||||
additionalProperties:
|
|
||||||
type: number
|
|
||||||
type: object
|
|
||||||
id:
|
|
||||||
type: integer
|
|
||||||
jobId:
|
|
||||||
example: 123000
|
|
||||||
type: integer
|
|
||||||
jobState:
|
|
||||||
allOf:
|
|
||||||
- $ref: '#/definitions/schema.JobState'
|
|
||||||
enum:
|
|
||||||
- completed
|
|
||||||
- failed
|
|
||||||
- cancelled
|
|
||||||
- stopped
|
|
||||||
- timeout
|
|
||||||
- out_of_memory
|
|
||||||
example: completed
|
|
||||||
metaData:
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
monitoringStatus:
|
|
||||||
example: 1
|
|
||||||
maximum: 3
|
|
||||||
minimum: 0
|
|
||||||
type: integer
|
|
||||||
numAcc:
|
|
||||||
example: 2
|
|
||||||
minimum: 1
|
|
||||||
type: integer
|
|
||||||
numHwthreads:
|
|
||||||
example: 20
|
|
||||||
minimum: 1
|
|
||||||
type: integer
|
|
||||||
numNodes:
|
|
||||||
example: 2
|
|
||||||
minimum: 1
|
|
||||||
type: integer
|
|
||||||
partition:
|
|
||||||
example: main
|
|
||||||
type: string
|
|
||||||
project:
|
|
||||||
example: abcd200
|
|
||||||
type: string
|
|
||||||
resources:
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/schema.Resource'
|
|
||||||
type: array
|
|
||||||
smt:
|
|
||||||
example: 4
|
|
||||||
type: integer
|
|
||||||
startTime:
|
|
||||||
example: 1649723812
|
|
||||||
minimum: 1
|
|
||||||
type: integer
|
|
||||||
statistics:
|
|
||||||
additionalProperties:
|
|
||||||
$ref: '#/definitions/schema.JobStatistics'
|
|
||||||
type: object
|
|
||||||
subCluster:
|
|
||||||
example: main
|
|
||||||
type: string
|
|
||||||
tags:
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/schema.Tag'
|
|
||||||
type: array
|
|
||||||
user:
|
|
||||||
example: abcd100h
|
|
||||||
type: string
|
|
||||||
walltime:
|
|
||||||
example: 86400
|
|
||||||
minimum: 1
|
|
||||||
type: integer
|
|
||||||
type: object
|
|
||||||
schema.JobMetric:
|
schema.JobMetric:
|
||||||
properties:
|
properties:
|
||||||
series:
|
series:
|
||||||
@ -599,6 +524,8 @@ definitions:
|
|||||||
type: number
|
type: number
|
||||||
remove:
|
remove:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
unit:
|
||||||
|
$ref: '#/definitions/schema.Unit'
|
||||||
type: object
|
type: object
|
||||||
schema.Tag:
|
schema.Tag:
|
||||||
description: Defines a tag using name and type.
|
description: Defines a tag using name and type.
|
||||||
@ -776,7 +703,7 @@ paths:
|
|||||||
get:
|
get:
|
||||||
description: |-
|
description: |-
|
||||||
Job to get is specified by database ID
|
Job to get is specified by database ID
|
||||||
Returns full job resource information according to 'JobMeta' scheme and all metrics according to 'JobData'.
|
Returns full job resource information according to 'Job' scheme and all metrics according to 'JobData'.
|
||||||
parameters:
|
parameters:
|
||||||
- description: Database ID of Job
|
- description: Database ID of Job
|
||||||
in: path
|
in: path
|
||||||
@ -829,7 +756,7 @@ paths:
|
|||||||
- application/json
|
- application/json
|
||||||
description: |-
|
description: |-
|
||||||
Job to get is specified by database ID
|
Job to get is specified by database ID
|
||||||
Returns full job resource information according to 'JobMeta' scheme and all metrics according to 'JobData'.
|
Returns full job resource information according to 'Job' scheme and all metrics according to 'JobData'.
|
||||||
parameters:
|
parameters:
|
||||||
- description: Database ID of Job
|
- description: Database ID of Job
|
||||||
in: path
|
in: path
|
||||||
@ -900,7 +827,7 @@ paths:
|
|||||||
"200":
|
"200":
|
||||||
description: Success message
|
description: Success message
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.DefaultJobApiResponse'
|
$ref: '#/definitions/api.DefaultApiResponse'
|
||||||
"400":
|
"400":
|
||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
@ -947,7 +874,7 @@ paths:
|
|||||||
"200":
|
"200":
|
||||||
description: Success message
|
description: Success message
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.DefaultJobApiResponse'
|
$ref: '#/definitions/api.DefaultApiResponse'
|
||||||
"400":
|
"400":
|
||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
@ -994,7 +921,7 @@ paths:
|
|||||||
"200":
|
"200":
|
||||||
description: Success message
|
description: Success message
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.DefaultJobApiResponse'
|
$ref: '#/definitions/api.DefaultApiResponse'
|
||||||
"400":
|
"400":
|
||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
@ -1078,21 +1005,21 @@ paths:
|
|||||||
- application/json
|
- application/json
|
||||||
description: |-
|
description: |-
|
||||||
Job specified in request body will be saved to database as "running" with new DB ID.
|
Job specified in request body will be saved to database as "running" with new DB ID.
|
||||||
Job specifications follow the 'JobMeta' scheme, API will fail to execute if requirements are not met.
|
Job specifications follow the 'Job' scheme, API will fail to execute if requirements are not met.
|
||||||
parameters:
|
parameters:
|
||||||
- description: Job to add
|
- description: Job to add
|
||||||
in: body
|
in: body
|
||||||
name: request
|
name: request
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/schema.JobMeta'
|
$ref: '#/definitions/schema.Job'
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
"201":
|
"201":
|
||||||
description: Job added successfully
|
description: Job added successfully
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/api.DefaultJobApiResponse'
|
$ref: '#/definitions/api.DefaultApiResponse'
|
||||||
"400":
|
"400":
|
||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
@ -1123,7 +1050,7 @@ paths:
|
|||||||
post:
|
post:
|
||||||
description: |-
|
description: |-
|
||||||
Job to stop is specified by request body. All fields are required in this case.
|
Job to stop is specified by request body. All fields are required in this case.
|
||||||
Returns full job resource information according to 'JobMeta' scheme.
|
Returns full job resource information according to 'Job' scheme.
|
||||||
parameters:
|
parameters:
|
||||||
- description: All fields required
|
- description: All fields required
|
||||||
in: body
|
in: body
|
||||||
@ -1137,7 +1064,7 @@ paths:
|
|||||||
"200":
|
"200":
|
||||||
description: Success message
|
description: Success message
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/schema.JobMeta'
|
$ref: '#/definitions/schema.Job'
|
||||||
"400":
|
"400":
|
||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
@ -1217,6 +1144,46 @@ paths:
|
|||||||
summary: Adds one or more tags to a job
|
summary: Adds one or more tags to a job
|
||||||
tags:
|
tags:
|
||||||
- Job add and modify
|
- Job add and modify
|
||||||
|
/api/nodestats/:
|
||||||
|
post:
|
||||||
|
description: |-
|
||||||
|
Returns a JSON-encoded list of users.
|
||||||
|
Required query-parameter defines if all users or only users with additional special roles are returned.
|
||||||
|
parameters:
|
||||||
|
- description: Request body containing nodes and their states
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.UpdateNodeStatesRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Success message
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.DefaultApiResponse'
|
||||||
|
"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'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.ErrorResponse'
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Deliver updated Slurm node states
|
||||||
|
tags:
|
||||||
|
- Nodestates
|
||||||
/api/users/:
|
/api/users/:
|
||||||
get:
|
get:
|
||||||
description: |-
|
description: |-
|
||||||
|
@ -208,7 +208,7 @@ const docTemplate = `{
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "Success message",
|
"description": "Success message",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.DefaultJobApiResponse"
|
"$ref": "#/definitions/api.DefaultApiResponse"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
@ -278,7 +278,7 @@ const docTemplate = `{
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "Success message",
|
"description": "Success message",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.DefaultJobApiResponse"
|
"$ref": "#/definitions/api.DefaultApiResponse"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
@ -348,7 +348,7 @@ const docTemplate = `{
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "Success message",
|
"description": "Success message",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.DefaultJobApiResponse"
|
"$ref": "#/definitions/api.DefaultApiResponse"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
@ -467,7 +467,7 @@ const docTemplate = `{
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Job specified in request body will be saved to database as \"running\" with new DB ID.\nJob specifications follow the 'JobMeta' scheme, API will fail to execute if requirements are not met.",
|
"description": "Job specified in request body will be saved to database as \"running\" with new DB ID.\nJob specifications follow the 'Job' scheme, API will fail to execute if requirements are not met.",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@ -485,7 +485,7 @@ const docTemplate = `{
|
|||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/schema.JobMeta"
|
"$ref": "#/definitions/schema.Job"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -493,7 +493,7 @@ const docTemplate = `{
|
|||||||
"201": {
|
"201": {
|
||||||
"description": "Job added successfully",
|
"description": "Job added successfully",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/api.DefaultJobApiResponse"
|
"$ref": "#/definitions/api.DefaultApiResponse"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
@ -536,7 +536,7 @@ const docTemplate = `{
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Job to stop is specified by request body. All fields are required in this case.\nReturns full job resource information according to 'JobMeta' scheme.",
|
"description": "Job to stop is specified by request body. All fields are required in this case.\nReturns full job resource information according to 'Job' scheme.",
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@ -559,7 +559,7 @@ const docTemplate = `{
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "Success message",
|
"description": "Success message",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/schema.JobMeta"
|
"$ref": "#/definitions/schema.Job"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
@ -681,7 +681,7 @@ const docTemplate = `{
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Job to get is specified by database ID\nReturns full job resource information according to 'JobMeta' scheme and all metrics according to 'JobData'.",
|
"description": "Job to get is specified by database ID\nReturns full job resource information according to 'Job' scheme and all metrics according to 'JobData'.",
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@ -755,7 +755,7 @@ const docTemplate = `{
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Job to get is specified by database ID\nReturns full job resource information according to 'JobMeta' scheme and all metrics according to 'JobData'.",
|
"description": "Job to get is specified by database ID\nReturns full job resource information according to 'Job' scheme and all metrics according to 'JobData'.",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@ -833,6 +833,66 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/nodestats/": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Returns a JSON-encoded list of users.\nRequired query-parameter defines if all users or only users with additional special roles are returned.",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Nodestates"
|
||||||
|
],
|
||||||
|
"summary": "Deliver updated Slurm node states",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Request body containing nodes and their states",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.UpdateNodeStatesRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success message",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.DefaultApiResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/users/": {
|
"/api/users/": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@ -1081,7 +1141,7 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"api.DefaultJobApiResponse": {
|
"api.DefaultApiResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"msg": {
|
"msg": {
|
||||||
@ -1175,7 +1235,7 @@ const docTemplate = `{
|
|||||||
"description": "Array of jobs",
|
"description": "Array of jobs",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/schema.JobMeta"
|
"$ref": "#/definitions/schema.Job"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"page": {
|
"page": {
|
||||||
@ -1198,6 +1258,20 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"api.Node": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"hostname": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"states": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"api.StopJobApiRequest": {
|
"api.StopJobApiRequest": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@ -1231,6 +1305,21 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"api.UpdateNodeStatesRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"cluster": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "fritz"
|
||||||
|
},
|
||||||
|
"nodes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/api.Node"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"schema.Accelerator": {
|
"schema.Accelerator": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -1266,7 +1355,6 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"schema.Job": {
|
"schema.Job": {
|
||||||
"description": "Information of a HPC job.",
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"arrayJobId": {
|
"arrayJobId": {
|
||||||
@ -1364,6 +1452,12 @@ const docTemplate = `{
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"example": "abcd200"
|
"example": "abcd200"
|
||||||
},
|
},
|
||||||
|
"requestedMemory": {
|
||||||
|
"description": "in MB",
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1,
|
||||||
|
"example": 128000
|
||||||
|
},
|
||||||
"resources": {
|
"resources": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
@ -1375,7 +1469,14 @@ const docTemplate = `{
|
|||||||
"example": 4
|
"example": 4
|
||||||
},
|
},
|
||||||
"startTime": {
|
"startTime": {
|
||||||
"type": "string"
|
"type": "integer",
|
||||||
|
"example": 1649723812
|
||||||
|
},
|
||||||
|
"statistics": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"$ref": "#/definitions/schema.JobStatistics"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"subCluster": {
|
"subCluster": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@ -1423,147 +1524,6 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"schema.JobMeta": {
|
|
||||||
"description": "Meta data information of a HPC job.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"arrayJobId": {
|
|
||||||
"type": "integer",
|
|
||||||
"example": 123000
|
|
||||||
},
|
|
||||||
"cluster": {
|
|
||||||
"type": "string",
|
|
||||||
"example": "fritz"
|
|
||||||
},
|
|
||||||
"concurrentJobs": {
|
|
||||||
"$ref": "#/definitions/schema.JobLinkResultList"
|
|
||||||
},
|
|
||||||
"duration": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"example": 43200
|
|
||||||
},
|
|
||||||
"energy": {
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"energyFootprint": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": {
|
|
||||||
"type": "number"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"exclusive": {
|
|
||||||
"type": "integer",
|
|
||||||
"maximum": 2,
|
|
||||||
"minimum": 0,
|
|
||||||
"example": 1
|
|
||||||
},
|
|
||||||
"footprint": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": {
|
|
||||||
"type": "number"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"id": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"jobId": {
|
|
||||||
"type": "integer",
|
|
||||||
"example": 123000
|
|
||||||
},
|
|
||||||
"jobState": {
|
|
||||||
"enum": [
|
|
||||||
"completed",
|
|
||||||
"failed",
|
|
||||||
"cancelled",
|
|
||||||
"stopped",
|
|
||||||
"timeout",
|
|
||||||
"out_of_memory"
|
|
||||||
],
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/definitions/schema.JobState"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"example": "completed"
|
|
||||||
},
|
|
||||||
"metaData": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"monitoringStatus": {
|
|
||||||
"type": "integer",
|
|
||||||
"maximum": 3,
|
|
||||||
"minimum": 0,
|
|
||||||
"example": 1
|
|
||||||
},
|
|
||||||
"numAcc": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"example": 2
|
|
||||||
},
|
|
||||||
"numHwthreads": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"example": 20
|
|
||||||
},
|
|
||||||
"numNodes": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"example": 2
|
|
||||||
},
|
|
||||||
"partition": {
|
|
||||||
"type": "string",
|
|
||||||
"example": "main"
|
|
||||||
},
|
|
||||||
"project": {
|
|
||||||
"type": "string",
|
|
||||||
"example": "abcd200"
|
|
||||||
},
|
|
||||||
"resources": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/definitions/schema.Resource"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"smt": {
|
|
||||||
"type": "integer",
|
|
||||||
"example": 4
|
|
||||||
},
|
|
||||||
"startTime": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"example": 1649723812
|
|
||||||
},
|
|
||||||
"statistics": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": {
|
|
||||||
"$ref": "#/definitions/schema.JobStatistics"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"subCluster": {
|
|
||||||
"type": "string",
|
|
||||||
"example": "main"
|
|
||||||
},
|
|
||||||
"tags": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/definitions/schema.Tag"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"user": {
|
|
||||||
"type": "string",
|
|
||||||
"example": "abcd100h"
|
|
||||||
},
|
|
||||||
"walltime": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"example": 86400
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"schema.JobMetric": {
|
"schema.JobMetric": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -1891,6 +1851,9 @@ const docTemplate = `{
|
|||||||
},
|
},
|
||||||
"remove": {
|
"remove": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"unit": {
|
||||||
|
"$ref": "#/definitions/schema.Unit"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -28,11 +28,6 @@ import (
|
|||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultApiResponse model
|
|
||||||
type DefaultJobApiResponse struct {
|
|
||||||
Message string `json:"msg"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// StopJobApiRequest model
|
// StopJobApiRequest model
|
||||||
type StopJobApiRequest struct {
|
type StopJobApiRequest struct {
|
||||||
JobId *int64 `json:"jobId" example:"123000"`
|
JobId *int64 `json:"jobId" example:"123000"`
|
||||||
@ -224,7 +219,7 @@ func (api *RestApi) getJobs(rw http.ResponseWriter, r *http.Request) {
|
|||||||
// @summary Get job meta and optional all metric data
|
// @summary Get job meta and optional all metric data
|
||||||
// @tags Job query
|
// @tags Job query
|
||||||
// @description Job to get is specified by database ID
|
// @description Job to get is specified by database ID
|
||||||
// @description Returns full job resource information according to 'JobMeta' scheme and all metrics according to 'JobData'.
|
// @description Returns full job resource information according to 'Job' scheme and all metrics according to 'JobData'.
|
||||||
// @produce json
|
// @produce json
|
||||||
// @param id path int true "Database ID of Job"
|
// @param id path int true "Database ID of Job"
|
||||||
// @param all-metrics query bool false "Include all available metrics"
|
// @param all-metrics query bool false "Include all available metrics"
|
||||||
@ -316,7 +311,7 @@ func (api *RestApi) getCompleteJobById(rw http.ResponseWriter, r *http.Request)
|
|||||||
// @summary Get job meta and configurable metric data
|
// @summary Get job meta and configurable metric data
|
||||||
// @tags Job query
|
// @tags Job query
|
||||||
// @description Job to get is specified by database ID
|
// @description Job to get is specified by database ID
|
||||||
// @description Returns full job resource information according to 'JobMeta' scheme and all metrics according to 'JobData'.
|
// @description Returns full job resource information according to 'Job' scheme and all metrics according to 'JobData'.
|
||||||
// @accept json
|
// @accept json
|
||||||
// @produce json
|
// @produce json
|
||||||
// @param id path int true "Database ID of Job"
|
// @param id path int true "Database ID of Job"
|
||||||
@ -637,11 +632,11 @@ func (api *RestApi) removeTags(rw http.ResponseWriter, r *http.Request) {
|
|||||||
// @summary Adds a new job as "running"
|
// @summary Adds a new job as "running"
|
||||||
// @tags Job add and modify
|
// @tags Job add and modify
|
||||||
// @description Job specified in request body will be saved to database as "running" with new DB ID.
|
// @description Job specified in request body will be saved to database as "running" with new DB ID.
|
||||||
// @description Job specifications follow the 'JobMeta' scheme, API will fail to execute if requirements are not met.
|
// @description Job specifications follow the 'Job' scheme, API will fail to execute if requirements are not met.
|
||||||
// @accept json
|
// @accept json
|
||||||
// @produce json
|
// @produce json
|
||||||
// @param request body schema.JobMeta true "Job to add"
|
// @param request body schema.Job true "Job to add"
|
||||||
// @success 201 {object} api.DefaultJobApiResponse "Job added successfully"
|
// @success 201 {object} api.DefaultApiResponse "Job added successfully"
|
||||||
// @failure 400 {object} api.ErrorResponse "Bad Request"
|
// @failure 400 {object} api.ErrorResponse "Bad Request"
|
||||||
// @failure 401 {object} api.ErrorResponse "Unauthorized"
|
// @failure 401 {object} api.ErrorResponse "Unauthorized"
|
||||||
// @failure 403 {object} api.ErrorResponse "Forbidden"
|
// @failure 403 {object} api.ErrorResponse "Forbidden"
|
||||||
@ -705,7 +700,7 @@ func (api *RestApi) startJob(rw http.ResponseWriter, r *http.Request) {
|
|||||||
log.Printf("new job (id: %d): cluster=%s, jobId=%d, user=%s, startTime=%d", id, req.Cluster, req.JobID, req.User, req.StartTime)
|
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(DefaultJobApiResponse{
|
json.NewEncoder(rw).Encode(DefaultApiResponse{
|
||||||
Message: "success",
|
Message: "success",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -714,10 +709,10 @@ func (api *RestApi) startJob(rw http.ResponseWriter, r *http.Request) {
|
|||||||
// @summary Marks job as completed and triggers archiving
|
// @summary Marks job as completed and triggers archiving
|
||||||
// @tags Job add and modify
|
// @tags Job add and modify
|
||||||
// @description Job to stop is specified by request body. All fields are required in this case.
|
// @description Job to stop is specified by request body. All fields are required in this case.
|
||||||
// @description Returns full job resource information according to 'JobMeta' scheme.
|
// @description Returns full job resource information according to 'Job' scheme.
|
||||||
// @produce json
|
// @produce json
|
||||||
// @param request body api.StopJobApiRequest true "All fields required"
|
// @param request body api.StopJobApiRequest true "All fields required"
|
||||||
// @success 200 {object} schema.JobMeta "Success message"
|
// @success 200 {object} schema.Job "Success message"
|
||||||
// @failure 400 {object} api.ErrorResponse "Bad Request"
|
// @failure 400 {object} api.ErrorResponse "Bad Request"
|
||||||
// @failure 401 {object} api.ErrorResponse "Unauthorized"
|
// @failure 401 {object} api.ErrorResponse "Unauthorized"
|
||||||
// @failure 403 {object} api.ErrorResponse "Forbidden"
|
// @failure 403 {object} api.ErrorResponse "Forbidden"
|
||||||
@ -762,7 +757,7 @@ func (api *RestApi) stopJobByRequest(rw http.ResponseWriter, r *http.Request) {
|
|||||||
// @description Job to remove is specified by database ID. This will not remove the job from the job archive.
|
// @description Job to remove is specified by database ID. This will not remove the job from the job archive.
|
||||||
// @produce json
|
// @produce json
|
||||||
// @param id path int true "Database ID of Job"
|
// @param id path int true "Database ID of Job"
|
||||||
// @success 200 {object} api.DefaultJobApiResponse "Success message"
|
// @success 200 {object} api.DefaultApiResponse "Success message"
|
||||||
// @failure 400 {object} api.ErrorResponse "Bad Request"
|
// @failure 400 {object} api.ErrorResponse "Bad Request"
|
||||||
// @failure 401 {object} api.ErrorResponse "Unauthorized"
|
// @failure 401 {object} api.ErrorResponse "Unauthorized"
|
||||||
// @failure 403 {object} api.ErrorResponse "Forbidden"
|
// @failure 403 {object} api.ErrorResponse "Forbidden"
|
||||||
@ -793,7 +788,7 @@ func (api *RestApi) deleteJobById(rw http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
rw.Header().Add("Content-Type", "application/json")
|
rw.Header().Add("Content-Type", "application/json")
|
||||||
rw.WriteHeader(http.StatusOK)
|
rw.WriteHeader(http.StatusOK)
|
||||||
json.NewEncoder(rw).Encode(DefaultJobApiResponse{
|
json.NewEncoder(rw).Encode(DefaultApiResponse{
|
||||||
Message: fmt.Sprintf("Successfully deleted job %s", id),
|
Message: fmt.Sprintf("Successfully deleted job %s", id),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -805,7 +800,7 @@ func (api *RestApi) deleteJobById(rw http.ResponseWriter, r *http.Request) {
|
|||||||
// @accept json
|
// @accept json
|
||||||
// @produce json
|
// @produce json
|
||||||
// @param request body api.DeleteJobApiRequest true "All fields required"
|
// @param request body api.DeleteJobApiRequest true "All fields required"
|
||||||
// @success 200 {object} api.DefaultJobApiResponse "Success message"
|
// @success 200 {object} api.DefaultApiResponse "Success message"
|
||||||
// @failure 400 {object} api.ErrorResponse "Bad Request"
|
// @failure 400 {object} api.ErrorResponse "Bad Request"
|
||||||
// @failure 401 {object} api.ErrorResponse "Unauthorized"
|
// @failure 401 {object} api.ErrorResponse "Unauthorized"
|
||||||
// @failure 403 {object} api.ErrorResponse "Forbidden"
|
// @failure 403 {object} api.ErrorResponse "Forbidden"
|
||||||
@ -844,7 +839,7 @@ func (api *RestApi) deleteJobByRequest(rw http.ResponseWriter, r *http.Request)
|
|||||||
|
|
||||||
rw.Header().Add("Content-Type", "application/json")
|
rw.Header().Add("Content-Type", "application/json")
|
||||||
rw.WriteHeader(http.StatusOK)
|
rw.WriteHeader(http.StatusOK)
|
||||||
json.NewEncoder(rw).Encode(DefaultJobApiResponse{
|
json.NewEncoder(rw).Encode(DefaultApiResponse{
|
||||||
Message: fmt.Sprintf("Successfully deleted job %d", job.ID),
|
Message: fmt.Sprintf("Successfully deleted job %d", job.ID),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -855,7 +850,7 @@ func (api *RestApi) deleteJobByRequest(rw http.ResponseWriter, r *http.Request)
|
|||||||
// @description Remove all jobs with start time before timestamp. The jobs will not be removed from the job archive.
|
// @description Remove all jobs with start time before timestamp. The jobs will not be removed from the job archive.
|
||||||
// @produce json
|
// @produce json
|
||||||
// @param ts path int true "Unix epoch timestamp"
|
// @param ts path int true "Unix epoch timestamp"
|
||||||
// @success 200 {object} api.DefaultJobApiResponse "Success message"
|
// @success 200 {object} api.DefaultApiResponse "Success message"
|
||||||
// @failure 400 {object} api.ErrorResponse "Bad Request"
|
// @failure 400 {object} api.ErrorResponse "Bad Request"
|
||||||
// @failure 401 {object} api.ErrorResponse "Unauthorized"
|
// @failure 401 {object} api.ErrorResponse "Unauthorized"
|
||||||
// @failure 403 {object} api.ErrorResponse "Forbidden"
|
// @failure 403 {object} api.ErrorResponse "Forbidden"
|
||||||
@ -888,7 +883,7 @@ func (api *RestApi) deleteJobBefore(rw http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
rw.Header().Add("Content-Type", "application/json")
|
rw.Header().Add("Content-Type", "application/json")
|
||||||
rw.WriteHeader(http.StatusOK)
|
rw.WriteHeader(http.StatusOK)
|
||||||
json.NewEncoder(rw).Encode(DefaultJobApiResponse{
|
json.NewEncoder(rw).Encode(DefaultApiResponse{
|
||||||
Message: fmt.Sprintf("Successfully deleted %d jobs", cnt),
|
Message: fmt.Sprintf("Successfully deleted %d jobs", cnt),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -927,7 +922,7 @@ func (api *RestApi) checkAndHandleStopJob(rw http.ResponseWriter, job *schema.Jo
|
|||||||
|
|
||||||
log.Printf("archiving job... (dbid: %d): cluster=%s, jobId=%d, user=%s, startTime=%d, duration=%d, state=%s", job.ID, job.Cluster, job.JobID, job.User, job.StartTime, job.Duration, job.State)
|
log.Printf("archiving job... (dbid: %d): cluster=%s, jobId=%d, user=%s, startTime=%d, duration=%d, state=%s", job.ID, job.Cluster, job.JobID, job.User, job.StartTime, job.Duration, job.State)
|
||||||
|
|
||||||
// Send a response (with status OK). This means that erros that happen from here on forward
|
// Send a response (with status OK). This means that errors that happen from here on forward
|
||||||
// can *NOT* be communicated to the client. If reading from a MetricDataRepository or
|
// can *NOT* be communicated to the client. If reading from a MetricDataRepository or
|
||||||
// writing to the filesystem fails, the client will not know.
|
// writing to the filesystem fails, the client will not know.
|
||||||
rw.Header().Add("Content-Type", "application/json")
|
rw.Header().Add("Content-Type", "application/json")
|
||||||
|
@ -24,7 +24,7 @@ type UpdateNodeStatesRequest struct {
|
|||||||
Cluster string `json:"cluster" example:"fritz"`
|
Cluster string `json:"cluster" example:"fritz"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// this routine assumes that only one of them applies per node
|
// this routine assumes that only one of them exists per node
|
||||||
func determineState(states []string) schema.NodeState {
|
func determineState(states []string) schema.NodeState {
|
||||||
for _, state := range states {
|
for _, state := range states {
|
||||||
switch strings.ToLower(state) {
|
switch strings.ToLower(state) {
|
||||||
@ -46,16 +46,16 @@ func determineState(states []string) schema.NodeState {
|
|||||||
|
|
||||||
// updateNodeStates godoc
|
// updateNodeStates godoc
|
||||||
// @summary Deliver updated Slurm node states
|
// @summary Deliver updated Slurm node states
|
||||||
// @tags node
|
// @tags Nodestates
|
||||||
// @description Returns a JSON-encoded list of users.
|
// @description Returns a JSON-encoded list of users.
|
||||||
// @description Required query-parameter defines if all users or only users with additional special roles are returned.
|
// @description Required query-parameter defines if all users or only users with additional special roles are returned.
|
||||||
// @produce json
|
// @produce json
|
||||||
// @param request body UpdateNodeStatesRequest true "Request body containing nodes and their states"
|
// @param request body UpdateNodeStatesRequest true "Request body containing nodes and their states"
|
||||||
// @success 200 {array} api.SuccessResponse "Success"
|
// @success 200 {object} api.DefaultApiResponse "Success message"
|
||||||
// @failure 400 {string} string "Bad Request"
|
// @failure 400 {object} api.ErrorResponse "Bad Request"
|
||||||
// @failure 401 {string} string "Unauthorized"
|
// @failure 401 {object} api.ErrorResponse "Unauthorized"
|
||||||
// @failure 403 {string} string "Forbidden"
|
// @failure 403 {object} api.ErrorResponse "Forbidden"
|
||||||
// @failure 500 {string} string "Internal Server Error"
|
// @failure 500 {object} api.ErrorResponse "Internal Server Error"
|
||||||
// @security ApiKeyAuth
|
// @security ApiKeyAuth
|
||||||
// @router /api/nodestats/ [post]
|
// @router /api/nodestats/ [post]
|
||||||
func (api *RestApi) updateNodeStates(rw http.ResponseWriter, r *http.Request) {
|
func (api *RestApi) updateNodeStates(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -124,6 +124,11 @@ type ErrorResponse struct {
|
|||||||
Error string `json:"error"` // Error Message
|
Error string `json:"error"` // Error Message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DefaultApiResponse model
|
||||||
|
type DefaultApiResponse struct {
|
||||||
|
Message string `json:"msg"`
|
||||||
|
}
|
||||||
|
|
||||||
func handleError(err error, statusCode int, rw http.ResponseWriter) {
|
func handleError(err error, statusCode int, rw http.ResponseWriter) {
|
||||||
log.Warnf("REST ERROR : %s", err.Error())
|
log.Warnf("REST ERROR : %s", err.Error())
|
||||||
rw.Header().Add("Content-Type", "application/json")
|
rw.Header().Add("Content-Type", "application/json")
|
||||||
|
@ -361,12 +361,21 @@ func (r *queryResolver) AllocatedNodes(ctx context.Context, cluster string) ([]*
|
|||||||
|
|
||||||
// Node is the resolver for the node field.
|
// Node is the resolver for the node field.
|
||||||
func (r *queryResolver) Node(ctx context.Context, id string) (*schema.Node, error) {
|
func (r *queryResolver) Node(ctx context.Context, id string) (*schema.Node, error) {
|
||||||
panic(fmt.Errorf("not implemented: Node - node"))
|
repo := repository.GetNodeRepository()
|
||||||
|
numericId, err := strconv.ParseInt(id, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("Error while parsing job id")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return repo.GetNode(numericId, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nodes is the resolver for the nodes field.
|
// Nodes is the resolver for the nodes field.
|
||||||
func (r *queryResolver) Nodes(ctx context.Context, filter []*model.NodeFilter, order *model.OrderByInput) (*model.NodeStateResultList, error) {
|
func (r *queryResolver) Nodes(ctx context.Context, filter []*model.NodeFilter, order *model.OrderByInput) (*model.NodeStateResultList, error) {
|
||||||
panic(fmt.Errorf("not implemented: Nodes - nodes"))
|
repo := repository.GetNodeRepository()
|
||||||
|
nodes, err := repo.QueryNodes(ctx, filter, order)
|
||||||
|
count := len(nodes)
|
||||||
|
return &model.NodeStateResultList{Items: nodes, Count: &count}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeStats is the resolver for the nodeStats field.
|
// NodeStats is the resolver for the nodeStats field.
|
||||||
@ -815,10 +824,12 @@ func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
|
|||||||
// SubCluster returns generated.SubClusterResolver implementation.
|
// SubCluster returns generated.SubClusterResolver implementation.
|
||||||
func (r *Resolver) SubCluster() generated.SubClusterResolver { return &subClusterResolver{r} }
|
func (r *Resolver) SubCluster() generated.SubClusterResolver { return &subClusterResolver{r} }
|
||||||
|
|
||||||
type clusterResolver struct{ *Resolver }
|
type (
|
||||||
type jobResolver struct{ *Resolver }
|
clusterResolver struct{ *Resolver }
|
||||||
type metricValueResolver struct{ *Resolver }
|
jobResolver struct{ *Resolver }
|
||||||
type mutationResolver struct{ *Resolver }
|
metricValueResolver struct{ *Resolver }
|
||||||
type nodeResolver struct{ *Resolver }
|
mutationResolver struct{ *Resolver }
|
||||||
type queryResolver struct{ *Resolver }
|
nodeResolver struct{ *Resolver }
|
||||||
type subClusterResolver struct{ *Resolver }
|
queryResolver struct{ *Resolver }
|
||||||
|
subClusterResolver struct{ *Resolver }
|
||||||
|
)
|
||||||
|
@ -15,13 +15,13 @@ import (
|
|||||||
type Hooks struct{}
|
type Hooks struct{}
|
||||||
|
|
||||||
// Before hook will print the query with it's args and return the context with the timestamp
|
// Before hook will print the query with it's args and return the context with the timestamp
|
||||||
func (h *Hooks) Before(ctx context.Context, query string, args ...interface{}) (context.Context, error) {
|
func (h *Hooks) Before(ctx context.Context, query string, args ...any) (context.Context, error) {
|
||||||
log.Debugf("SQL query %s %q", query, args)
|
log.Debugf("SQL query %s %q", query, args)
|
||||||
return context.WithValue(ctx, "begin", time.Now()), nil
|
return context.WithValue(ctx, "begin", time.Now()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// After hook will get the timestamp registered on the Before hook and print the elapsed time
|
// After hook will get the timestamp registered on the Before hook and print the elapsed time
|
||||||
func (h *Hooks) After(ctx context.Context, query string, args ...interface{}) (context.Context, error) {
|
func (h *Hooks) After(ctx context.Context, query string, args ...any) (context.Context, error) {
|
||||||
begin := ctx.Value("begin").(time.Time)
|
begin := ctx.Value("begin").(time.Time)
|
||||||
log.Debugf("Took: %s\n", time.Since(begin))
|
log.Debugf("Took: %s\n", time.Since(begin))
|
||||||
return ctx, nil
|
return ctx, nil
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package repository
|
package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -12,6 +13,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ClusterCockpit/cc-backend/internal/graph/model"
|
||||||
"github.com/ClusterCockpit/cc-backend/pkg/archive"
|
"github.com/ClusterCockpit/cc-backend/pkg/archive"
|
||||||
"github.com/ClusterCockpit/cc-backend/pkg/log"
|
"github.com/ClusterCockpit/cc-backend/pkg/log"
|
||||||
"github.com/ClusterCockpit/cc-backend/pkg/lrucache"
|
"github.com/ClusterCockpit/cc-backend/pkg/lrucache"
|
||||||
@ -177,6 +179,7 @@ func (r *NodeRepository) UpdateNodeState(hostname string, cluster string, nodeSt
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Infof("Added node '%s' to database", hostname)
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
log.Warnf("Error while querying node '%v' from database", id)
|
log.Warnf("Error while querying node '%v' from database", id)
|
||||||
@ -188,7 +191,7 @@ func (r *NodeRepository) UpdateNodeState(hostname string, cluster string, nodeSt
|
|||||||
log.Errorf("error while updating node '%s'", hostname)
|
log.Errorf("error while updating node '%s'", hostname)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
log.Infof("Updated node '%s' in database", hostname)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,8 +214,53 @@ func (r *NodeRepository) DeleteNode(id int64) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *NodeRepository) QueryNodes() ([]*schema.Node, error) {
|
// TODO: Implement order by
|
||||||
return nil, nil
|
func (r *NodeRepository) QueryNodes(
|
||||||
|
ctx context.Context,
|
||||||
|
filters []*model.NodeFilter,
|
||||||
|
order *model.OrderByInput,
|
||||||
|
) ([]*schema.Node, error) {
|
||||||
|
query, qerr := SecurityCheck(ctx, sq.Select(jobColumns...).From("node"))
|
||||||
|
if qerr != nil {
|
||||||
|
return nil, qerr
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range filters {
|
||||||
|
if f.Hostname != nil {
|
||||||
|
query = buildStringCondition("node.hostname", f.Hostname, query)
|
||||||
|
}
|
||||||
|
if f.Cluster != nil {
|
||||||
|
query = buildStringCondition("node.cluster", f.Cluster, query)
|
||||||
|
}
|
||||||
|
if f.NodeState != nil {
|
||||||
|
query = query.Where("node.node_state = ?", f.NodeState)
|
||||||
|
}
|
||||||
|
if f.HealthState != nil {
|
||||||
|
query = query.Where("node.health_state = ?", f.HealthState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := query.RunWith(r.stmtCache).Query()
|
||||||
|
if err != nil {
|
||||||
|
queryString, queryVars, _ := query.ToSql()
|
||||||
|
log.Errorf("Error while running query '%s' %v: %v", queryString, queryVars, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes := make([]*schema.Node, 0, 50)
|
||||||
|
for rows.Next() {
|
||||||
|
node := schema.Node{}
|
||||||
|
|
||||||
|
if err := rows.Scan(&node.Hostname, &node.Cluster, &node.SubCluster,
|
||||||
|
&node.NodeState, &node.HealthState); err != nil {
|
||||||
|
rows.Close()
|
||||||
|
log.Warn("Error while scanning rows (Nodes)")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
nodes = append(nodes, &node)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *NodeRepository) ListNodes(cluster string) ([]*schema.Node, error) {
|
func (r *NodeRepository) ListNodes(cluster string) ([]*schema.Node, error) {
|
||||||
|
@ -686,7 +686,7 @@ func (r *JobRepository) jobsMetricStatisticsHistogram(
|
|||||||
|
|
||||||
mainQuery := sq.Select(
|
mainQuery := sq.Select(
|
||||||
fmt.Sprintf(`%s + 1 as bin`, binQuery),
|
fmt.Sprintf(`%s + 1 as bin`, binQuery),
|
||||||
fmt.Sprintf(`count(*) as count`),
|
`count(*) as count`,
|
||||||
// For Debug: // fmt.Sprintf(`CAST((%f / %d) as INTEGER ) * %s as min`, peak, *bins, binQuery),
|
// For Debug: // fmt.Sprintf(`CAST((%f / %d) as INTEGER ) * %s as min`, peak, *bins, binQuery),
|
||||||
// For Debug: // fmt.Sprintf(`CAST((%f / %d) as INTEGER ) * (%s + 1) as max`, peak, *bins, binQuery),
|
// For Debug: // fmt.Sprintf(`CAST((%f / %d) as INTEGER ) * (%s + 1) as max`, peak, *bins, binQuery),
|
||||||
).From("job").Where(
|
).From("job").Where(
|
||||||
|
1
internal/tagger/apps/alf.txt
Normal file
1
internal/tagger/apps/alf.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
alf
|
7
internal/tagger/apps/caracal.txt
Normal file
7
internal/tagger/apps/caracal.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
calc_rate
|
||||||
|
qmdffgen
|
||||||
|
dynamic
|
||||||
|
evbopt
|
||||||
|
explore
|
||||||
|
black_box
|
||||||
|
poly_qmdff
|
3
internal/tagger/apps/chroma.txt
Normal file
3
internal/tagger/apps/chroma.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
chroma
|
||||||
|
qdp
|
||||||
|
qmp
|
1
internal/tagger/apps/cp2k.txt
Normal file
1
internal/tagger/apps/cp2k.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
cp2k
|
1
internal/tagger/apps/cpmd.txt
Normal file
1
internal/tagger/apps/cpmd.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
cpmd
|
1
internal/tagger/apps/flame.txt
Normal file
1
internal/tagger/apps/flame.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
flame
|
@ -1,4 +1,3 @@
|
|||||||
GROMACS
|
|
||||||
gromacs
|
gromacs
|
||||||
GMX
|
gmx
|
||||||
mdrun
|
mdrun
|
||||||
|
1
internal/tagger/apps/lammps.txt
Normal file
1
internal/tagger/apps/lammps.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
lmp
|
1
internal/tagger/apps/orca.txt
Normal file
1
internal/tagger/apps/orca.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
orca
|
@ -1,3 +1,4 @@
|
|||||||
python
|
python
|
||||||
|
pip
|
||||||
anaconda
|
anaconda
|
||||||
conda
|
conda
|
||||||
|
3
internal/tagger/apps/qe.txt
Normal file
3
internal/tagger/apps/qe.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pw
|
||||||
|
neb
|
||||||
|
ph
|
10
internal/tagger/apps/turbomole.txt
Normal file
10
internal/tagger/apps/turbomole.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
dscf
|
||||||
|
grad
|
||||||
|
ridft
|
||||||
|
rdgrad
|
||||||
|
ricc2
|
||||||
|
statpt
|
||||||
|
aoforce
|
||||||
|
escf
|
||||||
|
egrad
|
||||||
|
odft
|
@ -1,2 +1 @@
|
|||||||
VASP
|
|
||||||
vasp
|
vasp
|
||||||
|
@ -111,7 +111,7 @@ func (t *AppTagger) Match(job *schema.Job) {
|
|||||||
for _, a := range t.apps {
|
for _, a := range t.apps {
|
||||||
tag := a.tag
|
tag := a.tag
|
||||||
for _, s := range a.strings {
|
for _, s := range a.strings {
|
||||||
if strings.Contains(jobscript, s) {
|
if strings.Contains(strings.ToLower(jobscript), s) {
|
||||||
if !r.HasTag(id, t.tagType, tag) {
|
if !r.HasTag(id, t.tagType, tag) {
|
||||||
r.AddTagOrCreateDirect(id, t.tagType, tag)
|
r.AddTagOrCreateDirect(id, t.tagType, tag)
|
||||||
break out
|
break out
|
||||||
|
@ -35,8 +35,8 @@ func TestRegister(t *testing.T) {
|
|||||||
err := tagger.Register()
|
err := tagger.Register()
|
||||||
noErr(t, err)
|
noErr(t, err)
|
||||||
|
|
||||||
if len(tagger.apps) != 4 {
|
if len(tagger.apps) != 14 {
|
||||||
t.Errorf("wrong summary for diagnostic \ngot: %d \nwant: 3", len(tagger.apps))
|
t.Errorf("wrong summary for diagnostic \ngot: %d \nwant: 14", len(tagger.apps))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,10 +12,11 @@ import (
|
|||||||
|
|
||||||
// Job struct type
|
// Job struct type
|
||||||
//
|
//
|
||||||
// This type is used as the GraphQL interface and using sqlx as a table row.
|
// This type contains all metadata of a HPC job.
|
||||||
//
|
//
|
||||||
// Job model
|
// Job model
|
||||||
// @Description Information of a HPC job.
|
// @Description Information of a HPC job.
|
||||||
|
|
||||||
type Job struct {
|
type Job struct {
|
||||||
Cluster string `json:"cluster" db:"cluster" example:"fritz"`
|
Cluster string `json:"cluster" db:"cluster" example:"fritz"`
|
||||||
SubCluster string `json:"subCluster" db:"subcluster" example:"main"`
|
SubCluster string `json:"subCluster" db:"subcluster" example:"main"`
|
||||||
@ -50,25 +51,6 @@ type Job struct {
|
|||||||
StartTime int64 `json:"startTime" db:"start_time" example:"1649723812"`
|
StartTime int64 `json:"startTime" db:"start_time" example:"1649723812"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// JobMeta struct type
|
|
||||||
//
|
|
||||||
// When reading from the database or sending data via GraphQL, the start time
|
|
||||||
// can be in the much more convenient time.Time type. In the `meta.json`
|
|
||||||
// files, the start time is encoded as a unix epoch timestamp. This is why
|
|
||||||
// there is this struct, which contains all fields from the regular job
|
|
||||||
// struct, but "overwrites" the StartTime field with one of type int64. ID
|
|
||||||
// *int64 `json:"id,omitempty"` >> never used in the job-archive, only
|
|
||||||
// available via REST-API
|
|
||||||
//
|
|
||||||
// JobMeta model
|
|
||||||
// @Description Meta data information of a HPC job.
|
|
||||||
// type JobMeta struct {
|
|
||||||
// ID *int64 `json:"id,omitempty"`
|
|
||||||
// BaseJob
|
|
||||||
// Statistics map[string]JobStatistics `json:"statistics"`
|
|
||||||
// StartTime int64 `json:"startTime" db:"start_time" example:"1649723812" minimum:"1"`
|
|
||||||
// }
|
|
||||||
|
|
||||||
type JobLink struct {
|
type JobLink struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
JobID int64 `json:"jobId"`
|
JobID int64 `json:"jobId"`
|
||||||
|
@ -35,9 +35,6 @@ func TestValidateConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidateJobMeta(t *testing.T) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestValidateCluster(t *testing.T) {
|
func TestValidateCluster(t *testing.T) {
|
||||||
json := []byte(`{
|
json := []byte(`{
|
||||||
"name": "emmy",
|
"name": "emmy",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user