689 lines
24 KiB
YAML
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"
|