openapi: 3.0.0
info:
  title: Contree API
  description: |
    Contree is a container management system combining virtual machine isolation with container operational efficiency. 
    Designed for security-sensitive workloads requiring hardware-enforced boundaries while maintaining
    container workflow compatibility.
  version: 1.0.0

servers:
  - url: '/v1'

tags:
  - name: images
    description: Operations related to container images
  - name: files
    description: Operations related to file uploads
  - name: instances
    description: Operations related to container instances
  - name: inspect
    description: Operations related to inspecting container images
  - name: operations
    description: Operations related to long-running operations

paths:
  /images:
    get:
      summary: List publicly available images
      description: |
        Returns a list of all publicly available container images.
      operationId: listImages
      tags:
        - images
      parameters:
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
          description: |
            Maximum number of images to return. Must be between 1 and 1000.
            Default is 100. Invalid values raise 400 error.
        - name: offset
          in: query
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
          description: |
            Number of images to skip before starting to collect the result set.
            Default is 0. Invalid values raise 400 error.
        - name: tagged
          in: query
          required: false
          schema:
            type: string
            description: |
              If not `0` only images with tags will be listed. May be avoided or set to `0` to list all images.
              If no value is provided (like `?tagged`, it is considered as `1`.
          example: "1"
        - name: tag
          in: query
          required: false
          schema:
            type: string
          description: |
              A valid image tag prefix to filter images by this prefix. Only images with tags starting with. Implies `tagged` parameter.
          example: "ubuntu"
        - name: uuid
          in: query
          required: false
          schema:
            $ref: '#/components/schemas/UUIDSchema'
          description: Filter images by UUID
        - $ref: '#/components/parameters/SinceParameter'
        - $ref: '#/components/parameters/UntilParameter'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImageListResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'

  /images/{imageUUID}/tag:
    delete:
      summary: Remove the image tag
      description: |
        Removes the tag from aт image.

        If the any public image has the same tag, tag will start tracking that public image again.
  
        In all other cases tag will be set to null and the image will be accessible only by its UUID.
      operationId: deleteImageTag
      tags:
          - images
      parameters:
        - name: imageUUID
          in: path
          required: true
          description: The UUID of the image to untag
          schema:
              $ref: '#/components/schemas/UUIDSchema'
      responses:
          '200':
            description: OK
            content:
              application/json:
                schema:
                  $ref: '#/components/schemas/Image'
          '400':
            $ref: '#/components/responses/BadRequest'
          '401':
            $ref: '#/components/responses/Unauthorized'
          '403':
            $ref: '#/components/responses/Forbidden'
          '404':
            $ref: '#/components/responses/NotFound'
    patch:
      summary: Set the image tag
      description: |
        Sets or update an image's tag. Tags are unique; if the requested tag is already
        assigned to another image, it will be moved to this image.

        Assigning a tag that matches a public tag to a public image will freeze that tag
        to the current image — subsequent public updates to the tag will not affect it.
        To make the public tag track the latest public image again, remove your tag assignment.
        
        When a tag is removed from an image that resides in the public namespace, the API returns HTTP 200 OK.
        response body contains the tag that now points to the public image
        (i.e., the image that the tag is automatically re‑assigned to).

        In other words, un‑tagging a public image does not delete the tag; it simply moves the tag back to the public
        image and the caller receives that tag in the successful response.
      operationId: updateImageTag
      tags:
        - images
      parameters:
        - name: imageUUID
          in: path
          required: true
          description: The UUID of the image to update
          schema:
            $ref: '#/components/schemas/UUIDSchema'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - tag
              properties:
                tag:
                  type: string
                  description: New tag for the image
                  example: busybox:latest
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Image'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'

  /images/import:
    post:
      summary: Import a container image from a registry
      description: |
        Imports the OCI image filesystem content of from a specified registry.

        Important limitations and behavior:
        
        - Only the image root filesystem (files and directories) is imported. This is like to the output of
          `docker export` and does not preserve layers metadata.
        - Most image configuration and manifest data are ignored. Metadata such as `LABEL`,
          `ENTRYPOINT`, `CMD`, `WORKDIR`, `EXPOSE` and other image configuration directives
          will **NOT be imported or applied**.
        - `ENV` variables defined in the image **are imported** and automatically applied to the
          instance environment when `shell` is set to `true`. When `shell` is `false`, image
          environment variables are not inherited and must be passed explicitly via the `env` field.
        - The result is a flat rootfs snapshot with preserved environment variables.
        - If the specified tag already exists in the public images, the imported image will replace it.
          To avoid this, you can tag the existing image with a different tag for use it later.
          You also can use image UUIDs it is not changing for imported and existend image.
        - In case the remote image is unchanged and already imported, the operation will complete and the same UUID
          will be returned without re-importing the image.

        The request creates an import operation which runs asynchronously.
      operationId: importImage
      tags:
        - images
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ImageImportRequest'
      responses:
        '201':
          description: Created - The request has been accepted for processing
          headers:
            Location:
              schema:
                type: string
              description: URL to check the operation status
              example: /v1/operations/12345678-9abc-baba-deda-0123456789ab
          content:
            application/json:
              schema:
                type: object
                required:
                  - uuid
                properties:
                  uuid:
                    $ref: '#/components/schemas/UUIDSchema'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'

  /files:
    post:
      summary: Upload a file to the server. the body must be a file content.
      description: Uploads a file to the server. The body must contain the file content.
      operationId: uploadFile
      tags:
        - files
      requestBody:
        required: true
        content:
          application/octet-stream:
            schema:
              type: string
              format: binary
      responses:
        '201':
          description: Created - The file has been successfully uploaded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FileResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
    head:
      summary: Check if a file exists by its SHA256 hash
      description: Checks if a file with the specified SHA256 hash exists on the server
      operationId: checkFileExists
      tags:
        - files
      parameters:
        - name: sha256
          in: query
          required: true
          description: The SHA256 hash of the file to check
          schema:
            type: string
            format: sha256
      responses:
        '200':
          description: OK - The file exists
        '400':
          $ref: '#/components/responses/BadRequest'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: Not Found - The file does not exist
    get:
      summary: Get file uuid by sha256 hash
      description: Returns the UUID of a file by its SHA256 hash
      tags:
        - files
      parameters:
        - name: sha256
          in: query
          required: true
          schema:
            type: string
            format: sha256
          description: The SHA256 hash of the file to check
      responses:
        '200':
          description: OK - The file with the specified SHA256 hash exists
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FileResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'

  /instances:
    post:
      summary: Spawn a new container instance
      description: |
        Creates and runs a new execution instance with the specified configuration. 
        Requires a valid `Authorization` header.
        
        Common request body rules:

          * The request body must contain at least `command` and `image` fields all other fields can be omitted.
          * If the `command` field is a shell expression, you must set `shell` field to `true`.
          * For specifying the shell binary, you can use `env` field to set `SHELL` variable.
          * When `shell` is `true`, environment variables defined in the image (via `ENV` directives) are
            automatically inherited. When `shell` is `false`, image environment variables are not inherited
            and must be passed explicitly via the `env` field.
      operationId: spawnInstance
      tags:
        - instances
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InstanceSpawnRequest'
      responses:
        '201':
          description: >
            Created - The instance has been successfully created and its execution has been queued.
            When operation created successfully, the response will contain `Location` header with URL to check the operation status.
            and the body will contain the parsed request body with additional `uuid` field.
          headers:
            Location:
              schema:
                type: string
              description: URL to check the operation status
              example: /v1/operations/12345678-9abc-baba-deda-0123456789ab
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InstanceSpawnResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'

  /operations:
    get:
      summary: List operations
      description: Returns a list of running and completed operations
      operationId: listOperations
      tags:
        - operations
      parameters:
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
          description: |
            Maximum number of operations to return. Must be between 1 and 1000.
            Default is 100. Invalid values raise 400 error.
        - name: offset
          in: query
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
          description: |
            Number of operations to skip before starting to collect the result set.
            Default is 0. Invalid values raise 400 error.
        - name: status
          in: query
          required: false
          schema:
            type: string
            enum: [ PENDING, EXECUTING, SUCCESS, FAILED, CANCELLED, ASSIGNED ]
          description: Filter operations by their state
        - name: kind
          in: query
          required: false
          schema:
            type: string
            enum: [ image_import, instance ]
          description: Filter operations by their kind
        - $ref: '#/components/parameters/SinceParameter'
        - $ref: '#/components/parameters/UntilParameter'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/OperationSummary'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'

  /operations/{operationId}:
    get:
      summary: Get an operation status
      description: Returns the status of an operation
      operationId: getOperationStatus
      tags:
        - operations
      parameters:
        - name: operationId
          in: path
          required: true
          description: The ID of the operation
          schema:
            $ref: '#/components/schemas/UUIDSchema'
      responses:
        '200':
          description: OK
          headers:
            Retry-After:
              schema:
                type: integer
              description: Recommended time in seconds to wait before the next status check
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperationResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'

    delete:
      summary: Cancel an operation
      description: Cancels an operation
      operationId: cancelOperation
      tags:
        - operations
      parameters:
        - name: operationId
          in: path
          required: true
          description: The ID of the import operation to cancel
          schema:
            $ref: '#/components/schemas/UUIDSchema'
      responses:
        '202':
          description: Accepted - The cancellation request has been accepted
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'

  /inspect:
    get:
      summary: Redirect to /inspect/
      description: Redirects to /inspect/ with a trailing slash
      operationId: inspectRedirect
      tags:
        - inspect
      responses:
        '307':
          description: Temporary Redirect
          headers:
            Location:
              schema:
                type: string
              description: Redirect target with trailing slash
              example: /v1/inspect/

  /inspect/{imageUUID}:
    get:
      summary: Redirect to /inspect/{imageUUID}/
      description: Redirects to /inspect/{imageUUID}/ with a trailing slash
      operationId: inspectImageRedirect
      tags:
        - inspect
      parameters:
        - name: imageUUID
          in: path
          required: true
          description: The UUID of the image
          schema:
            $ref: '#/components/schemas/UUIDSchema'
      responses:
        '307':
          description: Temporary Redirect
          headers:
            Location:
              schema:
                type: string
              description: Redirect target with trailing slash
              example: /v1/inspect/12345678-9abc-baba-deda-0123456789ab/

  /inspect/:
    get:
      summary: Find image by tag
      description: Redirects to the image inspection endpoint for the specified tag
      operationId: inspectFindImageByTag
      tags:
        - inspect
      parameters:
        - name: tag
          in: query
          required: true
          description: The tag of the image to inspect
          schema:
              type: string
      responses:
        '302':
          description: Found - Redirecting to the image inspection endpoint
          headers:
            Location:
              schema:
                type: string
              description: URL of the image inspection endpoint
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'

  /inspect/{image_uuid}/:
    get:
      summary: Inspect an image
      description: Returns image metadata
      operationId: inspectImage
      tags:
        - inspect
      parameters:
      - name: image_uuid
        in: path
        required: true
        description: The UUID of the image to inspect
        schema:
          $ref: '#/components/schemas/UUIDSchema'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Image'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'

  /inspect/{image_uuid}/download:
    get:
      summary: Download a file from image
      description: Returns file content
      operationId: inspectImageDownload
      tags:
        - inspect
      parameters:
        - name: image_uuid
          in: path
          required: true
          description: The UUID of the image to inspect
          schema:
            $ref: '#/components/schemas/UUIDSchema'
        - name: path
          in: query
          required: true
          allowReserved: true
          schema:
            type: string
          description: The path of the file to inspect inside the image, e.g. `/etc/hosts`
        - name: text
          in: query
          required: false
          allowEmptyValue: true
          schema:
            type: boolean
          description: If present (with or without value), returns text/plain format instead of JSON
          example: ""
      responses:
        '200':
          description: OK
          content:
            application/octet-stream:
              schema:
                type: string
                format: binary
            text/plain:
              schema:
                type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: Not Found - The file does not exist in the image or image does not exist
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: Unprocessable Entity - The specified path is not a file inside the image
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    head:
      summary: Check if a file exists in image
      description: Checks if a file exists in the specified image without returning the file content
      operationId: checkImageFile
      tags:
        - inspect
      parameters:
        - name: image_uuid
          in: path
          required: true
          schema:
            type: string
            format: uuid
            example: "12345678-9abc-baba-deda-0123456789ab"
          description: The UUID of the image to inspect
        - name: path
          in: query
          required: true
          allowReserved: true
          schema:
            type: string
          description: The path of the file to check inside the image, e.g. `/etc/hosts`
      responses:
        '200':
          description: OK - The file exists in the image
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          description: Unauthorized - Invalid or missing JWT token
        '403':
          description: Forbidden - Token does not have sufficient permissions
        '404':
          description: Not Found - The file does not exist in the image or image does not exist
        '422':
          description: Unprocessable Entity - The specified path is not a file inside the image

  /inspect/{image_uuid}/list:
    get:
      summary: List files in image
      description: Returns files list
      operationId: inspectImageFile
      tags:
        - inspect
      parameters:
        - name: image_uuid
          in: path
          required: true
          description: The UUID of the image to inspect
          schema:
            $ref: '#/components/schemas/UUIDSchema'
        - name: path
          in: query
          required: true
          allowReserved: true
          description: The path of the directory to inspect inside the image
          schema:
            type: string
            example: "/etc"
        - name: text
          in: query
          required: false
          allowEmptyValue: true
          schema:
            type: boolean
          description: If present (with or without value), returns text/plain format instead of JSON
          example: ""
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryList'
            text/plain:
              schema:
                type: string
                description: ls-like output format
                example: |
                  total 19.42 KB
                  drwxr-xr-x 1 0 0   858.00 May 30 12:13 bin
                  drwxr-xr-x 1 0 0        0 May 30 12:13 dev
                  drwxr-xr-x 1 0 0   540.00 May 30 12:13 etc
                  drwxr-xr-x 1 0 0        0 May 30 12:13 home
                  drwxr-xr-x 1 0 0   146.00 May 30 12:13 lib
                  drwxr-xr-x 1 0 0    28.00 May 30 12:13 media
                  drwxr-xr-x 1 0 0        0 May 30 12:13 mnt
                  drwxr-xr-x 1 0 0        0 May 30 12:13 opt
                  dr-xr-xr-x 1 0 0        0 May 30 12:13 proc
                  drwx------ 1 0 0        0 May 30 12:13 root
                  drwxr-xr-x 1 0 0     8.00 May 30 12:13 run
                  drwxr-xr-x 1 0 0   790.00 May 30 12:13 sbin
                  drwxr-xr-x 1 0 0        0 May 30 12:13 srv
                  drwxr-xr-x 1 0 0        0 May 30 12:13 sys
                  drwxrwxrwt 1 0 0        0 May 30 12:13 tmp
                  drwxr-xr-x 1 0 0    40.00 May 30 12:13 usr
                  drwxr-xr-x 1 0 0    86.00 May 30 12:13 var
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: Not Found - The file does not exist in the image or image does not exist
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: Unprocessable Entity - The specified path could not be listed inside the image
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

components:
  parameters:
    UntilParameter:
      name: until
      in: query
      required: false
      description: |
        **Show only results created before the given date/time or interval.**

        Accepts a Unix timestamp or interval string.

        Interval format: `600s`/`15m`/`2h`/`3d`/`1w` means 600 seconds, 15 minutes, 2 hours, 3 day, or 1 week ago respectively).

        For example:
        * `2025-01-01T12:00:00+00:00` means January 1st, 2025 at 12:00 UTC
        * `600s` means 600 seconds ago
        * `15m` means 15 minutes ago

        Invalid values raise 400 error.
      schema:
        type: string
      example: 1h
    SinceParameter:
      name: since
      in: query
      required: false
      schema:
        type: string
      example: 1w
      description: |
        **Show only results created after the given date/time or interval.**

        Accepts a Unix timestamp or interval string.

        Interval format: `600s`/`15m`/`2h`/`3d`/`1w` means 600 seconds, 15 minutes, 2 hours, 3 day, or 1 week ago respectively).

        For example:
        * `2025-01-01T12:00:00+00:00` means January 1st, 2025 at 12:00 UTC
        * `600s` means 600 seconds ago
        * `15m` means 15 minutes ago

        Invalid values raise 400 error.

  responses:
    Unauthorized:
      description: Unauthorized - Invalid or missing JWT token
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'

    Forbidden:
      description: Forbidden - Token does not have sufficient permissions
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'

    NotFound:
      description: Not Found - The requested resource does not exist
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'

    BadRequest:
      description: Bad Request - Invalid request parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'

    Conflict:
      description: Conflict - The operation cannot be completed due to a conflict
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'

  securitySchemes:
      BearerAuth:
        type: http
        scheme: bearer
        bearerFormat: JWT

  schemas:
    UUIDSchema:
      type: string
      format: uuid
      description: A UUID string
      example: "12345678-9abc-baba-deda-0123456789ab"

    ImageSourceTag:
      type: string
      description: |
        A container image tag. String must be started with a prefix "tag:" followed by the actual tag.
      pattern: '^tag:[A-Za-z0-9][A-Za-z0-9_-]*(?:[:/.][A-Za-z0-9_-]+)*$'
      example: "tag:busybox:latest"

    ImageSource:
      oneOf:
        - $ref: '#/components/schemas/UUIDSchema'
        - $ref: '#/components/schemas/ImageSourceTag'
      description: |
        An base image for run a new instance. May be either image UUID or image tag (prefixed with "tag:").
        After creation of the instance, if tag is used, this value will be resolved to the image UUID, 
        and the UUID will be stored in the metadata.
      example: "tag:busybox:latest"

    FileItem:
      type: object
      required:
        - size
        - path
        - owner
        - group
        - mode
        - mtime
        - nlink
        - uid
        - gid
        - is_dir
        - is_regular
        - is_symlink
        - is_socket
        - is_fifo
        - symlink_to
      properties:
        size:
          type: integer
          format: int64
          description: File size in bytes
          example: 1024
        path:
          type: string
          description: File name (relative to the directory being listed)
          example: "passwd"
        owner:
          oneOf:
            - type: string
            - type: integer
          description: File owner name or UID
          example: "root"
        group:
          oneOf:
            - type: string
            - type: integer
          description: File group name or GID
          example: "root"
        uid:
          type: integer
          description: User ID of the file owner
          example: 0
        gid:
          type: integer
          description: Group ID of the file
          example: 0
        mode:
          type: integer
          description: File mode/permissions as integer (octal representation)
          example: 33188
        mtime:
          type: integer
          format: int64
          description: Last modification time as Unix timestamp
          example: 1640995200
        nlink:
          type: integer
          description: Number of hard links
          example: 1
        is_dir:
          type: boolean
          description: True if the item is a directory
          example: false
        is_regular:
          type: boolean
          description: True if the item is a regular file
          example: true
        is_symlink:
          type: boolean
          description: True if the item is a symbolic link
          example: false
        is_socket:
          type: boolean
          description: True if the item is a socket
          example: false
        is_fifo:
          type: boolean
          description: True if the item is a FIFO/named pipe
          example: false
        symlink_to:
          type: string
          description: Target path if the item is a symbolic link, empty string otherwise
          example: ""

    DirectoryList:
      type: object
      required:
        - path
        - files
      properties:
        path:
          type: string
          description: The directory path that was listed
          example: "/etc"
        files:
          type: array
          description: List of files and directories in the specified path
          items:
            $ref: '#/components/schemas/FileItem'

    ImageImportRequest:
      type: object
      required:
        - registry
      properties:
        registry:
          type: object
          required:
            - url
          properties:
            url:
              type: string
              description: URL of the container registry
              example: docker://docker.io/busybox:latest
            credentials:
              type: object
              properties:
                username:
                  type: string
                  description: Username for the registry authentication
                  example: myuser
                password:
                  type: string
                  description: Password for the registry authentication
                  example: secret
                  format: password
        tag:
          type: string
          nullable: true
          description: Tag to identify the image when listing publicly available images. If omitted, the image will be private and only accessible by ID.
          example: busybox:latest
        timeout:
          type: integer
          description: Maximum time in seconds to wait for the import operation to complete
          default: 300
          example: 300

    ImageListResponse:
      type: object
      properties:
        images:
          type: array
          items:
            $ref: '#/components/schemas/Image'
          description: List of publicly available images

    ImageImportMetadata:
      type: object
      properties:
        registry:
          type: object
          properties:
            url:
              type: string
              description: URL of the container registry
              example: docker://docker.io/busybox:latest
            credentials:
              type: object
              properties:
                username:
                  type: string
                  description: Username for the registry authentication
                  example: myuser
                password:
                  type: string
                  description: Always masked in the response is present
                  example: "<MASKED>"
        tag:
          type: string
          nullable: true
        timeout:
          type: integer
          description: Maximum time in seconds to wait for the import operation to complete
          default: 300
          example: 300

    Image:
      type: object
      properties:
        uuid:
          $ref: '#/components/schemas/UUIDSchema'
        tag:
          type: string
          nullable: true
          description: Tag to identify the image
          example: busybox:latest
        created_at:
          type: string
          description: ISO 8601 formatted timestamp of when the image was created
          example: "2024-01-01T12:00:00+00:00"

    StreamRepr:
      type: object
      required:
        - value
        - encoding
      properties:
        value:
          type: string
          description: Content of the stream
          example: "Y29tbWFuZCBvdXRwdXQK"
        encoding:
          type: string
          enum: [ascii, base64]
          description: Encoding of the content
          example: "base64"
        truncated:
          type: boolean
          description: Whether the output was truncated
          example: false

    InstanceSpawnRequest:
      type: object
      required:
        - command
        - image
      properties:
        command:
          type: string
          description: >
            The command to execute. In case if `shell` is set to `true`, this MUST contain
            shell expression. 
            
            For example `echo hello world` or `ls -l /app`. 
            
            If `shell` is set to `false`, this must be a relative or absolute path to the executable inside the
            image rootfs. 
            
            For example: `/bin/app` or `/usr/bin/find`.
            
            Do not forget pass necessary `PATH` variable to env field, by default `PATH` is set to 
            `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`.
          example: /bin/app
        disposable:
          type: boolean
          description: Creates a disposable execution environment no any state will be saved.
          default: false
        hostname:
          type: string
          description: Hostname to set when execution.
          example: container-name
          default: linuxkit
        image:
          $ref: '#/components/schemas/ImageSource'
        args:
          type: array
          items:
            type: string
          description: >
            Arguments to pass to the command if shell is set to false.
          example: [arg1, arg2]
          default: []
        shell:
          type: boolean
          description: >
            Whether to run the command through a shell. If `true`, the command must be a shell expression and all
            values from args will be ignored. If `false`, the command field must be a path to an executable and
            args will be used. When `true`, environment variables from the image are automatically inherited.
            When `false`, they are not — use the `env` field to pass them explicitly.
          default: false
        env:
          type: object
          additionalProperties:
            type: string
          description: >
            Environment variables to set in the container. These are merged with image-defined
            variables when `shell` is `true`. When `shell` is `false`, only variables specified
            here are available — image-defined variables are not inherited.
          example:
            KEY1: value1
            KEY2: value2
        cwd:
          type: string
          pattern: "^((/[^/]*)+/?)?$"
          description: >
            Path to the working directory, must be absolute or a special value the empty string.
            It means the default working directory of the image or server default will be used.
            If field is omitted it will be set to the empty string.
            You must pass an existing directory otherwise the command will fail.
          example: /app
          default: ""
        stdin:
          $ref: '#/components/schemas/StreamRepr'
        timeout:
          type: integer
          description: Maximum execution time in seconds
          example: 60
        truncate_output_at:
          type: integer
          description: >
            Maximum number of bytes to keep from stdout/stderr.
            Default is `1048576` (1 MiB).
            The maximum value is `10485760` (10 MiB).
          example: 65535
          default: 1048576
        files:
          type: object
          description: Map of absolute file paths to file metadata
          additionalProperties:
            type: object
            properties:
              uuid:
                $ref: '#/components/schemas/UUIDSchema'
              uid:
                type: integer
                description: User ID
                example: 0
              gid:
                type: integer
                description: Group ID
                example: 0
              mode:
                type: string
                description: File mode in octal format (e.g., "0644")
                example: "0644"
          example:
            /root/hello.txt:
              uuid: "a9165a5d-5c86-4bd8-8ee4-ae46c19cf45d"
              uid: 0
              gid: 0
              mode: "0644"
            /tmp/log.txt:
              uuid: "065def2a-e977-4852-8b26-a0ec05e85a90"
              uid: 1000
              gid: 1000
              mode: "0600"

    InstanceSpawnResponse:
      type: object
      properties:
        uuid:
          $ref: '#/components/schemas/UUIDSchema'
        command:
          type: string
        image:
          $ref: '#/components/schemas/UUIDSchema'
        hostname:
          type: string
        args:
          type: array
          items:
            type: string
        shell:
          type: boolean
        env:
          type: object
          additionalProperties:
            type: string
        cwd:
          type: string
        stdin:
          $ref: '#/components/schemas/StreamRepr'
        timeout:
          type: integer
        truncate_output_at:
          type: integer
        disposable:
          type: boolean
        files:
          type: object
          additionalProperties:
            type: object
            properties:
              uuid:
                $ref: '#/components/schemas/UUIDSchema'
              uid:
                type: integer
              gid:
                type: integer
              mode:
                type: string
        result:
          nullable: true
          allOf:
            - $ref: '#/components/schemas/InstanceResult'

    OperationSummary:
      type: object
      properties:
        uuid:
          $ref: '#/components/schemas/UUIDSchema'
        kind:
          type: string
          description: Type of the operation
          enum: [ image_import, instance ]
        status:
          type: string
          enum: [ PENDING, ASSIGNED, EXECUTING, SUCCESS, FAILED, CANCELLED ]
          description: Current state of the instance operation
          example: success
        error:
          type: string
          nullable: true
          description: Error message if the operation failed
          example: "Container image not found"
        duration:
          type: number
          nullable: true
          description: Operation duration in seconds
        created_at:
          type: string
          description: ISO 8601 formatted timestamp when the operation was created
          example: "2024-01-01T12:00:00+00:00"

    OperationListResponse:
      type: array
      items:
        $ref: '#/components/schemas/OperationSummary'

    InstanceResult:
      type: object
      description: Result of an instance execution
      properties:
        resources:
          type: object
          properties:
            block_input:
              type: integer
              description: Block input operations
            block_output:
              type: integer
              description: Block output operations
            cost:
              type: number
              format: float
              description: Operation cost
            elapsed_time:
              type: number
              description: Elapsed wall time
            involuntary_switches:
              type: integer
              description: Number of involuntary context switches
            max_rss:
              type: integer
              description: Maximum resident set size in KB
            monotonic_time:
              type: number
              format: float
              description: Monotonic time measurement
            page_faults:
              type: integer
              description: Number of page faults
            page_faults_io:
              type: integer
              description: Number of page faults requiring I/O
            shared_memory:
              type: integer
              description: Shared memory size
            signals:
              type: integer
              description: Number of signals received
            swaps:
              type: integer
              description: Number of swaps
            system_cpu_time:
              type: number
              format: float
              description: System CPU time used
            unshared_memory:
              type: integer
              description: Unshared memory size
            user_cpu_time:
              type: number
              format: float
              description: User CPU time used
            voluntary_switches:
              type: integer
              description: Number of voluntary context switches
        state:
          type: object
          properties:
            continued:
              type: boolean
              description: Whether the process was continued from a stop
            core_dump:
              type: boolean
              description: Whether a core dump was generated
            exit_code:
              type: integer
              description: Process exit code
            pid:
              type: integer
              description: Process ID
            signal:
              type: integer
              description: Signal that caused termination, if any
            stopped:
              type: boolean
              description: Whether the process was stopped
            timed_out:
              type: boolean
              description: Whether process had been killed because operation timeout was reached
        stdout:
          $ref: '#/components/schemas/StreamRepr'
        stderr:
          $ref: '#/components/schemas/StreamRepr'

    OperationInstanceMetadata:
      allOf:
        - $ref: '#/components/schemas/InstanceSpawnRequest'
        - type: object
          description: Metadata for an instance execution operation, including request parameters and result
          properties:
            image:
              $ref: '#/components/schemas/UUIDSchema'
            result:
              $ref: '#/components/schemas/InstanceResult'

    OperationMetadata:
      oneOf:
        - $ref: '#/components/schemas/OperationInstanceMetadata'
        - $ref: '#/components/schemas/ImageImportMetadata'
      description: Metadata specific to the operation type

    OperationResponse:
      type: object
      properties:
        uuid:
          $ref: '#/components/schemas/UUIDSchema'
        kind:
          type: string
          description: Type of the operation
          enum: [ image_import, instance ]
        status:
          type: string
          enum: [ PENDING, ASSIGNED, EXECUTING, SUCCESS, FAILED, CANCELLED ]
        error:
          type: string
          nullable: true
        metadata:
          $ref: '#/components/schemas/OperationMetadata'
        result:
          type: object
          description: Result of the operation, if any
          properties:
            image:
              nullable: true
              allOf:
                - $ref: '#/components/schemas/UUIDSchema'
            tag:
              type: string
              nullable: true
              description: Tag assigned to the imported image
              example: busybox:latest
        duration:
          type: number
          nullable: true

    Error:
      type: object
      required:
        - error
      properties:
        error:
          oneOf:
            - type: string
            - type: object
            - type: array
              items:
                type: object
          description: Error message or structured validation errors
          example: "Some error occurred, this is an example of error message"
        status:
          type: integer
          description: HTTP status code
          example: 500
        traceback:
          type: array
          items:
            type: string
    FileResponse:
      type: object
      properties:
        uuid:
          $ref: '#/components/schemas/UUIDSchema'
        sha256:
          type: string
          description: SHA256 hash of the file content
          example: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"

security:
  - BearerAuth: [ ]
