From 639739947ece9e99509dc9c30dc38243e0a2a59e Mon Sep 17 00:00:00 2001 From: Mathieu Moalic Date: Mon, 4 Mar 2024 12:45:14 +0100 Subject: [PATCH] Add output to api --- frontend/src/api/Api.ts | 166 ++++++----------------- frontend/src/api/Table.ts | 14 ++ frontend/src/lib/Drawer/Output.svelte | 7 +- frontend/src/lib/Table/TableTitle.svelte | 2 +- manager/manager/run_job.py | 2 +- manager/manager/views.py | 3 +- manager/schema.yml | 114 +++++++++------- 7 files changed, 133 insertions(+), 175 deletions(-) diff --git a/frontend/src/api/Api.ts b/frontend/src/api/Api.ts index 629b5ab..0c900de 100644 --- a/frontend/src/api/Api.ts +++ b/frontend/src/api/Api.ts @@ -22,34 +22,17 @@ export enum ConnectionStatusEnum { * * `SLOW` - SLOW * * `NORMAL` - NORMAL * * `FAST` - FAST + * * `UNDEF` - UNDEF */ export enum GpuPartitionEnum { SLOW = 'SLOW', NORMAL = 'NORMAL', - FAST = 'FAST' + FAST = 'FAST', + UNDEF = 'UNDEF' } export interface Gpus { readonly id: number; - /** - * The speed of the GPU. - * - * * `SLOW` - SLOW - * * `NORMAL` - NORMAL - * * `FAST` - FAST - * @default "NORMAL" - */ - speed?: SpeedEnum; - /** - * The current status of the GPU. - * - * * `WAITING` - WAITING - * * `PENDING` - PENDING - * * `RESERVED` - RESERVED - * * `UNAVALIBLE` - UNAVALIBLE - * @default "WAITING" - */ - status?: GpusStatusEnum; /** The associated node ID. */ node: number; /** @@ -65,6 +48,12 @@ export interface Gpus { */ uuid: string; model: string; + /** + * * `SLOW` - SLOW + * * `NORMAL` - NORMAL + * * `FAST` - FAST + */ + speed?: SpeedEnum; /** * The utilization of the GPU (must be <= 100). * @format int64 @@ -73,6 +62,13 @@ export interface Gpus { */ util: number; is_running_amumax?: boolean; + /** + * * `RUNNING` - RUNNING + * * `PENDING` - PENDING + * * `RESERVED` - RESERVED + * * `UNAVAILABLE` - UNAVAILABLE + */ + status?: GpusStatusEnum; /** * The timestamp of the last update (read-only, auto-generated). * @format date-time @@ -81,16 +77,16 @@ export interface Gpus { } /** - * * `WAITING` - WAITING + * * `RUNNING` - RUNNING * * `PENDING` - PENDING * * `RESERVED` - RESERVED - * * `UNAVALIBLE` - UNAVALIBLE + * * `UNAVAILABLE` - UNAVAILABLE */ export enum GpusStatusEnum { - WAITING = 'WAITING', + RUNNING = 'RUNNING', PENDING = 'PENDING', RESERVED = 'RESERVED', - UNAVALIBLE = 'UNAVALIBLE' + UNAVAILABLE = 'UNAVAILABLE' } export interface Job { @@ -121,6 +117,7 @@ export interface Job { * * `SLOW` - SLOW * * `NORMAL` - NORMAL * * `FAST` - FAST + * * `UNDEF` - UNDEF */ gpu_partition?: GpuPartitionEnum; /** @@ -130,14 +127,11 @@ export interface Job { */ duration?: number; /** - * * `WAITING` - WAITING * * `PENDING` - PENDING * * `FINISHED` - FINISHED * * `INTERRUPTED` - INTERRUPTED */ status?: JobStatusEnum; - output?: string | null; - error?: string | null; /** @maxLength 150 */ flags?: string | null; /** @maxLength 150 */ @@ -147,19 +141,17 @@ export interface Job { } /** - * * `WAITING` - WAITING * * `PENDING` - PENDING * * `FINISHED` - FINISHED * * `INTERRUPTED` - INTERRUPTED */ export enum JobStatusEnum { - WAITING = 'WAITING', PENDING = 'PENDING', FINISHED = 'FINISHED', INTERRUPTED = 'INTERRUPTED' } -export interface MS { +export interface ManagerSettings { readonly id: number; queue_watchdog?: boolean; } @@ -176,7 +168,6 @@ export interface Nodes { */ number_of_gpus: number; /** - * * `WAITING` - WAITING * * `PENDING` - PENDING * * `RESERVED` - RESERVED * * `UNAVAILABLE` - UNAVAILABLE @@ -192,13 +183,11 @@ export interface Nodes { } /** - * * `WAITING` - WAITING * * `PENDING` - PENDING * * `RESERVED` - RESERVED * * `UNAVAILABLE` - UNAVAILABLE */ export enum NodesStatusEnum { - WAITING = 'WAITING', PENDING = 'PENDING', RESERVED = 'RESERVED', UNAVAILABLE = 'UNAVAILABLE' @@ -232,6 +221,7 @@ export interface PatchedJob { * * `SLOW` - SLOW * * `NORMAL` - NORMAL * * `FAST` - FAST + * * `UNDEF` - UNDEF */ gpu_partition?: GpuPartitionEnum; /** @@ -241,14 +231,11 @@ export interface PatchedJob { */ duration?: number; /** - * * `WAITING` - WAITING * * `PENDING` - PENDING * * `FINISHED` - FINISHED * * `INTERRUPTED` - INTERRUPTED */ status?: JobStatusEnum; - output?: string | null; - error?: string | null; /** @maxLength 150 */ flags?: string | null; /** @maxLength 150 */ @@ -257,7 +244,7 @@ export interface PatchedJob { gpu?: number | null; } -export interface PatchedMS { +export interface PatchedManagerSettings { readonly id?: number; queue_watchdog?: boolean; } @@ -300,6 +287,10 @@ export interface TokenRefresh { refresh: string; } +export interface Output { + output: string; +} + export type QueryParamsType = Record; export type ResponseFormat = keyof Omit; @@ -708,32 +699,13 @@ export class Api extends HttpClient - this.request({ - path: `/api/jobs/${id}/start/`, - method: 'POST', - body: data, - secure: true, - type: ContentType.Json, - format: 'json', - ...params - }), - - /** - * No description - * - * @tags manager-settings - * @name ManagerSettingsList - * @request GET:/api/manager-settings/ + * @name JobsOutputRetrieve + * @request GET:/api/jobs/{id}/output/ * @secure */ - managerSettingsList: (params: RequestParams = {}) => - this.request({ - path: `/api/manager-settings/`, + jobsOutputRetrieve: (id: number, params: RequestParams = {}) => + this.request({ + path: `/api/jobs/${id}/output/`, method: 'GET', secure: true, format: 'json', @@ -743,14 +715,14 @@ export class Api extends HttpClient - this.request({ - path: `/api/manager-settings/`, + jobsStartCreate: (id: number, data: Job, params: RequestParams = {}) => + this.request({ + path: `/api/jobs/${id}/start/`, method: 'POST', body: data, secure: true, @@ -759,42 +731,6 @@ export class Api extends HttpClient - this.request({ - path: `/api/manager-settings/${id}/`, - method: 'GET', - secure: true, - format: 'json', - ...params - }), - - /** - * No description - * - * @tags manager-settings - * @name ManagerSettingsUpdate - * @request PUT:/api/manager-settings/{id}/ - * @secure - */ - managerSettingsUpdate: (id: number, data: MS, params: RequestParams = {}) => - this.request({ - path: `/api/manager-settings/${id}/`, - method: 'PUT', - body: data, - secure: true, - type: ContentType.Json, - format: 'json', - ...params - }), - /** * No description * @@ -803,8 +739,12 @@ export class Api extends HttpClient - this.request({ + managerSettingsPartialUpdate: ( + id: number, + data: PatchedManagerSettings, + params: RequestParams = {} + ) => + this.request({ path: `/api/manager-settings/${id}/`, method: 'PATCH', body: data, @@ -814,22 +754,6 @@ export class Api extends HttpClient - this.request({ - path: `/api/manager-settings/${id}/`, - method: 'DELETE', - secure: true, - ...params - }), - /** * No description * diff --git a/frontend/src/api/Table.ts b/frontend/src/api/Table.ts index bbceaae..a8291ba 100644 --- a/frontend/src/api/Table.ts +++ b/frontend/src/api/Table.ts @@ -55,6 +55,20 @@ export function sortItems(item_type: 'jobs' | 'nodes' | 'gpus'): void { }); } +export function getJobOutput(job: Job): Promise { + return new Promise((resolve, reject) => { + api.jobsOutputRetrieve(job.id, getRequestParams()).then( + (response) => { + resolve(response.data.output); + } + ).catch(err => { + console.error(err); + reject(err); + }); + }); +} + + export async function runJob(job: Job) { api.jobsStartCreate(job.id, job, getRequestParams()).then(() => { newToast(`Started job ${job.id}`, "green"); diff --git a/frontend/src/lib/Drawer/Output.svelte b/frontend/src/lib/Drawer/Output.svelte index 0343448..d7c32e1 100644 --- a/frontend/src/lib/Drawer/Output.svelte +++ b/frontend/src/lib/Drawer/Output.svelte @@ -1,13 +1,14 @@ diff --git a/frontend/src/lib/Table/TableTitle.svelte b/frontend/src/lib/Table/TableTitle.svelte index 6a70a2f..ff6d5be 100644 --- a/frontend/src/lib/Table/TableTitle.svelte +++ b/frontend/src/lib/Table/TableTitle.svelte @@ -16,7 +16,7 @@ { - fetchItems('jobs'); + fetchItems(item_type); }} class="ml-3 text-gray-500" /> diff --git a/manager/manager/run_job.py b/manager/manager/run_job.py index 1b62297..aef4a79 100644 --- a/manager/manager/run_job.py +++ b/manager/manager/run_job.py @@ -14,7 +14,7 @@ def __init__(self) -> None: def find_gpu(self, partition): gpu = Gpu.objects.filter( - status="WAITING", + status="PENDING", # speed=partition #TEMPORARY DISABLED ).first() if gpu is None: diff --git a/manager/manager/views.py b/manager/manager/views.py index 9126d2a..1addd80 100644 --- a/manager/manager/views.py +++ b/manager/manager/views.py @@ -94,7 +94,8 @@ def start(self, _request, pk=None): def output(self, *_args, **_kwargs): try: job = self.get_object() - return Response({"output": job.output}, status=status.HTTP_200_OK) + output = job.output if job.output else "" + return Response({"output": output}, status=status.HTTP_200_OK) except Job.DoesNotExist: return Response( {"error": "Job not found."}, status=status.HTTP_404_NOT_FOUND diff --git a/manager/schema.yml b/manager/schema.yml index 2e59b80..34f05ac 100644 --- a/manager/schema.yml +++ b/manager/schema.yml @@ -97,6 +97,7 @@ paths: security: - basicAuth: [] - jwtAuth: [] + - {} responses: '200': content: @@ -125,6 +126,7 @@ paths: security: - basicAuth: [] - jwtAuth: [] + - {} responses: '201': content: @@ -147,6 +149,7 @@ paths: security: - basicAuth: [] - jwtAuth: [] + - {} responses: '200': content: @@ -180,6 +183,7 @@ paths: security: - basicAuth: [] - jwtAuth: [] + - {} responses: '200': content: @@ -212,6 +216,7 @@ paths: security: - basicAuth: [] - jwtAuth: [] + - {} responses: '200': content: @@ -233,9 +238,33 @@ paths: security: - basicAuth: [] - jwtAuth: [] + - {} responses: '204': description: No response body + /api/jobs/{id}/output/: + get: + operationId: jobs_output_retrieve + parameters: + - in: path + name: id + schema: + type: integer + description: A unique integer value identifying this job. + required: true + tags: + - jobs + security: + - basicAuth: [] + - jwtAuth: [] + - {} + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/output' + description: '' /api/jobs/{id}/start/: post: operationId: jobs_start_create @@ -263,6 +292,7 @@ paths: security: - basicAuth: [] - jwtAuth: [] + - {} responses: '200': content: @@ -626,38 +656,19 @@ components: - SLOW - NORMAL - FAST + - UNDEF type: string description: |- * `SLOW` - SLOW * `NORMAL` - NORMAL * `FAST` - FAST + * `UNDEF` - UNDEF Gpus: type: object properties: id: type: integer readOnly: true - speed: - allOf: - - $ref: '#/components/schemas/SpeedEnum' - default: NORMAL - description: |- - The speed of the GPU. - - * `SLOW` - SLOW - * `NORMAL` - NORMAL - * `FAST` - FAST - status: - allOf: - - $ref: '#/components/schemas/StatusCcdEnum' - default: WAITING - description: |- - The current status of the GPU. - - * `WAITING` - WAITING - * `PENDING` - PENDING - * `RESERVED` - RESERVED - * `UNAVAILABLE` - UNAVAILABLE node: type: integer description: The associated node ID. @@ -673,6 +684,8 @@ components: description: The unique identifier of the GPU. model: type: string + speed: + $ref: '#/components/schemas/SpeedEnum' util: type: integer maximum: 100 @@ -681,6 +694,8 @@ components: description: The utilization of the GPU (must be <= 100). is_running_amumax: type: boolean + status: + $ref: '#/components/schemas/GpusStatusEnum' last_update: type: string format: date-time @@ -694,6 +709,18 @@ components: - node - util - uuid + GpusStatusEnum: + enum: + - RUNNING + - PENDING + - RESERVED + - UNAVAILABLE + type: string + description: |- + * `RUNNING` - RUNNING + * `PENDING` - PENDING + * `RESERVED` - RESERVED + * `UNAVAILABLE` - UNAVAILABLE Job: type: object properties: @@ -736,12 +763,6 @@ components: format: int64 status: $ref: '#/components/schemas/JobStatusEnum' - output: - type: string - nullable: true - error: - type: string - nullable: true flags: type: string nullable: true @@ -761,13 +782,11 @@ components: - user JobStatusEnum: enum: - - WAITING - PENDING - FINISHED - INTERRUPTED type: string description: |- - * `WAITING` - WAITING * `PENDING` - PENDING * `FINISHED` - FINISHED * `INTERRUPTED` - INTERRUPTED @@ -798,7 +817,7 @@ components: minimum: 0 format: int64 status: - $ref: '#/components/schemas/StatusCcdEnum' + $ref: '#/components/schemas/NodesStatusEnum' connection_status: $ref: '#/components/schemas/ConnectionStatusEnum' last_seen: @@ -809,6 +828,16 @@ components: - ip - name - number_of_gpus + NodesStatusEnum: + enum: + - PENDING + - RESERVED + - UNAVAILABLE + type: string + description: |- + * `PENDING` - PENDING + * `RESERVED` - RESERVED + * `UNAVAILABLE` - UNAVAILABLE PatchedJob: type: object properties: @@ -851,12 +880,6 @@ components: format: int64 status: $ref: '#/components/schemas/JobStatusEnum' - output: - type: string - nullable: true - error: - type: string - nullable: true flags: type: string nullable: true @@ -903,18 +926,6 @@ components: * `SLOW` - SLOW * `NORMAL` - NORMAL * `FAST` - FAST - StatusCcdEnum: - enum: - - WAITING - - PENDING - - RESERVED - - UNAVAILABLE - type: string - description: |- - * `WAITING` - WAITING - * `PENDING` - PENDING - * `RESERVED` - RESERVED - * `UNAVAILABLE` - UNAVAILABLE TokenObtainPair: type: object properties: @@ -947,6 +958,13 @@ components: required: - access - refresh + output: + type: object + properties: + output: + type: string + required: + - output securitySchemes: basicAuth: type: http