Files
polyphem/api/swagger.yaml
2024-08-12 10:02:36 +02:00

689 lines
24 KiB
YAML

openapi: 3.0.0
info:
title: Poseidon API
description: |
This API is used by CodeOcean to run code in runners.
version: '0.2.2'
servers:
- url: '/api/v1'
components:
schemas:
ExecutionEnvironment:
type: object
properties:
id:
description: The id of the execution environment
type: integer
example: 6
image:
description: The name of the OCI image used for this execution environment
type: string
example: openhpi/co_execenv_python:latest
prewarmingPoolSize:
description: Number of runners with this configuration to prewarm
type: integer
example: 50
cpuLimit:
description: CPU limit for one runner in MHz
type: number
example: 100
memoryLimit:
description: Memory limit for one runner in MB. Exceeding the limit may result in termination of the runner.
type: integer
example: 256
networkAccess:
description: Whether the runner is allowed to access the network or not
type: boolean
example: true
exposedPorts:
description: A list of ports inside the runner to expose to the outside
type: array
items:
type: integer
minimum: 1
maximum: 65535
example: [80, 443]
required:
- id
- image
- prewarmingPoolSize
- cpuLimit
- memoryLimit
- networkAccess
- exposedPorts
additionalProperties: false
FileHeader:
type: object
properties:
name:
description: The path of the file.
type: string
example: ./logs/last.log
entryType:
description: The type of the object (file). See the man page `info ls` for all the meanings.
type: string
minLength: 1
maxLength: 1
enum: ["-", "a", "A", "b", "c", "C", "d", "D", "l", "M", "n", "p", "P", "s", "w", "?"]
default: "-"
size:
description: The size of the file in bytes.
type: integer
example: 42
modificationTime:
description: The Unix Time Stamp of the last modification.
type: integer
example: 1654201799
required:
- name
- size
- modificationTime
additionalProperties: false
ClientError:
type: object
properties:
message:
description: Explanation on why the request could not be handled
type: string
example: Nomad server unreachable
required:
- message
additionalProperties: false
securitySchemes:
poseidonAuthToken:
type: apiKey
in: header
name: Poseidon-Token
description: A security token that might be required depending on the Poseidon configuration.
responses:
BadRequest:
description: Request is invalid. E.g. request body does not follow the json schema required by the given route or url parameters are invalid.
content:
application/json:
schema:
type: object
properties:
message:
description: Explanation on why the request is invalid
type: string
Unauthorized:
description: Client could not be authenticated
NotFound:
description: The entity with the given identifier does not exist.
RunnerGone:
description: The runner is not available any longer.
content:
application/json:
schema:
$ref: "#/components/schemas/ClientError"
FailedFileDependency:
description: The file is not available.
content:
application/json:
schema:
$ref: "#/components/schemas/ClientError"
InternalServerError:
description: Request could not be handled
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/ClientError"
- type: object
properties:
errorCode:
description: Machine readable error description
type: string
enum:
- NOMAD_UNREACHABLE
- NOMAD_OVERLOAD
- NOMAD_INTERNAL_SERVER_ERROR
- PREWARMING_POOL_DEPLETING
- UNKNOWN
example: NOMAD_UNREACHABLE
tags:
- name: runner
description: A unit of execution
- name: execution environment
description: A template for runners
- name: miscellaneous
paths:
/health:
get:
summary: Check if the API is available
description: If this route does not return, the API is not available.
tags:
- miscellaneous
responses:
"204":
description: Everything okay
"503":
$ref: "#/components/responses/InternalServerError"
/version:
get:
summary: Retrieve the version of Poseidon
description: Return hash-like release information.
tags:
- miscellaneous
responses:
"200":
description: The release information could be returned.
"404":
$ref: "#/components/responses/NotFound"
"500":
$ref: "#/components/responses/InternalServerError"
/statistics/execution-environments:
get:
summary: Retrieve the statistics about the execution environments of Poseidon
description: Return Return the current availability and usage of runners.
tags:
- miscellaneous
security:
- poseidonAuthToken: [ ]
responses:
"200":
description: Success. Returns all execution environments
content:
application/json:
schema:
type: object
additionalProperties:
type: object
properties:
id:
description: The id of the execution environment.
type: integer
prewarmingPoolSize:
description: Number of runners with this configuration to prewarm.
type: integer
example: 50
idleRunners:
description: Number of runners currently prewarmed.
type: number
example: 45
usedRunners:
description: Number of runners currently in use.
type: number
example: 20
example:
21:
id: 21
prewarmingPoolSize: 50
idleRunners: 45
usedRunners: 20
42:
id: 42
prewarmingPoolSize: 50
idleRunners: 45
usedRunners: 20
"500":
$ref: "#/components/responses/InternalServerError"
/runners:
post:
summary: Provide a runner
description: Provide a runner with the requested execution environment to the client (CodeOcean).
tags:
- runner
security:
- poseidonAuthToken: [ ]
requestBody:
description: Runner attributes
required: true
content:
application/json:
schema:
type: object
properties:
inactivityTimeout:
description: Specify how long the runner should be available when there is no activity (execution or file copy). Activity resets this timer. 0 means no timeout
type: integer
default: 0
example: 60
executionEnvironmentId:
description: Specifies the execution environment of the runner
type: integer
example: 6
required:
- executionEnvironmentId
additionalProperties: false
responses:
"200":
description: A runner was successfully reserved
content:
application/json:
schema:
type: object
properties:
runnerId:
description: The UUID of the provided runner
type: string
example: 123e4567-e89b-12d3-a456-426614174000
mappedPorts:
description: Array containing the addresses of the mapped ports specified in the execution environment.
type: array
items:
description: The exposedPort inside the container is reachable on the returned hostAddress.
type: object
properties:
exposedPort:
description: The port inside the container.
type: integer
minimum: 0
maximum: 65535
example: 80
hostAddress:
description: The address which can be contacted to reach the mapped port.
type: string
example: 10.224.6.18:23832
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
"500":
$ref: "#/components/responses/InternalServerError"
/runners/{runnerId}:
delete:
summary: Destroy the runner
description: The runner is no longer in use and should be destroyed.
tags:
- runner
security:
- poseidonAuthToken: [ ]
parameters:
- name: runnerId
in: path
schema:
description: The UUID of the runner that should be destroyed
type: string
example: 123e4567-e89b-12d3-a456-426614174000
required: true
responses:
"204":
description: Success
"401":
$ref: "#/components/responses/Unauthorized"
"410":
$ref: "#/components/responses/RunnerGone"
"500":
$ref: "#/components/responses/InternalServerError"
/runners/{runnerId}/files:
parameters:
- name: runnerId
in: path
schema:
description: Runner on which the files should be placed
type: string
example: 123e4567-e89b-12d3-a456-426614174000
required: true
get:
summary: List filesystem.
description: List all files available in the runner.
tags:
- runner
security:
- poseidonAuthToken: [ ]
parameters:
- name: recursive
in: query
description: Specify if the filesystem should be listed recursively.
schema:
type: boolean
default: true
required: false
- name: path
in: query
description: Specify the directory from where the filesystem is listed.
schema:
type: string
format: pct-encoded # rfc 3986
default: "./"
required: false
- name: privilegedExecution
in: query
description: Specifies if the command should be executed as an privileged user.
schema:
type: boolean
default: false
responses:
"200":
description: Success. Returns the listing of the runner's filesystem.
content:
application/json:
schema:
type: object
properties:
files:
description: A list of all Files
type: array
items:
$ref: "#/components/schemas/FileHeader"
"401":
$ref: "#/components/responses/Unauthorized"
"410":
$ref: "#/components/responses/RunnerGone"
"424":
$ref: "#/components/responses/FailedFileDependency"
"500":
$ref: "#/components/responses/InternalServerError"
patch:
summary: Manipulate runner file system
description: Delete the files with the given paths from the file system of the specified runner. Afterwards, copy the enclosed files to the runner. Existing files get overwritten and results of previous file copy operations on the same runner are present when executing multiple requests.
tags:
- runner
security:
- poseidonAuthToken: [ ]
requestBody:
description: Files to copy or delete
required: true
content:
application/json:
schema:
type: object
properties:
delete:
description: Array of filepaths that should be deleted. Each of the given files or directories should be deleted recursively.
type: array
items:
description: Location of the file or directory that should be deleted. Can be absolute (starting with /) or relative to the workspace directory.
type: string
example: /workspace
copy:
description: Array of files that should be placed in the runner.
type: array
items:
type: object
properties:
path:
description: Location where the file should be placed. Can be absolute (starting with /) or relative to the workspace directory. Missing parent directories are created. If this ends with a /, the path is interpreted as a directory and content is ignored. Currently, every file/directory is owned by root but the directories have the sticky bit set to allow unprivileged file creation.
type: string
example: /etc/passwd
content:
description: The content of the file. MUST be base64 encoded. If this is not given, the file is created with no content.
type: string
example: cm9vdDp4OjA6MDo6L3Jvb3Q6L2Jpbi9iYXNo # root:x:0:0::/root:/bin/bash
required:
- path
additionalProperties: false
additionalProperties: false
responses:
"204":
description: All files were saved
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"410":
$ref: "#/components/responses/RunnerGone"
"500":
$ref: "#/components/responses/InternalServerError"
/runners/{runnerId}/files/raw:
get:
summary: Download the file.
description: Download the specified file from the selected runner.
tags:
- runner
security:
- poseidonAuthToken: [ ]
parameters:
- name: runnerId
description: Runner on which the command should be executed
in: path
schema:
type: string
example: 123e4567-e89b-12d3-a456-426614174000
required: true
- name: path
in: query
description: Specify the file that should be returned by its filename including its path and extension.
schema:
type: string
format: pct-encoded # rfc 3986
example: "./flag.txt"
required: true
- name: privilegedExecution
in: query
description: Specifies if the command should be executed as an privileged user.
schema:
type: boolean
default: false
responses:
"200":
description: Success. Returns the file.
content:
application/octet-stream:
schema:
type: string
format: binary
"401":
$ref: "#/components/responses/Unauthorized"
"410":
$ref: "#/components/responses/RunnerGone"
"424":
$ref: "#/components/responses/FailedFileDependency"
/runners/{runnerId}/execute:
post:
summary: Execute a command
description: Execute a command in the runner. Whether this starts the actual execution or only prepares a Websocket URL to start it depends on the implementation.
tags:
- runner
security:
- poseidonAuthToken: [ ]
parameters:
- name: runnerId
description: Runner on which the command should be executed
in: path
schema:
type: string
example: 123e4567-e89b-12d3-a456-426614174000
required: true
requestBody:
description: Description what and how to execute
required: true
content:
application/json:
schema:
type: object
properties:
command:
description: The command to be executed. The working directory for this execution is the working directory of the image of the execution environment. Single quotation ' can not be used.
type: string
example: python exercise.py
privilegedExecution:
description: Specifies if the command should be executed as an privileged user.
type: boolean
default: false
environment:
description: Environment variables for this execution. The keys of this object are the variable names and the value of each key is the value of the variable with the same name. The environment variables of the system remain accessible.
type: object
additionalProperties:
type: string
pattern: "[a-zA-Z_][a-zA-Z0-9_]+"
default: {}
example:
PATH: /bin
timeLimit:
description: Specifies the time in seconds until this execution should be killed. 0 means do not kill
type: integer
default: 0
example: 5
required:
- command
additionalProperties: false
responses:
"200":
description: Success. Returns a Websocket URL to connect to
content:
application/json:
schema:
type: object
properties:
websocketUrl:
description: A Websocket endpoint to connect to communicate with the process running in the runner
type: string
example: "ws://ws.example.com/path/to/websocket"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"410":
$ref: "#/components/responses/RunnerGone"
"500":
$ref: "#/components/responses/InternalServerError"
/runners/{runnerId}/websocket:
get:
summary: Connect to an execution.
description: The url including all parameters will be generated and returned by the `execute` route. This is a WebSocket endpoint. The schema for the WS communication is described in `websocket.schema.json`.
tags:
- runner
security:
- poseidonAuthToken: [ ]
parameters:
- name: runnerId
description: Runner on which the execution is created.
in: path
schema:
type: string
example: 123e4567-e89b-12d3-a456-426614174000
required: true
- name: executionID
description: The execution of the runner that you want to connect to.
in: query
schema:
type: string
example: 123e4567-e89b-12d3-a456-426614174000
required: true
responses:
"101":
description: Success. Switching protocols to WebSocket.
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
"410":
$ref: "#/components/responses/RunnerGone"
"500":
$ref: "#/components/responses/InternalServerError"
/execution-environments:
get:
summary: List execution environments
description: List all execution environments the API is aware of.
tags:
- execution environment
security:
- poseidonAuthToken: [ ]
parameters:
- name: fetch
in: query
description: Specify whether environments should be fetched again from the executor before returning. Otherwise, the data currently in cache is returned.
schema:
type: boolean
default: false
required: false
responses:
"200":
description: Success. Returns all execution environments
content:
application/json:
schema:
type: object
properties:
executionEnvironments:
description: A list of all execution environments
type: array
items:
$ref: "#/components/schemas/ExecutionEnvironment"
"401":
$ref: "#/components/responses/Unauthorized"
/execution-environments/{executionEnvironmentId}:
parameters:
- name: executionEnvironmentId
in: path
description: Id of the execution environment
required: true
schema:
type: integer
get:
summary: Show an execution environment
description: Get a representation of the execution environment specified by the id.
tags:
- execution environment
security:
- poseidonAuthToken: [ ]
parameters:
- name: fetch
in: query
description: Specify whether the environment should be fetched again from the executor before returning. Otherwise, the data currently in cache is returned.
schema:
type: boolean
default: false
required: false
responses:
"200":
description: Success. Returns the execution environment
content:
application/json:
schema:
$ref: "#/components/schemas/ExecutionEnvironment"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
put:
summary: Create or replace the execution environment
description: This is used for keeping execution environments in sync between the client and the provider of this API. By sending a request with an id, the execution environment is created if it does not exist and updated otherwise.
tags:
- execution environment
security:
- poseidonAuthToken: [ ]
requestBody:
description: The new execution environment
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ExecutionEnvironment"
responses:
"201":
description: The executions environment did not exist and was created
"204":
description: The execution environment was replaced
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
delete:
summary: Delete the execution environment
description: Remove the specified execution environment from the API.
tags:
- execution environment
security:
- poseidonAuthToken: [ ]
responses:
"204":
description: The execution environment was deleted.
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"