From 92e2922e9507096c8f26363aff338dd6e0e0818e Mon Sep 17 00:00:00 2001 From: Piyush Jena Date: Tue, 8 Oct 2024 19:11:03 -0700 Subject: [PATCH] Add documentation for ephemeral-storage apis and bootstrap-commands --- .../en/os/1.22.x/api/endpoints/index.markdown | 2 +- .../bootstrap-commands/_index.markdown | 8 + .../bootstrap-commands/_index.markdown | 129 +++ data/settings/1.22.x/bootstrap-commands.toml | 59 ++ .../bootstrap_commands_diagram.html | 129 +++ static/external/openapi/1.22.x/openapi.yaml | 794 ++++++++++++++++++ 6 files changed, 1120 insertions(+), 1 deletion(-) create mode 100644 content/en/os/1.22.x/api/settings/bootstrap-commands/_index.markdown create mode 100644 content/en/os/1.22.x/concepts/bootstrap-commands/_index.markdown create mode 100644 data/settings/1.22.x/bootstrap-commands.toml create mode 100644 layouts/shortcodes/bootstrap_commands_diagram.html create mode 100644 static/external/openapi/1.22.x/openapi.yaml diff --git a/content/en/os/1.22.x/api/endpoints/index.markdown b/content/en/os/1.22.x/api/endpoints/index.markdown index 51580880..06fc4044 100644 --- a/content/en/os/1.22.x/api/endpoints/index.markdown +++ b/content/en/os/1.22.x/api/endpoints/index.markdown @@ -8,4 +8,4 @@ The following output is generated from [Bottlerocket's OpenAPI Spec](https://git --- -{{< swaggerui src="../../../../external/openapi/1.15.x/openapi.yaml" >}} +{{< swaggerui src="../../../../external/openapi/1.22.x/openapi.yaml" >}} diff --git a/content/en/os/1.22.x/api/settings/bootstrap-commands/_index.markdown b/content/en/os/1.22.x/api/settings/bootstrap-commands/_index.markdown new file mode 100644 index 00000000..26e8355d --- /dev/null +++ b/content/en/os/1.22.x/api/settings/bootstrap-commands/_index.markdown @@ -0,0 +1,8 @@ ++++ +title="bootstrap-commands" +type="docs" +toc_hide=true +description="Settings related to bootstrap commands (`settings.bootstrap-commands.*`)" ++++ + +{{< settings >}} diff --git a/content/en/os/1.22.x/concepts/bootstrap-commands/_index.markdown b/content/en/os/1.22.x/concepts/bootstrap-commands/_index.markdown new file mode 100644 index 00000000..1424544a --- /dev/null +++ b/content/en/os/1.22.x/concepts/bootstrap-commands/_index.markdown @@ -0,0 +1,129 @@ ++++ +title = "Bootstrap Commands" +type = "docs" +description = "Configure the host with Bottlerocket API commands during boot." ++++ + +Bootstrap commands are a way to configure and modify a Bottlerocket instance using the Bottlerocket API at boot time. They run prior to the {{< ver-ref project="os" page="/concepts/bootstrap-containers/" >}}Bootstrap Containers{{}}. + +## Lifecycle + +When you define a bootstrap command using user-data or the Bottlerocket API, the following sequence occurs on next boot: + +- [`systemd`](https://systemd.io/) runs all the bootstrap commands in lexicographical order of their names. Each Bottlerocket API command inside a bootstrap-command runs serially in the declared order. +- `systemd` will not move to the next [target](https://www.freedesktop.org/software/systemd/man/systemd.target.html) until all of the bootstrap commands start, run and exit. +- any bootstrap command configured with `mode=once` will change to `mode=off` once complete. +- any bootstrap command set to `essential=true` that exits with a non-zero exit code halts the boot process. + +### Examples + +{{< twocol + containerclass="td-max-width-on-larger-screens docs-figure" + rowclass="docs-figure" >}} + {{< twocol_inner colsplit="7" >}} + {{< bootstrap_commands_diagram example=1 >}} + {{}} + {{% twocol_inner %}} +This example shows four bootstrap commands whose names begin with `001-cmd`,`002-cmd`,`003-cmd`, and `004-cmd`. +The start order of these commands is in lexicographical order of their names. +The boot does not proceed to the next stage until the last bootstrap command completes. + {{%/ twocol_inner %}} +{{}} + +{{< twocol + containerclass="td-max-width-on-larger-screens docs-figure" + rowclass="docs-figure" >}} + {{< twocol_inner colsplit="7" >}} + {{< bootstrap_commands_diagram example=2 >}} + {{}} + {{% twocol_inner %}} +This example is the same as the previous one except the bootstrap command `003-cmd` is configured with {{< ver-ref project="os" page="/api/settings/bootstrap-commands#name_essential">}}`essential=true`{{< /ver-ref >}}. +Bootstrap command `003-cmd` exits with a non-zero exit code and consequently the boot halts. As a result, `004-cmd` isn't run at all. + {{%/ twocol_inner %}} +{{}} + +{{< twocol + containerclass="td-max-width-on-larger-screens docs-figure" + rowclass="docs-figure" >}} + {{< twocol_inner colsplit="7" >}} + {{< bootstrap_commands_diagram example=3 >}} + {{}} + {{% twocol_inner %}} +This example is the same as the first except bootstrap command `004-cmd` is configured with {{< ver-ref project="os" page="/api/settings/bootstrap-commands#name_mode">}}`mode=once`{{< /ver-ref >}}. +After `004-cmd` finishes, the bootstrap command `004-cmd` is turned off by settings its `mode` to `off`, and will no longer be executed in future boot sequences. + {{%/ twocol_inner %}} +{{}} + +### Considerations + +As a consequence of this lifecycle, you should keep a few things in mind when using bootstrap commands: + +1. Bootstrap commands **can only** run `apiclient` commands. +2. Bootstrap commands can’t run `apiclient exec` commands because host containers aren’t ready at this stage of the boot. +3. Running `apiclient reboot` in a bootstrap command with `mode=always` will cause the node to reboot endlessly. +4. `apiclient reboot` in a bootstrap command with `mode=once` will hold off the reboot until the completion of all bootstrap commands. +5. Due to serial nature of bootstrap commands, they should be short-running to reduce overhead on boot times. + +## Use cases + +The following are a few examples use cases for bootstrap commands + +### Configure ephemeral disks + +**In a Kubernetes host** + +``` +[settings.bootstrap-commands.k8s-ephemeral-storage] +commands = [ + ["apiclient", "ephemeral-storage", "init"], + ["apiclient", "ephemeral-storage" ,"bind", "--dirs", "/var/lib/containerd", "/var/lib/kubelet", "/var/log/pods"] +] +essential = true +mode = "always" +``` + +**In an ECS host** + +``` +[settings.bootstrap-commands.ecs-ephemeral-storage] +commands = [ + ["apiclient", "ephemeral-storage", "init"], + ["apiclient", "ephemeral-storage" ,"bind", "--dirs", "/var/lib/containerd", "/var/lib/docker", "/var/log/ecs"] +] +essential = true +mode = "always" +``` + +### Running the CIS reports + +**Bottlerocket CIS Benchmark** + +``` +[settings.bootstrap-commands.bottlerocket-cis-benchmark] +commands = [["apiclient", "report", "cis", "-l", "2"]] +essential = true +mode = "always" +``` + +**Kubernetes CIS Benchmark** + +``` +[settings.bootstrap-commands.kubernetes-cis-benchmark] +commands = [["apiclient", "report", "cis-k8s", "-l", "2"]] +essential = true +mode = "always" +``` + +### Checking and Applying Updates + +``` +[settings.bootstrap-commands.kubernetes-cis-benchmark] +commands = [["apiclient", "update", "apply", "--check", "--reboot"]] +essential = true +mode = "always" +``` + +## Also see +- {{< ver-ref project="os" page="/api/settings/bootstrap-commands">}} bootstrap-commands in the API Setting Reference{{< /ver-ref >}} + +{{< on-github >}} diff --git a/data/settings/1.22.x/bootstrap-commands.toml b/data/settings/1.22.x/bootstrap-commands.toml new file mode 100644 index 00000000..1e42816f --- /dev/null +++ b/data/settings/1.22.x/bootstrap-commands.toml @@ -0,0 +1,59 @@ +[[docs.ref.name_commands]] +name_override = ".commands" +description = "Specifies the API commands to be run as part of the bootstrap command. Each API command is expressed as a list of strings and commands field comprises of a list of API commands." +see = [ + ["[`settings.bootstrap-commands..mode`](../bootstrap-commands/#name_mode) for a full example with `settings.bootstrap-commands..commands`."], + ["The {{< ver-ref project=\"os\" page=\"/concepts/bootstrap-commands#lifecycle\" >}}bootstrap commands lifecycle{{< /ver-ref >}} conceptual documentationion"] +] + +[[docs.ref.name_essential]] +name_override = ".essential" +description = "If `essential` is set to `true` the bootstrap command will halt the boot process when it exits with a non-zero exit code." +default = "`false`" +accepted_values = [ + "`true`", + "`false`" +] +see = [ + ["[`settings.bootstrap-commands..mode`](../bootstrap-commands/#name_mode) for a full example with `settings.bootstrap-commands..essential`."], + ["The {{< ver-ref project=\"os\" page=\"/concepts/bootstrap-commands#lifecycle\" >}}bootstrap commands lifecycle{{< /ver-ref >}} conceptual documentationion"] +] + + +[[docs.ref.name_mode]] +name_override = ".mode" +description = """ +Specifies how (or if) a bootstrap command starts at boot. +If you set the value to: + +* `"always"`, the bootstrap command will start on every boot, +* `"off"`, the bootstrap command will not start at boot, +* `"once"`, the bootstrap command will start on the first boot but after exit, the `mode` changes to `off`. +""" +accepted_values = [ + "`\"always\"`", + "`\"off\"`", + "`\"once\"`" +] +see = [ + ["[`settings.bootstrap-commands..mode`](../bootstrap-commands/#name_mode) for a full example with `settings.bootstrap-commands..mode`."], + ["The {{< ver-ref project=\"os\" page=\"/concepts/bootstrap-commands#lifecycle\" >}}bootstrap commands lifecycle{{< /ver-ref >}} conceptual documentation"] +] + +[[docs.ref.name_mode.example]] +direct_toml = """ +# Creates a bootstrap command called `mybootstrap` +# It runs everytime the instance boots and if exits with a non-zero code, will halt the boot process +[settings.bootstrap-commands.mybootstrap] +commands = [["apiclient", "ephemeral-storage", "init"], ["apiclient", "ephemeral-storage" ,"bind", "--dirs", "/var/lib/containerd", "/var/lib/docker", "/var/log/ecs"]] +essential = true +mode = "always" +""" +direct_shell = """ +# Creates a bootstrap container called `mybootstrap` +# It runs only one time and if exits with a non-zero code, will halt the boot process +apiclient set \\ + bootstrap-commands.mybootstrap.source=[["apiclient", "ephemeral-storage", "init"], ["apiclient", "ephemeral-storage" ,"bind", "--dirs", "/var/lib/containerd", "/var/lib/docker", "/var/log/ecs"]] \\ + bootstrap-commands.mybootstrap.essential=true \\ + bootstrap-commands.mybootstrap.mode=\"always\" +""" diff --git a/layouts/shortcodes/bootstrap_commands_diagram.html b/layouts/shortcodes/bootstrap_commands_diagram.html new file mode 100644 index 00000000..89c79961 --- /dev/null +++ b/layouts/shortcodes/bootstrap_commands_diagram.html @@ -0,0 +1,129 @@ +{{- $example := .Get "example" -}} + +{{ if (eq $example 1) }} + + + + + + + + systemd + + + + + + + bootstrap commands + + + + 001-cmd + + + + 002-cmd + + + + 003-cmd + + + + 004-cmd + + + + next boot stage + + + +{{ end }} +{{ if (eq $example 2) }} + + + + + + + + systemd + + + + + + + 001-cmd + + + bootstrap commands + + + + 002-cmd + + + + 003-cmd + essential = true + + + boot halt + + + + exit code 1 + + + +{{end}} +{{ if (eq $example 3) }} + + + + + + + + systemd + + + + + bootstrap commands + + + + 001-cmd + + + + 002-cmd + + + + 003-cmd + essential = true + + + + + + 004-cmd + mode=once + + + Update mode for + 004-cmd to off + + + + + + next boot stage + + + +{{end}} diff --git a/static/external/openapi/1.22.x/openapi.yaml b/static/external/openapi/1.22.x/openapi.yaml new file mode 100644 index 00000000..726584f3 --- /dev/null +++ b/static/external/openapi/1.22.x/openapi.yaml @@ -0,0 +1,794 @@ +openapi: "3.0.2" +info: + version: "0.1.0" + title: "Bottlerocket API" + description: "The API for the Bottlerocket OS" + license: + name: "Apache-2.0 OR MIT" + url: "https://github.com/bottlerocket-os/bottlerocket/blob/develop/COPYRIGHT" + +servers: +- url: file:///run/api.sock + description: The production API server + +components: + schemas: + HashMap: + type: object + additionalProperties: + type: string + Service: + type: object + additionalProperties: + $ref: '#/components/schemas/HashMap' + Services: + type: object + additionalProperties: + $ref: '#/components/schemas/Service' + ConfigurationFileInfo: + type: object + properties: + template-path: + type: string + path: + type: string + mode: + type: string + ConfigurationFiles: + type: object + additionalProperties: + $ref: '#/components/schemas/ConfigurationFileInfo' + Report: + type: object + properties: + name: + type: string + description: + type: string + Version: + type: object + properties: + major: + type: integer + minor: + type: integer + patch: + type: integer + UpdateImage: + type: object + properties: + arch: + type: string + variant: + type: string + version: + $ref: '#/components/schemas/Version' + StagedImage: + type: object + properties: + image: + $ref: '#/components/schemas/UpdateImage' + next_to_boot: + type: boolean + CommandResult: + type: object + properties: + cmd_type: + type: string + cmd_status: + type: string + timestamp: + type: string + exit_status: + type: integer + stderr: + type: string + UpdateStatus: + type: object + properties: + update_state: + type: string + available_updates: + type: array + items: + $ref: '#/components/schemas/Version' + chosen-update: + $ref: '#/components/schemas/UpdateImage' + active-partition: + $ref: '#/components/schemas/StagedImage' + staging-partition: + $ref: '#/components/schemas/StagedImage' + most-recent-command: + $ref: '#/components/schemas/CommandResult' + EphemeralStorageInit: + type: object + properties: + filesystem: + type: string + disks: + type: array + items: + type: string + EphemeralStorageBind: + type: object + properties: + targets: + type: array + items: + type: string + Settings: + type: object + properties: + motd: + type: string + kubernetes: + type: object + ecs: + type: object + updates: + type: object + host-containers: + type: object + ntp: + type: object + properties: + time-servers: + type: array + items: + type: string + network: + type: object + properties: + hostname: + type: string + kernel: + type: object + properties: + lockdown: + type: string + aws: + type: object + properties: + region: + type: string + config: + type: string + credentials: + type: string + profile: + type: string + metrics: + type: object + oci-defaults: + type: object + oci-hooks: + type: object + properties: + log4j-hotpatch-enabled: + type: boolean + cloudformation: + type: object + properties: + should-signal: + type: boolean + stack-name: + type: string + logical-resource-id: + type: string + autoscaling: + type: object + properties: + should-wait: + type: boolean + additionalProperties: true + BottlerocketRelease: + type: object + properties: + pretty-name: + type: string + variant-id: + type: string + version-id: + type: string + build-id: + type: string + arch: + type: string + Model: + type: object + properties: + settings: + $ref: '#/components/schemas/Settings' + services: + $ref: '#/components/schemas/Services' + configuration-files: + $ref: '#/components/schemas/ConfigurationFiles' + os: + $ref: '#/components/schemas/BottlerocketRelease' + +paths: + /: + get: + summary: "Get current model, including settings, services, configuration files, and os info" + operationId: "get_model" + parameters: + - in: query + name: prefix + description: "Specific key prefix to query" + schema: + type: string + required: false + responses: + 200: + description: "Successful request" + content: + application/json: + schema: + $ref: "Model" + 500: + description: "Server error" + + /settings: + get: + summary: "Get current settings" + operationId: "get_settings" + parameters: + - in: query + name: keys + description: "Specific keys to query. Takes precedence over 'prefix' if both query parameters are supplied" + schema: + type: array + items: + type: string + # `style: form` and `explode: false` format parameters as such: /settings?keys=foo,bar,baz + style: form + explode: false + required: false + - in: query + name: prefix + description: "Specific key prefix to query. This parameter will be ignored if 'keys' is also supplied" + schema: + type: string + required: false + responses: + 200: + description: "Successful request" + content: + application/json: + schema: + $ref: "Settings" + 500: + description: "Server error" + patch: + summary: "Update settings" + operationId: "set_settings" + parameters: + - in: query + name: tx + description: "Transaction in which to update settings; defaults to user 'default' transaction" + schema: + type: string + required: false + requestBody: + required: true + content: + application/json: + schema: + $ref: "Settings" + responses: + 204: + description: "Settings successfully staged for update" + 400: + description: "Invalid body" + 500: + description: "Server error" + + /tx: + get: + summary: "Get pending settings in a transaction" + operationId: "get_tx" + parameters: + - in: query + name: tx + description: "Transaction for which to retrieve pending settings; defaults to user 'default' transaction" + schema: + type: string + required: false + responses: + 200: + description: "Successful request" + content: + application/json: + schema: + $ref: "Settings" + 500: + description: "Server error" + delete: + summary: "Delete transaction" + operationId: "delete_tx" + parameters: + - in: query + name: tx + description: "Transaction to delete; defaults to user 'default' transaction" + schema: + type: string + required: false + responses: + 200: + description: "Successful deleted pending settings - deleted keys are returned" + 500: + description: "Server error" + + /tx/list: + get: + summary: "List names of pending transactions" + operationId: "list_tx" + responses: + 200: + description: "Successful request" + content: + application/json: + schema: + type: array + items: + type: string + 500: + description: "Server error" + + /tx/commit: + post: + summary: "Commit pending settings, without applying changes to config files or restarting services" + operationId: "commit_tx" + parameters: + - in: query + name: tx + description: "Transaction to commit; defaults to user 'default' transaction" + schema: + type: string + required: false + responses: + 200: + description: "Successfully Staged settings - changed keys are returned" + 500: + description: "Server error" + + /tx/apply: + post: + summary: "Apply changes to config files and restart services" + operationId: "apply" + parameters: + - in: query + name: keys + description: "Apply changes only if related to these keys; if not specified, applies for all known keys" + schema: + type: array + items: + type: string + # `style: form` and `explode: false` format parameters as such: /tx/apply?keys=settings.foo,settings.bar + style: form + explode: false + required: false + responses: + 204: + description: "Successfully started settings applier" + 500: + description: "Server error" + + /tx/commit_and_apply: + post: + summary: "Commit transaction, and apply any committed changes to relevant config files and services" + operationId: "commit_tx_and_apply" + parameters: + - in: query + name: tx + description: "Transaction to commit; defaults to user 'default' transaction" + schema: + type: string + required: false + responses: + 200: + description: "Successful settings update, committed keys are returned" + 500: + description: "Server error" + + /os: + get: + summary: "Get OS information such as version, variant, and architecture" + operationId: "get_os_info" + parameters: + - in: query + name: prefix + description: "Specific key prefix to query" + schema: + type: string + required: false + responses: + 200: + description: "Successful request" + content: + application/json: + # The response is a hashmap of string to string. Example: + # { "arch": "x86_64" } + schema: + type: object + additionalProperties: + type: string + 500: + description: "Server error" + + /metadata/affected-services: + get: + summary: "Get affected services" + operationId: "get_affected_services" + parameters: + - in: query + name: keys + description: "Specific keys to query" + schema: + type: array + items: + type: string + # `style: form` and `explode: false` format parameters as such: /metadata/affected-services?keys=settings.foo,settings.bar + style: form + explode: false + required: true + responses: + 200: + description: "Successful request" + content: + application/json: + # The response is a hashmap of string to array of strings. Example: + # { "settings.foo": [ "service1", "service2" ] } + schema: + type: object + additionalProperties: + type: array + items: + type: string + 400: + description: "Missing required query parameter: 'keys'" + 500: + description: "Server error" + + /metadata/setting-generators: + get: + summary: "Get programs needed to generate settings" + operationId: "get_setting_generators" + responses: + 200: + description: "Successful request" + content: + application/json: + # The response is a hashmap of string to string. Example: + # { "settings.foobar": "/usr/bin/foobar" } + schema: + type: object + additionalProperties: + type: string + 500: + description: "Server error" + + /metadata/templates: + get: + summary: "Get template strings for dynamically generated settings" + operationId: "get_templates" + responses: + 200: + description: "Successful request" + content: + application/json: + # The response is a hashmap of string to string. Example: + # { "settings.foobar": "hi {{ key }}" } + schema: + type: object + additionalProperties: + type: string + 500: + description: "Server error" + + /services: + get: + summary: "Get service data" + operationId: "get_services" + parameters: + - in: query + name: names + description: "Specific services to query" + schema: + type: array + items: + type: string + # `style: form` and `explode: false` format parameters as such: /services?names=foo,bar,baz + style: form + explode: false + required: false + - in: query + name: prefix + description: "Specific key prefix to query. This parameter will be ignored if 'names' is also supplied" + schema: + type: string + required: false + responses: + 200: + description: "Successful request" + content: + application/json: + schema: + $ref: "Services" + 500: + description: "Server error" + + /configuration-files: + get: + summary: "Get configuration file data" + operationId: "get_config_files" + parameters: + - in: query + name: names + description: "Specific configuration files to query" + schema: + type: array + items: + type: string + # `style: form` and `explode: false` format parameters as such: /configuration-files?names=file1,file2 + style: form + explode: false + required: false + - in: query + name: prefix + description: "Specific key prefix to query. This parameter will be ignored if 'names' is also supplied" + schema: + type: string + required: false + responses: + 200: + description: "Successful request" + content: + application/json: + schema: + $ref: "ConfigurationFiles" + 500: + description: "Server error" + + /actions/reboot: + post: + summary: "Reboot" + operationId: "reboot" + responses: + 204: + description: "Reboot requested" + 500: + description: "Server error" + + /actions/refresh-updates: + post: + summary: "Query update repository and refresh list of updates" + operationId: "refresh_update" + responses: + 204: + description: "Successful request" + 500: + description: "Server error" + 423: + description: "Update write lock held. Try again in a moment" + + /actions/prepare-update: + post: + summary: "Download the chosen update and write the update image to the inactive partition" + operationId: "prepare_update" + responses: + 204: + description: "Successful request" + 404: + description: "Chosen update does not exist" + 409: + description: "Action not allowed according to current update state" + 500: + description: "Server error" + 423: + description: "Update write lock held. Try again in a moment" + + /actions/activate-update: + post: + summary: "Mark the partition with the prepared update as active so you can reboot into the chosen version" + operationId: "activate_update" + responses: + 204: + description: "Successfully activated update" + 404: + description: "No update image applied to staging partition, need to prepare-update first" + 409: + description: "Action not allowed according to current update state" + 500: + description: "Server error" + 423: + description: "Update write lock held. Try again in a moment" + + /actions/deactivate-update: + post: + summary: "Deactivate the update by marking the running partition as active again" + operationId: "deactivate-update" + responses: + 204: + description: "Successfully deactivated update" + 404: + description: "No update image applied to staging partition, need to prepare-update first" + 409: + description: "Action not allowed according to current update state" + 500: + description: "Server error" + 423: + description: "Update write lock held. Try again in a moment" + + /actions/ephemeral-storage/init: + post: + summary: "Initialize ephemeral storage" + operationId: "init" + requestBody: + required: true + content: + application/json: + schema: + $ref: "EphemeralStorageInit" + responses: + 200: + description: "Successful request" + content: + application/json: + schema: + type: string + 400: + description: "Bad request input" + 422: + description: "Unprocessable request" + 500: + description: "Server error" + + /actions/ephemeral-storage/bind: + post: + summary: "Bind directories to previously initialized ephemeral storage" + operationId: "bind" + requestBody: + required: true + content: + application/json: + schema: + $ref: "EphemeralStorageBind" + responses: + 200: + description: "Successful request" + content: + application/json: + schema: + type: string + 400: + description: "Bad request input" + 422: + description: "Unprocessable request" + 500: + description: "Server error" + + /actions/ephemeral-storage/list-disks: + get: + summary: "List the discovered ephemeral disks that can be initialized" + operationId: "list-disks" + parameters: + - in: query + name: format + description: "Format of the disk listing (text or json). Default format is text." + schema: + type: string + required: false + responses: + 200: + description: "Successful request" + content: + application/json: + schema: + type: string + 400: + description: "Bad request input" + 422: + description: "Unprocessable request" + 500: + description: "Server error" + + /actions/ephemeral-storage/list-dirs: + get: + summary: "List the directories that can be bound to ephemeral storage" + operationId: "list-dirs" + parameters: + - in: query + name: format + description: "Format of the directory listing (text or json). Default format is text." + schema: + type: string + required: false + responses: + 200: + description: "Successful request" + content: + application/json: + schema: + type: string + 400: + description: "Bad request input" + 422: + description: "Unprocessable request" + 500: + description: "Server error" + + /updates/status: + get: + summary: "Get update status" + operationId: "get_update_status" + responses: + 200: + description: "Successful request" + content: + application/json: + schema: + $ref: "UpdateStatus" + 500: + description: "Server error" + 423: + description: "Update write lock held. Try again in a moment" + + /exec: + get: + summary: "Request exec WebSocket" + operationId: "exec" + responses: + 101: + description: "Connection upgraded to WebSocket" + 500: + description: "Server error" + + /report: + get: + summary: "Get available report types" + operationId: "get_reports" + responses: + 200: + description: "Successful request" + content: + application/json: + schema: + type: array + items: + $ref: "Report" + 500: + description: "Server error" + + /report/cis: + get: + summary: "Get CIS benchmark report" + operationId: "cis-report" + parameters: + - in: query + name: level + description: "The CIS compliance level to test (1 or 2). Default level is 1." + schema: + type: integer + minimum: 1 + maximum: 2 + required: false + - in: query + name: format + description: "The CIS compliance report format (text or json). Default format is text." + schema: + type: string + required: false + responses: + 200: + description: "Successful request" + content: + application/json: + schema: + type: string + 400: + description: "Bad request input" + 422: + description: "Unprocessable request" + 500: + description: "Server error"