# Welcome to Cedana

<figure><img src="/files/rqmSq6dZRPlF6g50W8oM" alt=""><figcaption></figcaption></figure>

**Cedana** (/ce'dana/) is Save/Migrate/Resume (SMR) for containerized CPU and GPU workloads. Our solution sits between the linux kernel and your workloads to save the full state of your container enabling you to save, migrate and resume your workloads across instances and vendors.

Our API enables users to integrate this powerful capability into their clusters.

We are building a global, real-time system for compute that is designed to 1) maximize compute utilization by eliminating idle resources, 2) seamlessly access all available compute, 3) increase reliabiltiy and availability through node failures, and 4) support policy-based orchestration with workload-level SLAs. This changes how we allocate resources to high performance computing, numerical simulation, and training/running AI models.

To get started, follow the sidebar!


# Authentication

Reach out to us through your contact at Cedana or <founders@cedana.ai> to get an account!

Once logged in, you'll be redirected to an account management page, where you can create an API key. If you've logged in via your organization's email address, you'll be able to create and manage organization-wide API keys as well.

Once you have obtained an API key, you can set up and start using Cedana with your system of choice via either:

* [Cedana for Kubernetes](https://github.com/cedana/cedana-gitbook/blob/main/cedana-kubernetes/installation.md)
* [Cedana for SLURM](https://github.com/cedana/cedana-gitbook/blob/main/cedana-slurm/installation.md)
* Cedana on Bare-Metal (see [Cedana Daemon documentation](https://docs.cedana.ai/daemon/))


# Local Setup

It's also possible to use the powerful save and resume capabilities of Cedana on any linux host, locally.

The Cedana daemon is designed to manage the lifecycle of processes/containers, including checkpoint/restore, in the larger Cedana system. However, it can be installed and used independently as a checkpoint/restore tool with its convenient defaults and a friendly command-line interface.

Go to [Cedana Daemon documentation](https://docs.cedana.ai/daemon/).


# Installation

Begin checkpoint/migrate/restoring stateful workloads in Kubernetes in under 5 minutes!

We provide a helm chart to easily install our services on your cluster.

{% hint style="success" %}
To use Cedana in Kubernetes, you need to be registered with us! Reach out to [founders@cedana.ai](mailto:foundes@cedana.ai) to get set up with an organization.
{% endhint %}

{% hint style="info" %}
You can also deploy fully self-hosted, with zero limitations on where you can store your checkpoints! Check out [configuration](/cedana-kubernetes/configuration). If you have any questions, please reach out to us at <founders@cedana.ai>.
{% endhint %}

## Install

{% hint style="success" %}
To install Cedana on your cluster, you need to be authenticated. See [authentication](/get-started/authentication).
{% endhint %}

1. Make sure you have the `helm` tool installed. See the [Helm installation guide](https://helm.sh/docs/intro/install/) for instructions.
2. Register a new cluster on the [Clusters Page](https://ui.cedana.com/monitoring/clusters).

<figure><img src="/files/4Fdn1RiIBmC1RGXSR2av" alt=""><figcaption></figcaption></figure>

3. Once you've registered your cluster, you'll receive a `clusterId`. Use this `clusterId`, along with your `authToken` and `url` to install the helm chart below.

<figure><img src="/files/YvdhNBXFM68SZbnDshWf" alt=""><figcaption></figcaption></figure>

4. Run the following command to install the helm chart:

```bash
export CEDANA_AUTH_TOKEN=<your-auth-token>
export CEDANA_CLUSTER_ID=<cluster_id>
export CEDANA_URL=<your-org-url>

helm upgrade -i cedana oci://registry-1.docker.io/cedana/cedana-helm  \
 --create-namespace -n cedana-system \
 --set=config.clusterId=$CEDANA_CLUSTER_ID \
 --set=config.url=$CEDANA_URL \
 --set=config.authToken=$CEDANA_AUTH_TOKEN
```

Take a look at [Configuration](/cedana-kubernetes/configuration) for customizing your Cedana installation.

You're all set up! Let's checkpoint some workloads. Continue to [Checkpoint/restore](/cedana-kubernetes/cr) to get started.

## Uninstall

To uninstall Cedana completely, simply do:

```bash
helm uninstall cedana -n cedana-system
```


# Manual Checkpoint/Restore

Begin checkpoint/migrate/restoring stateful workloads in Kubernetes in under 5 minutes!

For CPU workloads, no additional configuration is required. With Cedana running on your cluster, you can start by deploying this sample stateful reinforcement learning job (running [Stable Baselines 3](https://github.com/DLR-RM/stable-baselines3)).

## Deploy

```yaml
# test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: cedana-sample-ppo-sb3
  labels:
    app: cedana-sample-ppo-sb3
spec:
  restartPolicy: Never
  containers:
    - name: cedana-sample-container
      image: "cedana/cedana-samples:latest"
      command: ["python3", "/app/cpu_smr/rl/ppo_sb3.py"]
      resources:
        requests:
          cpu: "1"
        limits:
          cpu: "1"
```

{% hint style="info" %}
Note that for any sort of automation (resume on failure), it might make more sense to use [Kubernetes Jobs](https://kubernetes.io/docs/concepts/workloads/controllers/job/). See [checkpoint/restoring Jobs](/cedana-kubernetes/jobs) for more information.
{% endhint %}

Deploy this pod to your cluster using:

```bash
kubectl apply -f test-pod.yaml
```

## Checkpoint

You can either create a heartbeat policy to automatically checkpoint at regular intervals, or you can manually checkpoint this pod on the [Pods Page](https://ui.cedana.com/monitoring/pods).

## Restore

You can manually restore the workload on the [Checkpoints Page](https://ui.cedana.com/checkpoints).

{% hint style="info" %}
Automated restores are currently best performed *within* the context of the Kubernetes lifecycle, where we integrate cleanly. For example, if you're using a kind (e.g. [Kubernetes Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)) that automatically reschedules the pod on node failure or eviction, it will restore from the latest checkpoint instead of starting from scratch. Check [checkpoint/restoring Jobs](/cedana-kubernetes/jobs) for more information.
{% endhint %}

## Example

Below you can find an example of this workflow:

{% embed url="<https://youtu.be/J_yEUqt66Rw>" %}

If you've made it this far, congratulations! You've successfully used Cedana to move a stateful workload between nodes and have it pick up work where it left off.

Take a look at the left sidebar to see more examples, such as [GPU Save/Migrate/Resume on Kubernetes](https://github.com/cedana/cedana-gitbook/blob/main/examples/gpu-smr-on-kubernetes.md).


# Automatic Checkpoint/Restore

Adding automation to checkpoint/restore in Kubernetes

Cedana offers two distinct types of automation to best take advantage of our checkpoint/restore.

### Policies

Through the dashboard, you can enable and set policies, that configure bits of automation like heartbeat checkpointing, which will act as a cron job and checkpoint every *n* minutes.

<figure><img src="/files/T2vTQLxcHkTmKuCQ7Wb2" alt=""><figcaption></figcaption></figure>

Policies in cedana operate through a Trigger -> Filter -> Action mechanism, allowing users to build complex automations. For example, you could build:

* a policy that automatically fires a checkpoint if a pod exceeds 80% memory utilization in a specific namespace or deployment,
* a policy that deletes checkpoints past a certain age,
* a policy that checkpoints on some webhook

We aim for the policy engine to be extensible, so value feedback for more features! Policies work best when integrated into Kubernetes however, as the below section illustrates.

### Integration into Kubernetes

The second is simply our deep integration into Kubernetes. As users, you are likely to use tools such as Armada, Kueue, KServe, Dynamo, etc, that are come with their own opinions about container lifecycle, management, preemption and more.

As we work seamlessly with the scheduler, cedana automatically inserts the checkpoint if a pod (that had a checkpoint previously taken) auto-scales. For example, if using a tool like Karpenter, cedana will automatically restore from a checkpoint when the underlying node is preempted and a new node is spun up, *instead of starting from scratch.*

Our goal is to be as pain-free to integrate into your existing tooling as possible, and as such simply work with schedulers like the ones listed above. The best demonstration of this can be found in [Jobs](/cedana-kubernetes/jobs), which can more or less be applied universally to kubernetes kinds.

At the node level, Cedana uses the `cedana.ai/not-ready` taint while a node is bootstrapping. That taint is removed only after both the `cedana-helper` and `cedana-health-check` pods are Ready, which prevents workloads from landing on a node before Cedana is ready to restore them.

If you need Cedana to preserve additional pod spec fields during checkpointing, or map an older field name into the saved spec, see [Pod Spec Whitelist and Remapping](/cedana-kubernetes/podspec-whitelist-remapping).

See our Managed Dynamo for an example with a more complex Kubernetes deployment.


# Storage

There are two aspects to storage we cover here - ***where*** we checkpoint to, and ***what*** we checkpoint.

## Where we checkpoint *to*

Simple, anywhere that's POSIX complaint. Our helm charts come configured to write to local storage at first so there's no issues, but while setting up Cedana you can configure a folder that's mounted in on a NAS or even an S3-compatible bucket. Here's an example:<br>

```
--set config.awsAccessKeyId=$AWS_ACCESS_KEY_ID \ 
--set config.awsSecretAccessKey=$AWS_SECRET_ACCESS_KEY \
--set config.awsRegion=$PROVIDER_REGION \ 
--set config.awsEndpoint="https://storage.eu-north1.nebius.cloud"
```

Note that in the above case, it's not sending to S3 but an S3-compatible bucket hosted on another cloud provider (Nebius).

## What *else* we checkpoint

While we can move the state of your process (including both CPU and GPU state), there should be some careful consideration with open files.

Given this, we have three ways with which we currently deal with files that are being written to (as a restored or migrated process *expects* the file to have the exact same size so it can pick up where it left off). There are 2 scenarios we recommend for 2 different filesystem-writing regimes:

* files <\~ 1GB: *Default Behavior*
* files >> 1GB: *Volume snapshotting*

Each scenario is described below.

## Default Behavior

If you're writing files into the rootfs of the container, we just take them with us on the snapshot! We perform a diff of the filesystem and add it to our process/system-level checkpoint. This includes JIT compiled files, intermediate files created during install and more.

However, when files become very large >> 1GB, and persistence is necessary (if the files themselves are outputs of the run, like in physical simulations for example), we recommend using volumes.

## Volume Snapshotting

{% hint style="info" %}
This is still a very early work in progress! Please reach out to us if you're planning on using this.
{% endhint %}

The alternate method requires coordination with your CSI driver. We take advantage of the snapshotting primitives already present (<https://kubernetes.io/docs/concepts/storage/volume-snapshots/>), and take a reference to these with us; so when we restore, we restore from a Kubernetes Volume Snapshot.

## Persistent Volume Claims

If your workload uses `PersistentVolumeClaim`-backed volumes, Cedana also checkpoints the PVC objects that are attached to the pod.

During checkpointing:

* Cedana collects each PVC referenced by the pod.
* If the PVC is bound to a PV, Cedana patches that PV to use the `Retain` reclaim policy when needed.

During restore:

* Cedana recreates missing PVCs for the restored pod.
* If the original PVC was bound to a specific PV and that PV is still available, Cedana tries to reclaim it.
* If the PV cannot be reclaimed or is no longer present, Cedana falls back to dynamic provisioning by clearing the explicit `volumeName`.

This keeps volume-backed workloads restorable without requiring you to manually rewire storage objects after a checkpoint.


# Jobs

The right question is: what schedulers do we not support?

While Cedana can checkpoint/migrate/restore arbitrary Kubernetes pods, if you come in with your own CRDs, use the standard kubernetes job or use a scheduler like [Armada](https://github.com/armadaproject/armada), [Kueue](https://kueue.sigs.k8s.io/) or [Volcano](https://volcano.sh/en/); things become more complicated.

Fortunately, Cedana has a very simple integration for making it as seamless as possible to work with most systems under the sun.

Simply add the `CEDANA_CHECKPOINT` env to the spec of the container you're trying to checkpoint, and you're set!

Here's an example yaml for a standard k8s job:

```yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: cuda-vector-add-job
  namespace: default
spec:
  backoffLimit: 1
  completions: 1
  parallelism: 1
  completionMode: NonIndexed
  manualSelector: false
  podReplacementPolicy: TerminatingOrFailed
  template:
    metadata:
      labels:
        job-name: cuda-vector-add-job
    spec:
      restartPolicy: Never
      runtimeClassName: cedana
      priorityClassName: indiv-priority
      volumes:
        - name: repo-data
          emptyDir: {}
      initContainers:
        - name: clone-repo
          image: alpine/git:latest
          command:
            - sh
            - -c
            - |
              echo "Init ran at $(date)" >> /workspace/init-log.txt
              git clone https://github.com/mirror/busybox.git /workspace || echo "Clone failed"
          volumeMounts:
            - name: repo-data
              mountPath: /workspace
      containers:
        - name: cuda-vector-add
          image: cedana/cedana-samples:cuda
          command:
            - /bin/sh
            - -c
            - |
              gpu_smr/vector_add
          env:
            - name: CEDANA_CHECKPOINT
              value: job-preemption-test-3
          resources:
            limits:
              nvidia.com/gpu: 1 # request one GPU
            requests:
              nvidia.com/gpu: 1
          volumeMounts:
            - name: repo-data
              mountPath: /workspace
```

This comes with an `initContainer` and a `volumeMount`, which we have no issues supporting. Notice the env for the container we do wish to checkpoint/migrate/resume:

```yaml
env:
  - name: CEDANA_CHECKPOINT
    value: job-preemption-test-3
```

Once applied, every subsequent application of that yaml will ***use the latest snapshot taken*** for that ID when starting the container.

Since this is how Kubernetes jobs work under the hood (when they get restarted if the job isn't complete), if the job fails for whatever reason (preemption, node failure, etc) - as long as a checkpoint has been taken with a unique ID, it'll pick up from where it left off.

For convenience, these are also represented as automatic policies in the UI:

<figure><img src="/files/Cep0Y9j9b0jUS6oaXjB7" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/SIBJkpDEbpHBsnS18YKM" alt=""><figcaption></figcaption></figure>


# Pod Spec Whitelist and Remapping

Extending the saved Kubernetes pod spec with annotations

When Cedana checkpoints a pod, the controller stores a reduced version of the pod spec for later restore. By default, it keeps the core fields the controller already depends on. If your workload needs extra fields preserved, or if you need to map a legacy field name into the modern pod spec, you can opt in with pod annotations.

## Annotations

Use these annotations on `metadata.annotations`:

* `cedana.ai/pod-spec-whitelist`
* `cedana.ai/pod-spec-remap`

## Default behavior

The saved pod spec always includes these fields without any annotation:

* `volumes`
* `nodeSelector`
* `containers`
* `initContainers`
* `restartPolicy`
* `dnsPolicy`
* `serviceAccountName`
* `priorityClassName`
* `priority`

This default set is intentionally small so Cedana only preserves the fields it already needs for restore.

## Whitelist annotation

The whitelist annotation is a comma-separated list of pod spec field names.

Example:

```yaml
metadata:
  annotations:
    cedana.ai/pod-spec-whitelist: "schedulerName,tolerations"
```

Each listed field is copied from the live pod spec into the saved pod spec if the controller supports it.

Supported whitelist fields:

* `affinity`
* `automountServiceAccountToken`
* `dnsConfig`
* `enableServiceLinks`
* `hostAliases`
* `imagePullSecrets`
* `schedulerName`
* `tolerations`
* `topologySpreadConstraints`

Behavior:

* Unknown or unsupported field names are ignored and logged as warnings.
* Empty entries are skipped.
* Duplicate entries are harmless.

## Remap annotation

The remap annotation is a JSON object that maps a source field to a destination field.

Example:

```yaml
metadata:
  annotations:
    cedana.ai/pod-spec-remap: '{"serviceAccount":"serviceAccountName"}'
```

This is useful when a pod spec uses a deprecated or alternate field name that should be written into the modern field before the checkpointed spec is published.

Supported remaps:

* `serviceAccount` to `serviceAccountName`

Behavior:

* The annotation must be valid JSON.
* Both the source field and destination field must be supported by the controller.
* The source value must be non-empty.
* A remap does not overwrite a destination field that was already populated by the default saved spec.
* Invalid remaps are ignored and logged as warnings.

## Merge order

Cedana applies the saved spec updates in this order:

1. Copy the default fields into the saved spec.
2. Apply whitelist entries.
3. Apply remaps.

This means annotations only add fields to the saved spec. They do not remove the default fields, and remaps stay conservative so they do not overwrite a non-empty destination field.

## Example pod

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: cedana-podspec-meta-sample
  annotations:
    cedana.ai/pod-spec-whitelist: "schedulerName,tolerations"
    cedana.ai/pod-spec-remap: '{"serviceAccount":"serviceAccountName"}'
spec:
  serviceAccount: legacy-runner
  schedulerName: default-scheduler
  restartPolicy: Never
  tolerations:
    - key: dedicated
      operator: Equal
      value: checkpoint
      effect: NoSchedule
  containers:
    - name: app
      image: busybox:1.36
      command: ["sh", "-c", "sleep 3600"]
```

For this pod, the saved spec keeps the default fields and also preserves:

* `schedulerName`
* `tolerations`
* `serviceAccountName` copied from `serviceAccount`

## Operational notes

* If you are debugging a missing field, check the Cedana controller logs for warnings about unknown whitelist fields or invalid remaps.
* This feature is designed for the controller path that captures pod specs during checkpointing, so it applies to workloads restored through Cedana Kubernetes.


# Configuration

This document outlines the configurable parameters for the Cedana Helm chart. For up-to-date configuration, see [values.yaml](https://github.com/cedana/cedana-helm-charts/blob/main/cedana-helm/values.yaml).

## Global Settings

These settings control the overall behavior of the deployment.

| Parameter                 | Description                                                                                                                                                                                                                                                  | Default         |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- |
| `nameOverride`            | Overrides the name of the chart.                                                                                                                                                                                                                             | `cedana`        |
| `fullnameOverride`        | Overrides the full name of the release.                                                                                                                                                                                                                      | `cedana`        |
| `installKueue`            | If set to `true`, Kueue will be installed. **Note:** The Kueue CRDs must be applied before enabling this option. You can apply them with `kubectl apply --server-side -f https://github.com/kubernetes-sigs/kueue/releases/download/v0.10.1/manifests.yaml`. | `false`         |
| `kubernetesClusterDomain` | The Kubernetes cluster domain.                                                                                                                                                                                                                               | `cluster.local` |

## Cedana Configuration (`config`)

This section contains the core configuration for the Cedana platform.

### Authentication & Platform

| Parameter     | Description                                                                                                            | Default |
| ------------- | ---------------------------------------------------------------------------------------------------------------------- | ------- |
| `authToken`   | Your authentication token for the Cedana platform.                                                                     | `""`    |
| `url`         | The URL for the Cedana API.                                                                                            | `""`    |
| `clusterId`   | A unique ID for your cluster (you can generate one on the [Clusters Page](https://ui.cedana.com/monitoring/clusters)). | `""`    |
| `sqsQueueUrl` | The SQS queue URL for communication with Cedana.                                                                       | `""`    |

### Daemon Configuration

| Parameter  | Description                                                                                                                                                                                                                                                                | Default        |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
| `address`  | The address and port to bind the daemon on. Must be `0.0.0.0` for external accessibility.                                                                                                                                                                                  | `0.0.0.0:8080` |
| `protocol` | The protocol to use for daemon service. Options: `tcp` (TCP socket), `unix` (Unix socket), `vsock` (VSock for VM and hypervisor communication, useful for supporting VM-based migrations). **Note:** Other protocols might not be supported properly, update with caution. | `tcp`          |

### Checkpoint Storage & Streaming

| Parameter               | Description                                                                                                                                                                                                                                                                                                                                                                                    | Default |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `checkpointDir`         | Specify path to directory for storing checkpoints. Options: `cedana://<path>` for Cedana-managed global storage (recommended), `s3://<bucket>/<path>` for your S3 storage, `<path>` for node-local storage (not recommended, as it won't be accessible across nodes).                                                                                                                          | `/tmp`  |
| `checkpointStreams`     | Specify the number of parallel streams to use for streaming checkpoint/restore operations. `0` means no streaming. `n > 0` means n parallel streams (or number of pipes) to use. Streaming ensures a low footprint by using memory efficiently with no intermediate disk space required, although performance may be slightly better or worse depending on disk and network read/write speeds. | `0`     |
| `checkpointCompression` | The compression algorithm for checkpoints. Options: `none`, `tar`, `lz4`, `gzip`, `zlib`.                                                                                                                                                                                                                                                                                                      | `none`  |
| `checkpointAsync`       | Specify whether to perform checkpoint compression/upload async. Recommended if anticipating large checkpoints, which could take too long to stream directly to a bucket. Note that restore will only be possible after upload is complete, so there might be a delay before a workload can be restored even though the checkpoint shows as complete.                                           | `false` |

### GPU Configuration

| Parameter                  | Description                                                                                                                                 | Default                                       |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| `gpuPoolSize`              | Number of GPU controllers to keep warm. Improves GPU workload startup/restore time but uses more memory.                                    | `0`                                           |
| `gpuShmSize`               | The shared memory size for GPU workloads. 8 GiB is enough for most workloads. Reduce if memory constrained or running small workloads only. | `8589934592` (8 GiB)                          |
| `gpuLdLibPath`             | Additional `LD_LIBRARY_PATH` to look for CUDA libraries.                                                                                    | `/run/nvidia/driver/usr/lib/x86_64-linux-gnu` |
| `gpuSkipNvidiaRuntimeHook` | Whether to skip adding the nvidia-container-runtime hook when starting GPU workloads.                                                       | `false`                                       |

### Plugin Versions

| Parameter                         | Description                                                                                                                                                          | Default   |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- |
| `pluginsBuilds`                   | Specify the plugin versions to use. If set to `release`, then any release version for the plugins can be specified. If set to `alpha`, then specify the branch name. | `alpha`   |
| `pluginsNativeVersion`            | The version of the native plugin to use.                                                                                                                             | `latest`  |
| `pluginsCriuVersion`              | The version of the CRIU plugin to use.                                                                                                                               | `7/merge` |
| `pluginsContainerdRuntimeVersion` | The version of the containerd runtime plugin to use.                                                                                                                 | `v0.7.1`  |
| `pluginsGpuVersion`               | The version of the GPU plugin to use.                                                                                                                                | `v0.7.0`  |
| `pluginsStreamerVersion`          | The version of the streamer plugin to use.                                                                                                                           | `v0.0.8`  |

### Observability

| Parameter   | Description                | Default |
| ----------- | -------------------------- | ------- |
| `profiling` | Enable profiling.          | `true`  |
| `metrics`   | Enable metrics collection. | `true`  |
| `logLevel`  | The logging level.         | `info`  |

### AWS Configuration

| Parameter            | Description                                                                           | Default |
| -------------------- | ------------------------------------------------------------------------------------- | ------- |
| `awsAccessKeyId`     | AWS access key ID if using S3 storage (if `s3://<bucket>/<path>` in `checkpointDir`). | `""`    |
| `awsSecretAccessKey` | AWS secret access key if using S3 storage.                                            | `""`    |
| `awsRegion`          | AWS region if using S3 storage (uses default region if not set).                      | `""`    |
| `awsEndpoint`        | AWS endpoint if using S3-compatible storage.                                          | `""`    |

### Custom Secrets

| Parameter           | Description                                    | Default                              |
| ------------------- | ---------------------------------------------- | ------------------------------------ |
| `preExistingSecret` | Uncomment to use a custom pre-existing secret. | `cedana-secret-user` (commented out) |

## Host Configuration (`hostConfig`)

Configuration for host-level settings.

| Parameter           | Description                                                                                                          | Default                           |
| ------------------- | -------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
| `containerdAddress` | Path to containerd socket.                                                                                           | `/run/containerd/containerd.sock` |
| `disableIoUring`    | Set to `true` to disable Linux kernel's io-uring option. Cedana does not support io-uring based checkpoint restores. | `true`                            |

### Shared Memory Configuration (`hostConfig.shmConfig`)

Optional configuration to increase `/dev/shm` size on nodes, which is useful for workloads requiring large shared memory.

| Parameter | Description                                           | Default |
| --------- | ----------------------------------------------------- | ------- |
| `enabled` | Set to `true` to enable `/dev/shm` size increase.     | `false` |
| `size`    | Size to set for `/dev/shm` (e.g., `10G`, `20G`).      | `10G`   |
| `minSize` | Minimum size to trigger remount (e.g., `10G`, `20G`). | `10G`   |

## Daemon Helper (`daemonHelper`)

Configuration for the `daemon-helper` DaemonSet.

### Service

| Parameter             | Description                                      | Default |
| --------------------- | ------------------------------------------------ | ------- |
| `service.annotations` | Annotations to add to the daemon helper service. | `{}`    |

### Image

| Parameter               | Description                                    | Default                |
| ----------------------- | ---------------------------------------------- | ---------------------- |
| `image.repository`      | The repository for the image.                  | `cedana/cedana-helper` |
| `image.tag`             | The tag for the image.                         | `v0.9.284`             |
| `image.digest`          | The digest for the image (ignores tag if set). | `""`                   |
| `image.imagePullPolicy` | The image pull policy.                         | `IfNotPresent`         |

### Update Strategy

| Parameter                       | Description                                                                   | Default |
| ------------------------------- | ----------------------------------------------------------------------------- | ------- |
| `updateStrategy.maxSurge`       | The maximum number of pods that can be created over the desired number.       | `0`     |
| `updateStrategy.maxUnavailable` | The maximum number of pods that can be unavailable during the update process. | `99999` |

### Scheduling

| Parameter      | Description                                                                                                                                                                                      | Default                                                                |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------- |
| `tolerations`  | Tolerations for the daemon helper pods. Cedana uses the `cedana.ai/not-ready:NoSchedule` taint while the node is bootstrapping, then removes it once the helper and health-check pods are Ready. | Allows scheduling on nodes with `cedana.ai/not-ready:NoSchedule` taint |
| `affinity`     | Affinity settings for the daemon helper pods.                                                                                                                                                    | `{}`                                                                   |
| `nodeSelector` | Node selector for the daemon helper pods.                                                                                                                                                        | `{}`                                                                   |

## Service Account (`serviceAccount`)

Configuration for the Kubernetes Service Account.

| Parameter     | Description                                                                                                               | Default                     |
| ------------- | ------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
| `create`      | Specifies whether a service account should be created.                                                                    | `true`                      |
| `automount`   | Automatically mount a ServiceAccount's API credentials.                                                                   | `true`                      |
| `annotations` | Annotations to add to the service account.                                                                                | `{}`                        |
| `name`        | The name of the service account to use. If not set and `create` is true, a name is generated using the fullname template. | `cedana-controller-manager` |

## Controller Manager (`controllerManager`)

Configuration for the `cedana-controller-manager`.

### Autoscaling

| Parameter                                    | Description                                        | Default |
| -------------------------------------------- | -------------------------------------------------- | ------- |
| `autoscaling.enabled`                        | Enable autoscaling for the controller manager.     | `false` |
| `autoscaling.replicaCount`                   | The number of replicas for the controller manager. | `1`     |
| `autoscaling.deploymentRevisionHistoryLimit` | The number of old ReplicaSets to retain.           | `10`    |

### Service

| Parameter             | Description                                     | Default                                           |
| --------------------- | ----------------------------------------------- | ------------------------------------------------- |
| `service.annotations` | Annotations for the controller manager service. | `{}`                                              |
| `service.ports`       | The ports for the controller manager service.   | `[{protocol: TCP, port: 1324, targetPort: 1324}]` |

### Manager Configuration

| Parameter                          | Description                                                                                                                                                       | Default                                                                                      |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `manager.podAnnotations`           | Annotations for the controller manager pods.                                                                                                                      | `{}`                                                                                         |
| `manager.args`                     | Arguments for the controller manager container.                                                                                                                   | `[--health-probe-bind-address=:8081, --metrics-bind-address=127.0.0.1:8080, --leader-elect]` |
| `manager.containerSecurityContext` | The security context for the manager container. Controller doesn't require any privileges.                                                                        | `allowPrivilegeEscalation: false`, `capabilities: { drop: [ALL] }`                           |
| `manager.image.repository`         | The repository for the `cedana-controller` image.                                                                                                                 | `cedana/cedana-controller`                                                                   |
| `manager.image.tag`                | The tag for the `cedana-controller` image.                                                                                                                        | `v0.6.2`                                                                                     |
| `manager.image.digest`             | The digest for the image (ignores tag if set).                                                                                                                    | `""`                                                                                         |
| `manager.image.imagePullPolicy`    | The image pull policy.                                                                                                                                            | `IfNotPresent`                                                                               |
| `manager.resources`                | Resource limits and requests for the manager container. Empty to ensure minimal resource usage on demo/test deployments. Uncomment or add custom resource limits. | `{}`                                                                                         |

### RBAC Proxy

| Parameter        | Description                                                                                                                                                          | Default |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `rbac.resources` | Resource limits and requests for the RBAC proxy container. Empty to ensure minimal resource usage on demo/test deployments. Uncomment or add custom resource limits. | `{}`    |

### Scheduling

| Parameter      | Description                                                                                                                                                                                                                                                                                                                                                           | Default                                                                |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| `tolerations`  | Tolerations for the controller manager pods. Cedana uses the `cedana.ai/not-ready:NoSchedule` taint while the node is bootstrapping, then removes it once the helper and health-check pods are Ready. To deploy the controller on a dedicated node, run `kubectl taint node <node-name> dedicated=cedana-manager:NoSchedule` and uncomment the additional toleration. | Allows scheduling on nodes with `cedana.ai/not-ready:NoSchedule` taint |
| `affinity`     | Affinity settings for the controller manager pods. To allow scheduling of controller pod on labeled nodes only, use `kubectl label nodes <node-name> dedicated=cedana-manager` and uncomment the nodeAffinity configuration.                                                                                                                                          | `{}`                                                                   |
| `nodeSelector` | Node selector for the controller manager pods.                                                                                                                                                                                                                                                                                                                        | `{}`                                                                   |

## Metrics Service (`metricsService`)

Configuration for the metrics service.

| Parameter | Description                        | Default                                                         |
| --------- | ---------------------------------- | --------------------------------------------------------------- |
| `ports`   | The ports for the metrics service. | `[{name: https, port: 8443, protocol: TCP, targetPort: https}]` |
| `type`    | The type of the metrics service.   | `ClusterIP`                                                     |


# Installation

Begin checkpoint/migrate/restoring stateful workloads in SLURM in under 5 minutes!

{% hint style="success" %}
To use Cedana in SLURM, you need to be registered with us! Reach out to [founders@cedana.ai](mailto:foundes@cedana.ai) to get set up with an organization.
{% endhint %}

{% hint style="info" %}
You can also deploy fully self-hosted, with zero limitations on where you can store your checkpoints! Check out [configuration](https://docs.cedana.ai/daemon/get-started/configuration). If you have any questions, please reach out to us at <founders@cedana.ai>.
{% endhint %}

You can install Cedana on a SLURM node in 3 ways:

1. \[Option 1]  [#install-from-web-recommended](#install-from-web-recommended "mention")
2. \[Option 2] [#install-using-cedana](#install-using-cedana "mention")
3. \[Option 3] [#build-from-source](#build-from-source "mention")

{% hint style="warning" %}
These steps must be performed on **a SLURM controller and one compute node minimum**. Other compute nodes without Cedana can continue to functional normally without checkpoint/restore capability.
{% endhint %}

{% hint style="warning" %}
The installer restarts the `slurmctld` , `slurmd` daemons on the controller and compute nodes after successful completion. This may cause a short disruption in job submission capability.
{% endhint %}

## Install from web (recommended)

The web installer will automatically install the latest stable version of Cedana and all plugins required for SLURM support with sane defaults.

### Install

{% hint style="success" %}
Check [Authentication](/get-started/authentication) for more details on how to get an authentication token.
{% endhint %}

```sh
export CEDANA_URL=https://myorg.cedana.ai/v1
export CEDANA_AUTH_TOKEN=your_auth_token
export CEDANA_CLUSTER_ID=your_cluster_id

curl -fsSL "${CEDANA_URL}/install/slurm" -H "Authorization: Bearer ${CEDANA_AUTH_TOKEN}" | sudo -E bash -s -- --node-role <node-role>
```

* Register a new cluster through [Cedana Dashboard](https://ui.cedana.com/slurm/clusters).
* Use `?version=x.y.z` query parameter to install a specific version.
* Use `?build=alpha&version=feat/my-branch` to install an alpha build from a branch.
* Use `--node-role controller` on controller nodes, `--node-role worker` on worker nodes, and `--node-role login` on login (submission) nodes.

### Configure

For changes in configuration, follow instructions on [Cedana Daemon configuration](https://docs.cedana.ai/daemon/get-started/configuration).&#x20;

After you have made changes to the configuration, simply run the installer again to update and restart Cedana on the node.

```sh
export CEDANA_URL=https://myorg.cedana.ai/v1
export CEDANA_AUTH_TOKEN=your_auth_token

curl -fsSL "${CEDANA_URL}/install/slurm" -H "Authorization: Bearer ${CEDANA_AUTH_TOKEN}" | sudo -E bash -s -- --node-role <node-role>
```

And you're all set! Check out [Manual Checkpoint/Restore](/cedana-slurm/cr) to test it out. Below sections are on the alternative methods to install Cedana SLURM.

## Install using Cedana

You can also install SLURM support directly using Cedana, if you have Cedana already installed.

### Install

First, install Cedana by following instructions on [Cedana Daemon installation](https://docs.cedana.ai/daemon/get-started/installation).

{% hint style="success" %}
Check [Authentication](/get-started/authentication) for more details on how to get an authentication token.
{% endhint %}

Then, install the `slurm` plugin and run the setup:

```sh
export CEDANA_URL=https://myorg.cedana.ai/v1
export CEDANA_AUTH_TOKEN=your_auth_token
export CEDANA_CLUSTER_ID=your_cluster_id

sudo cedana plugin install slurm
sudo cedana slurm setup --node-role <node-role>
```

* Register a new cluster through [Cedana Dashboard](https://ui.cedana.com/slurm/clusters).
* Use `--node-role controller` on controller nodes, `--node-role worker` on worker nodes, and `--node-role login` on login (submission) nodes.

This should setup everything required. If you wish to setup manually, follow the [next section](#install-manual).

### Install (manual)

For deployments that require installing the plugin files manually, you can download the files directly.

First, install Cedana by following instructions on [Cedana Daemon installation](https://docs.cedana.ai/daemon/get-started/installation).

{% hint style="success" %}
Check [Authentication](/get-started/authentication) for more details on how to get an authentication token.
{% endhint %}

To get the Cedana SLURM plugin:

```sh
export CEDANA_URL=https://myorg.cedana.ai/v1
export CEDANA_AUTH_TOKEN=your_auth_token
export CEDANA_CLUSTER_ID=your_cluster_id

sudo cedana version --init-config
sudo cedana plugin remove slurm slurm/wlm
sudo cedana plugin install slurm slurm/wlm
```

For `alpha` builds:

```sh
export CEDANA_URL=https://myorg.cedana.ai/v1
export CEDANA_AUTH_TOKEN=your_auth_token
export CEDANA_CLUSTER_ID=your_cluster_id
export CEDANA_PLUGINS_BUILDS=alpha

sudo cedana version --init-config
sudo ./cedana plugin remove slurm slurm/wlm
sudo ./cedana plugin install slurm@main slurm/wlm@main-slurm-25-11-5-1
```

This will download the `cedana-slurm` binary to `/usr/local/bin` and the SLURM plugin files to `/usr/local/lib`. Remember to replace the `slurm-25-11-5-1` above with the SLURM version your cluster is running.&#x20;

To install the files, transfer the files to the required directories:

```sh
# install to the worker nodes (slurmd), controller nodes (slurmctld), and the database node (slurmdbd)
sudo install /usr/local/bin/cedana-slurm <binary-directory>/cedana-slurm
sudo install /usr/local/lib/cli_filter_cedana.so <slurm-plugin-directory>/cli_filter_cedana.so
sudo install /usr/local/lib/job_submit_cedana.so <slurm-plugin-directory>/job_submit_cedana.so
sudo install /usr/local/lib/task_cedana.so <slurm-plugin-directory>/task_cedana.so
sudo install /usr/local/lib/spank_cedana.so <slurm-plugin-directory>/spank_cedana.so
```

Update the `/etc/slurm/plugstack.conf` to include the `spank_cedana.so:`

```diff
+required <slurm-plugin-directory>/spank_cedana.so
```

Update the `/etc/slurm/slurm.conf` to include the plugins:

```diff
-TaskPlugin=task/affinity,task/cgroup
+TaskPlugin=task/affinity,task/cgroup,task/cedana
+CliFilterPlugins=cli_filter/cedana
+JobSubmitPlugins=job_submit/cedana
```

Reload the `slurmctld` and `slurmd` with:

```sh
sudo systemctl restart slurmctld
sudo systemctl restart slurmd
```

On the database node (`slurmdbd`), start `cedana-slurm:`

```sh
sudo cedana-slurm daemon
```

Or, if you are using systemd, create the service file:

```sh
export LOG_PATH=/var/log/cedana-slurm.log
export SERVICE_FILE=/etc/systemd/system/cedana-slurm.service
export APP_PATH=/usr/local/bin/cedana-slurm

cat <<EOF | tee "$SERVICE_FILE" >/dev/null
[Unit]
Description=Cedana Daemon
[Service]
ExecStart=$APP_PATH daemon start
User=root
Group=root
Restart=no

[Install]
WantedBy=multi-user.target

[Service]
StandardError=append:$LOG_PATH
StandardOutput=append:$LOG_PATH
EOF
```

### Configure

For changes in Cedana configuration, follow instructions on [Cedana Daemon configuration](https://docs.cedana.ai/daemon/get-started/configuration).

## Build from source

Check `make help` for available build targets.

Build all binaries:

```sh
make all
```

By default, the binaries will be built using the `cedana/cedana-slurm:build` docker image.

These binaries are useless on their own. You need to install Cedana to use them.

First, install Cedana by following instructions on [Cedana Daemon installation](https://docs.cedana.ai/daemon/get-started/installation). Then, install the `slurm` plugin after changing into the build directory:

```sh
cd build
sudo cedana plugin install slurm
sudo cedana slurm setup --node-role <node-role>
```

{% hint style="info" %}
You need to be in the `build` directory for the `cedana slurm setup` command to work, as it needs to find the binaries you just built.
{% endhint %}

{% hint style="success" %}
Check [Authentication](/get-started/authentication) for more details on how to get an authentication token.
{% endhint %}

You're all set up! Let's checkpoint some workloads. Continue to [Checkpoint/restore](/cedana-slurm/cr) to get started.

## Uninstall

To remove Cedana SLURM completely, run on all nodes:

```sh
sudo cedana slurm destroy
```


# Unprivileged Mode (non-root)

By default, the checkpointing and restoring of a SLURM job is done as root. Root user has all the capabilities required for performing a complete checkpoint/restore of a process. This is often though an issue for SLURM sysadmins depending on the installation site.&#x20;

To address this, Cedana supports unprivileged mode, where the checkpointing and restoring are done as the job's user, i.e., the UID of the SLURM job performs the checkpoint and restore. This configuration is useful when the root is demoted for security purposes. For example, NFS with `root_squash` requires unprivileged mode.

To enable unprivileged mode, set `Slurm.Unprivileged` to `true` in the [Cedana Daemon configuration](https://docs.cedana.ai/daemon/get-started/configuration) on all the compute/worker nodes. Otherwise, just do this on each compute/worker node:

```sh
export CEDANA_SLURM_UNPRIVILEGED=true

sudo cedana version --merge-config
```

In addition, the `criu` binary must have the right capabilities set. There are two ways to go about this:&#x20;

* `sudo setcap cap_sys_ptrace,cap_checkpoint_restore=eip "$(command -v criu)"` , which sets `cap_sys_ptrace` and `cap_checkpoint_restore` on the criu binary.&#x20;
* Setting *only `cap_checkpoint_restore` ,* which would require setting an additional kernel configuration

The recommended configuration is the former.&#x20;


# Manual Checkpoint/Restore

Begin checkpoint/migrate/restoring stateful workloads in SLURM in under 5 minutes!

## Deploy

For both CPU and GPU workloads, no additional configuration is required. Below is an example of a simple CPU workload that counts from 0 to 600, sleeping for 1 second between each count. By default, Cedana must be enabled to checkpoint SLURM jobs by adding the `CEDANA_ENABLE=1` environment variable.

{% code title="counting.sbatch" lineNumbers="true" %}

```bash
#!/bin/bash
#SBATCH --job-name=hello_world          # Job name
#SBATCH --output=hello_world.out        # Standard output log
#SBATCH --error=hello_world.err         # Standard error log
#SBATCH --time=00:10:00                 # Time limit (hh:mm:ss)
#SBATCH --nodes=1                       # Run on 1 node
#SBATCH --ntasks=1                      # Run 1 task
#SBATCH --export=CEDANA_ENABLE=1        # Enable Cedana

echo "Starting counter job on $(hostname)..."

# Loop from 0 to 600
for i in {0..600}
do
    echo "Counter: $i"
    sleep 1
done

echo "Job finished successfully."
```

{% endcode %}

Submit the job using `sbatch` .

```shellscript
sbatch counting.sbatch
```

## Checkpoint

<figure><img src="/files/kTl4xNS1kTMg7WfAybgl" alt=""><figcaption></figcaption></figure>

To checkpoint a job in SLURM, navigate to the [SLURM Jobs Page](https://ui.cedana.com/slurm/jobs), select the job, and checkpoint it.

Feel free to kill the job now by using `scancel`.

```shellscript
scancel <jobid>
```

## Restore

<figure><img src="/files/o481NkjkpGElQxal6CFh" alt=""><figcaption></figcaption></figure>

To restore a job in SLURM, navigate to the [SLURM Checkpoints Page](https://ui.cedana.com/slurm/checkpoints), select a checkpoint, and restore it.

Check `squeue` to confirm the job is running again, and verify that it was resumed from where it was checkpointed by checking the output file `hello_world.out`.

```shellscript
squeue
```


# Automatic Checkpoint/Restore

Automating checkpoint/restore with SLURM

In most cases, the end user will likely *not* be using the UI to manually checkpoint/restore workloads. Cedana offers seamless automation for SLURM workloads.

## Preemption-based

Let's deploy a sample SLURM job and cause a preemption to test out Cedana's preemption-based automation. In short, a job will be automatically checkpointed on preemption and resumed when it starts running again after being re-queued by SLURM (if configured to).

{% hint style="info" %}
Below example assumes your SLURM cluster/partition is configured with `PreemptMode=REQUEUE` and `PreemptType=preempt/partition_prio`. Check out [SLURM preemption](https://slurm.schedmd.com/preempt.html) for more information.
{% endhint %}

For simplicity, we have two partitions `debug` and `high` overlapping on the same compute node. `high` has higher priority tier than `debug`. The configuration looks like:

```
PreemptType=preempt/partition_prio
PreemptMode=REQUEUE
SchedulerParameters=preempt_reorder_count=100,preempt_strict_order

PartitionName=debug Nodes=compute-01 Default=YES MaxTime=INFINITE State=UP PreemptMode=REQUEUE PriorityTier=1 GraceTime=15
PartitionName=high  Nodes=compute-01 MaxTime=INFINITE State=UP PreemptMode=REQUEUE PriorityTier=2
```

{% hint style="success" %}
`GraceTime` of 15 seconds on the `debug` partition allows Cedana plenty of time to perform a checkpoint on the job before it gets completely evicted/killed.
{% endhint %}

### Deploy victim

Below is an example CPU workload that we will use as our preemption victim. By default, Cedana must be enabled to checkpoint this job by adding the `CEDANA_ENABLE=1` environment variable. Additionally, you must set `CEDANA_CHECKPOINT=<label name>` to label all checkpoints of this workload. So that when this workload is restored, the latest checkpoint from this label is automatically used.

{% code title="victim.sbatch" lineNumbers="true" %}

```bash
#!/bin/bash
#SBATCH --job-name=victim                    # Job name
#SBATCH --output=victim.out                  # Standard output log
#SBATCH --error=victim.err                   # Standard error log
#SBATCH --time=00:10:00                      # Time limit (hh:mm:ss)
#SBATCH --nodes=1                            # Run on 1 node
#SBATCH --ntasks=1                           # Run 1 task
#SBATCH --export=CEDANA_ENABLE=1             # Enable Cedana
#SBATCH --export=CEDANA_CHECKPOINT=victim    # Label for all checkpoints

echo "Starting victim job on $(hostname)..."

# Loop from 0 to 600
for i in {0..600}
do
    echo "Counter: $i"
    sleep 1
done
```

{% endcode %}

Submit the victim to the `debug` (low priority) partition on your node using `sbatch`.

```shellscript
sbatch -p debug -w compute-01 victim.sbatch
```

### Deploy preemptor

The preemptor job can be any job submitted to the `high` partition (higher priority than `debug`) as long as it occupies all the CPUs available on the node. This ensures SLURM preempts any low partition jobs before deploying this job.

{% hint style="info" %}
Use `nproc` to find number of CPUs on your node.
{% endhint %}

{% code title="preemptor.sbatch" lineNumbers="true" %}

```shellscript
#!/bin/bash
#SBATCH --job-name=preemptor                 # Job name
#SBATCH --output=victim.out                  # Standard output log
#SBATCH --error=victim.err                   # Standard error log
#SBATCH --time=00:10:00                      # Time limit (hh:mm:ss)
#SBATCH --nodes=1                            # Run on 1 node
#SBATCH --ntasks=1                           # Run 1 task

echo "Starting preemptor job on $(hostname)..."

# Loop from 0 to 600
for i in {0..600}
do
    echo "Counter: $i"
    sleep 1
done
```

{% endcode %}

Note that this job *does not* need any `CEDANA_` environment variable as we don't need it to be checkpointed.

Submit the preemptor to the `high` partition on your node using `sbatch`, ensuring it occupies all the CPUs available on the node. In this example, `compute-01` has 4 CPUs.

```shellscript
sbatch -p high -w compute-01 --cpus-per-task=4 preemptor.sbatch
```

You should be able to see that our victim job has been preempted and re-queued onto the node (in pending `PD` state), while our preemptor job is freely running. Check the queue using `squeue`.

```
JOBID PARTITION        NAME     USER ST       TIME  NODES NODELIST(REASON)
  182     debug      victim     root PD       0:00      1 (BeginTime)
  183      high   preemptor     root  R       0:02      1 compute-01
```

### Restore

Now let's restore our victim job. All we need to do is `scancel` our preemptor job or wait for it to finish running.

Cancel the higher priority job using `scancel`.

```shellscript
scancel 183
```

After some time, the victim job should resume running on the node. Check the output file `victim.out` to verify that it was resumed from where it was preempted!

{% hint style="warning" %}
If for some reason, a checkpoint could not be taken during preemption, the job should simply start fresh. This can happen if the `GraceTime` on the partition is not sufficient for the size of the job. Alternatively, any older available checkpoints will be restored. Check out [#policy-based](#policy-based "mention") automation for taking regular checkpoints.
{% endhint %}

## Policy-based

Let's deploy a sample SLURM job and explore Cedana's policy-based automation for checkpoint/restore.

### Deploy

Below is an example CPU workload that counts from 0 to 600, sleeping for 1 second between each count. By default, Cedana must be enabled to checkpoint this job by adding the `CEDANA_ENABLE=1` environment variable.

<pre class="language-bash" data-title="counting.sbatch" data-line-numbers><code class="lang-bash"><strong>#!/bin/bash
</strong>#SBATCH --job-name=counting                  # Job name
#SBATCH --output=counting.out                # Standard output log
#SBATCH --error=counting.err                 # Standard error log
#SBATCH --time=00:10:00                      # Time limit (hh:mm:ss)
#SBATCH --nodes=1                            # Run on 1 node
#SBATCH --ntasks=1                           # Run 1 task
#SBATCH --export=CEDANA_ENABLE=1             # Enable Cedana
#SBATCH --export=CEDANA_CHECKPOINT=counting  # Label for all checkpoints

echo "Starting counter job on $(hostname)..."

# Loop from 0 to 600
for i in {0..600}
do
    echo "Counter: $i"
    sleep 1
done
</code></pre>

Additionally, you must set `CEDANA_CHECKPOINT=<label name>` to label all checkpoints of this workload. So that when this workload is restored, the latest checkpoint from this label is automatically used.

Submit the job using `sbatch`.

```bash
sbatch counting.sbatch
```

### Configure policy

You may now take [manual checkpoints](/cedana-slurm/cr) of this workload or configure an automation policy.&#x20;

1. Head over to the [SLURM Policies Page](https://staging.cedana.com/slurm/policies) and click on "Create Policy".<br>

   <figure><img src="/files/NQIv1Dk08QBnXueDSG4c" alt=""><figcaption></figcaption></figure>
2. Set a unique name for this policy and select a checkpoint interval.
3. Select the job to apply this policy to and click on "Create Policy".

You should start seeing new checkpoints of your job on the [SLURM Checkpoints Page](https://ui.cedana.com/slurm/checkpoints).

### Restore

As soon as a checkpoint is available, you should be able to cancel your job using `scancel`.&#x20;

```bash
scancel <jobid>
```

{% hint style="info" %}
Cancellation should also trigger an automatic checkpoint if the `GraceTime` in your SLURM configuration allows sufficient time for a checkpoint to be taken.
{% endhint %}

Simply submit the job again using `sbatch`. You will notice that the job will automatically resume from the latest checkpoint instead of starting fresh.


# Cedana + Dynamo for Inference at Scale

#### Why Cedana + Dynamo?

NVIDIA [Dynamo](https://github.com/ai-dynamo/dynamo) offers SOTA inference serving at scale, designed to enhance the performance of LLM inference. By leveraging advanced optimization techniques and dynamic scheduling, Dynamo significantly accelerates inference workloads.

Dynamo's architecture is built on the modular disaggregation of the prefill and decode phases, allowing each to be scaled independently on hardware best suited for their specific compute or memory profiles.

Its core components include:

* a Smart Router that uses Radix Tree indexing to track KV-cache locality across the cluster, ensuring requests land on workers that already hold relevant context.
* the KV Block Manager (KVBM) (for large caches) offloads cache data across a storage hierarchy of host DRAM, SSDs, and network storage
* NVIDIA Inference Transfer Library (NIXL), which enables zero-copy, asynchronous KV cache migration at near-memory speeds

And more! See their [Core Capabilities](https://github.com/ai-dynamo/dynamo?tab=readme-ov-file#core-capabilities) section in the docs for all the features Dynamo offers.

What makes Dynamo incredibly compelling is that it's a fast-moving project, keeping track of developments in research and the field to bring frontier-lab level performance to users with access to clusters of GPUs, both in datacenters and the cloud.

However some challenges still remain with using a tool like Dynamo that an integration with Cedana solves!

* **Cold Start Times:** Cold starts won't generally go away, even with infrastructure optimizations like Dynamo presents as the weights still need to be downloaded and loaded into GPU memory for a worker or set of workers. Model initialization for large models like Llama-3-70B can exceed 80 seconds. Cedana solves this by restoring "ready-to-serve" Dynamo workers from checkpoints, enabling new replicas to come online 10x faster than a native cold start.
* **A Recompute Tax**: In long-context agentic sessions, losing a decode worker node results in the total loss of its in-memory KV cache. To resume, a new node must pay a "recompute tax", re-running the expensive prefill phase which can take 10+ seconds and waste significant GPU cycles. Cedana provides system-level Save, Migrate, and Resume (SMR) capabilities that transparently capture the exact state of the GPU and CPU memory, allowing generation to resume from the very next token without re-prefilling the context (or regenerating the KV-Cache!).
* **Resilience:** Dynamo's stateful nature makes it difficult to run reliably on high-volatility, low-cost infrastructure like spot nodes. Cedana integrates with cloud-native schedulers to monitor preemption notices and live-migrate active inference tasks to healthy nodes before they are terminated.


# Deploying with Dynamo

#### Deploying Cedana + Dynamo

The good news is that Cedana just works with Dynamo! You can follow this guide on setting up Cedana on your Kubernetes cluster: [Installation](/cedana-kubernetes/installation), and follow this to setup Dynamo on your cluster: <https://docs.nvidia.com/dynamo/v1.0.1/kubernetes-deployment/deployment-guide>.

Dynamo requires another controller from the cedana side, so in your helm values.yml you'll need to add the following config:<br>

```
# Only enable on clusters that have NVIDIA Dynamo (DynamoGraphDeployment CRD) installed.
dynamo:
  enabled: true
  image:
    repository: cedana/cedana-dynamo-watcher
    tag: main
    digest: # ignores tag if set
    imagePullPolicy: IfNotPresent
  resources: {}
  tolerations:
    - key: "cedana.ai/not-ready"
      operator: "Exists"
      effect: "NoSchedule"
  affinity: {}
  nodeSelector: {}
metricsService:
  ports:
    - name: https
      port: 8443
      protocol: TCP
      targetPort: https
  type: ClusterIP

```

Once set up, you can manage your dynamo deployment via our UI:

<figure><img src="/files/x2rKisdliQGF8qb7wHJY" alt=""><figcaption></figcaption></figure>


# Performance of Cedana's GPU Interception

Gain 11% inference throughput and 10x faster cold starts, with minimal overhead

## GPU Interception

Checkpointing and restoring a process or container that uses an NVIDIA GPU is a complex task. It requires low-level access to the driver, which is challenging due to the proprietary nature of NVIDIA's drivers. To overcome this, Cedana interposes at the Driver API while the process is running. This approach enables Cedana to reliably, transparently, and deterministically capture and restore GPU state — even for multi-GPU workloads or workloads scattered across several machines — while also enabling live migration.

While this could theoretically introduce performance overhead, Cedana minimizes this cost by using a bag of low-level tricks. Our optimizations effectively turn Cedana into a virtual machine for NVIDIA GPUs. By operating at our level (rather than the higher-level CUDA runtime or at the application layer) Cedana gains deep visibility into GPU operations. This enables advanced optimizations in real time, such as merging CUDA graph API calls, eliminating redundant operations and more — almost functioning as a [just-in-time (JIT) compiler](https://en.wikipedia.org/wiki/Just-in-time_compilation) for GPUs.

Moreover, GPU workloads often involve the CPU idling while waiting for GPU tasks to complete. Because Cedana still runs on the CPU, its overhead is frequently hidden or amortized over time — often resulting in no measurable cost at all.

In practice, the performance overhead from Cedana’s GPU interception is minimal, and in some cases, even improves performance. Below are benchmarks that demonstrate this in more detail.

Performance is a moving target, and Cedana's goal is to get to native or better — so check back in for regular updates!

## Benchmarks

The benchmarks list below were run on a range of machines:

1. **Intel Zeon Platinum 8480+ CPU** with an **NVIDIA H100 PCIe GPU**
2. **AMD EPYC 7R13 CPU** with an **NVIDIA L4 GPU**
3. **AMD EPYC 7J13 CPU** with an **NVIDIA A100 SXM4 GPU**

*Complete system specifications can be found at the top-right corner of each image.*

### Raw Performance <a href="#docs-internal-guid-79d54ed3-7fff-b8bb-5f63-9e2b8bc68a42" id="docs-internal-guid-79d54ed3-7fff-b8bb-5f63-9e2b8bc68a42"></a>

Benchmarks that measure raw GPU performance — such as memory bandwidth (in-device) and compute throughput — show minimal overhead of **3%** with Cedana.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXebE7jdBIV6F8E8ksrceGdwX58Pcn2m_DoVeDbTuRtihy5Zj1hPZN9qztNniay_OsHalqnR9Z2gleUl2OXbErQ4cDslHOzSckmBTkWEeDppy-RmZedJzOpTfJv0yTUBNWxcIVJp?key=lQWWVZpH0lEmynIqt5H93--6" alt=""><figcaption><p>Memory throughput (GPU)</p></figcaption></figure>

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXf4BwktYYPfES05GBTfSvu0Tdz1srATHe4cKLuNTiEJlY8uh6gA5p5eWAAKUPvG2WLI_Kv9Ndaz8WdxE-GEteZNYWXOuquJwoqqUmfY43PhYlAgT7Iv_imZgvdD3Ng8wVaqNH38?key=lQWWVZpH0lEmynIqt5H93--6" alt=""><figcaption><p>Compute throughput (GPU)</p></figcaption></figure>

These workloads rely almost entirely on the GPU, with minimal CPU involvement. Since Cedana’s interception introduces only a small CPU-side cost, it has minimal impact on these GPU-bound benchmarks, as expected. These were run on an **AMD EPYC 7R13 CPU** with an **NVIDIA L4 GPU** (full spec in top-right of the image).

The benchmark below measures the time taken to concurrently launch multiple kernels. Even under this concurrent load, the observed overhead was about **3%**. This was run on an **Intel Zeon Platinum 8480+ CPU** with an **NVIDIA H100 PCIe GPU** (full specs shown in the top-right corner of the image).

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXcA-T2awSPIqIfIMZnhcGDX7NUs1hDRC7wzeoXT_qAm3Ps-IbciLS9bqkJPza91HJc4QolLMS7jOxPz-UUjVom_aOq3HPmPvDgqtuLlpvcaHxuDM9YEC0TbzrPGmmRo__hzYENY?key=lQWWVZpH0lEmynIqt5H93--6" alt=""><figcaption><p>Concurrent kernels execution duration</p></figcaption></figure>

### Memory Bandwidth

When performing memory transfers to/from the GPU, interception could, in theory, introduce some overhead. However, Cedana is designed to preserve the performance of these operations.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXf8ulH541v4iTX6Lu79DcUIom3-6dUZjxOlApWNTGG7l3FH9qRBRpCX7W7d86HoRL3yP6rTUf_gWkSn6hvCa77s9fcRUe8xYmFVvB7RGsnEV6F1t_KAYmgLoPrbixhZa7L6gY0?key=lQWWVZpH0lEmynIqt5H93--6" alt=""><figcaption><p>Memory throughput (GPU to host)</p></figcaption></figure>

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXcep2t0Qb3qYWKw-_SVpVZgbdRnebpnmh0uRZIuH6DIwAdjVRF31TzryiRqzjk6dt_3m_g7tw1gzRf9OJo2zMwMVrMcYeD4j9mFwZvdM5j-dO3Ab92w40AQNiocmm1MVRlUjSiA?key=lQWWVZpH0lEmynIqt5H93--6" alt=""><figcaption><p>Memory throughput (host to GPU)</p></figcaption></figure>

There is minimal degradation observed for small-sized memory transfers, where the overhead of interception can accumulate due to the higher number of CUDA calls. These were run on an **Intel Zeon Platinum 8480+ CPU** with an **NVIDIA H100 PCIe GPU** (full specs shown in the top-right corner of the image).

### Training Overhead

As mentioned earlier, for longer-running workloads, the interception overhead is largely amortized. This is because most GPU workloads involve the CPU waiting idly for the GPU to complete its tasks, making the CPU-side cost negligible over time. First, we measured the overhead of each training iteration as we increased the model size. The overhead seemed to increase with model size.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXe1uMDY59e9IG2QQ1eZ68jJzkG1QM3GmAEafM2jlJNjaZjq0bYK5Hi11IzMXZULEL_J3c97LpKbeMH2DVHv4y9TOBOsMcN60c0-9e33WwseT23jzciXucaXYCYuoCOU4nRftrhD?key=lQWWVZpH0lEmynIqt5H93--6" alt=""><figcaption><p>ML training time per iteration</p></figcaption></figure>

On the other hand, when we measure the overhead over time for a model size of 120 million parameters, if the training is continued to run, we observe a total overhead of just **1.3%**, likey due to amortization. With some of our planned work on the horizon, our goal is to get this to < **0.1**%.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXeWXQ3TJObWpGVfWGVRQJac5l6FMHiFCcXRJVtOR2g-AUm0m6U_3D_YZIZ7PJNpCj1LCursXc_iCpa7KpGgGoQwAfEmtNG3xraR-i0VPDdNqg26LYgGSRhpOkPLhUfSyEJAnrXL?key=lQWWVZpH0lEmynIqt5H93--6" alt=""><figcaption><p>ML training time</p></figcaption></figure>

These were run on an **AMD EPYC 7R13 CPU** with an **NVIDIA L4 GPU** (full specs shown in the top-right corner of the image).

### Inference Overhead

Below are the results from running [this benchmark](https://github.com/vllm-project/vllm/blob/main/benchmarks/benchmark_throughput.py) on a *LLaMa 3.1 8B* model comparing runtime throughput of using Cedana with native.

| Throughput      | Native  | Cedana  |
| --------------- | ------- | ------- |
| Requests/s      | 11.69   | 13.85   |
| Total tokens/s  | 4833.43 | 5725.69 |
| Output tokens/s | 2318.23 | 2746.18 |

Runtime throughput when running with Cedana is about **11% faster**. Any overhead has been mitigated by optimizations that are only possible due to the asynchronous design of our GPU virtual machine. This design allows the GPU controller to make decisions before actually executing CUDA driver API calls.

These were run on an **AMD EPYC 7J13 CPU** with an **NVIDIA A100 SXM4 GPU**.

### Cold Start Time

Inference cold starts can be greatly reduced when restoring from a checkpoint. Here we compare cold starts with restored starts of NVIDIA’s CUDA C/R (light grey) and Cedana (blue).

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXcs6W_hCiZ0CHfCOAMKl3H3wQmzDVI5rsWLbeR5RFiNOGBHKaj-xHF4iuBWZ-AUMFk-AAL98CKlmy9Vj3uvSM7fixQC9CFG3X1w8HyxmKiLRRBuUQy_f1ERM8ZLuT-n6nVfLc9V?key=lQWWVZpH0lEmynIqt5H93--6" alt=""><figcaption><p>Cold start time (smaller models)</p></figcaption></figure>

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXcVJ3Czfl5p9KuC7fEpxGqRjTFCFQIt9T6__aF5qNBgokXhSUWK4su8nVIwCuKhTkqkPTtEnIJZxDTvWeYLytpoiLX9oL4xEtbGJSiOTanpeiG0amgxyJRkQ6K2m9toEG_Ru2NL?key=lQWWVZpH0lEmynIqt5H93--6" alt=""><figcaption><p>Cold start time (larger models)</p></figcaption></figure>

Cedana’s restored cold starts are an order of magnitude faster than native cold starts. In the case of larger models (as shown in the second image), Cedana’s cold start times remain nearly constant, regardless of model size. This is likely due to saturation of the GPU’s memory bandwidth, while being bottlenecked by a large fixed component of the total time. In contrast, restores using NVIDIA’s CUDA checkpoint/restore (C/R) show little to no improvement over native cold starts for most larger models. These were run on an **Intel Xeon Platinum 8480+ CPU** with an **NVIDIA H100 PCIe GPU** (full specs shown in the top-right corner of the image).

## Conclusion

The overhead introduced by Cedana’s GPU interception is minimal — typically in the range of **1–3%**. In some cases, it can even result in performance gains (see [Inference Overhead](#inference-overhead)). Overall, the benefits enabled by Cedana, such as live migration and significantly faster cold starts, often far outweigh the costs.


# Cedana vs. CRIUgpu for GPU Checkpoint/Restore

We benchmark our SOTA GPU checkpoint/restore solution against CRIU’s CUDA plugin that’s based on NVIDIA’s CUDA Driver functionality

## GPU Checkpoint/Restore

Until 2024, checkpoint/restore of GPUs was only possible through some form of interception, either at the CUDA runtime API or driver API level. In April 2024, NVIDIA released [native support for checkpoint/restore](https://developer.nvidia.com/blog/checkpointing-cuda-applications-with-criu/) for their GPUs. A recent paper, [CRIUgpu: Transparent Checkpointing of GPU-Accelerated Workloads](https://arxiv.org/abs/2502.16631), benchmarks the CRIU CUDA plugin that makes use of[ NVIDIA’s CUDA checkpoint utility](https://github.com/NVIDIA/cuda-checkpoint) to enable checkpoint/restore of GPUs-enabled processes using CRIU. This paper highlights valid issues with traditional GPU checkpoint/restore solutions that are based on interception.

At Cedana, we've been developing our own GPU checkpoint/restore solution through GPU virtualization. In this article, we compare our solution with the new CRIU CUDA plugin and also highlight the unique benefits enabled through virtualization & interception.

You can try out both our interception-based GPU checkpoint/restore and CRIU CUDA checkpoint/restore using the [cedana](https://docs.cedana.ai/daemon/) daemon. Check out [checkpoint/restore with GPUs](/daemon/checkpoint-restore/cr-1) for more info.

## Benchmarks

We benchmarked our [GPU checkpoint/restore](broken://spaces/Su8hW4oAhjiIohf3AFfl/pages/ieK7Li9lPJmOK4Jjfpem#usage-gpu-plugin) against the [CRIU CUDA checkpoint/restore](https://arxiv.org/abs/2502.16631) on model inferencing across some popular large language models (LLMs), such as GPT2, LLaMa3, StableLM, Gemma 2 and more. Our customers generally cared about the following, which we collected data on:

1. **Warm checkpoint time**: Time it takes to checkpoint warmed-up inference jobs, i.e. when the model is fully loaded onto the GPU.
2. **Cold start time**: Time it takes to cold-start inferencing (also known as Time To First Token).
3. **Save migrate resume**: Total time taken to checkpoint, migrate across network, and restore on another machine.
4. **vLLM throughput**: Runtime throughput performance as measured in this [vLLM benchmark](https://github.com/vllm-project/vllm/blob/main/benchmarks/benchmark_throughput.py).

Setup information (environment and machine specs) can be found at the [bottom of the page](#setup).

Each reading taken in the benchmarks below is calculated by taking a **minimum of 3 samples**.

### Cold Start Time

For this benchmark, we also include native cold start time as a baseline (or, time to first token when running natively).

Below, you can see results for smaller models (GPT2). Leftmost bars (gray) are native cold starts (without checkpoint/restore), middle bars (light blue) are cold starts using CRIU CUDA, and rightmost bars (blue) are cold starts using Cedana.

<figure><img src="/files/WwKjokP21NQLd0GfnyiU" alt=""><figcaption><p>Cold start time (time to first token, on GPT2 models)</p></figcaption></figure>

For larger models, we observe similar results. Cedana cold starts (blue) are the fastest. CRIU CUDA cold starts for these larger models are even slower than native cold starts. For the models *gemma-2-9b*, and *stablelm-2-12b*, CRIU CUDA checkpoint failed for every sample so there is no reading to show. *Update: this is a known CRIU issue that was recently fixed, but unreleased when the readings were taken.*

<figure><img src="/files/KAewuKyoB7T4yLFNaYjG" alt=""><figcaption><p>Cold start time (time to first token, on popular LLMs)</p></figcaption></figure>

### Warm Checkpoint Time

Below, you can see the results for smaller models (GPT2). Left bars (dark gray) are CRIU CUDA checkpoint times, right bars (light gray) are Cedana checkpoint times.

There is also an overlay plot in the same figure, comparing checkpoint throughputs (right y-axis for values). The topmost line (gray) is the maximum possible throughput (disk write speed), middle line (blue) is throughput observed when using Cedana, lowermost line (dark blue) is throughput observed when using CRIU CUDA.

You can see that Cedana’s throughput (\~0.6 GiB/s) is pretty close to the maximum possible throughput (0.68 GiB/s), which means you’re likely going to see faster checkpoint times when using a faster disk/network as Cedana is spending most of the time writing to disk/network. Whereas, CRIU CUDA’s throughput appears to increase with model size, which likely means it’s not using all of the available disk/network throughput as it’s more busy doing other work.

<figure><img src="/files/AX7G2pCE2LMn76x63gwd" alt=""><figcaption><p>Warm checkpoint time &#x26; throughput (GPT2 models)</p></figcaption></figure>

For larger models, we observe similar results. The above observations on throughput still hold. Just like for[ cold start time](#cold-start-time), we are missing CRIU CUDA results for the *gemma-2-9b*, and *stablelm-2-12b* models, as CRIU CUDA failed to checkpoint these models in every sample.

<figure><img src="/files/xNLTkn74YX9XVCu6r6yA" alt=""><figcaption><p>Warm checkpoint time &#x26; throughput (popular LLMs)</p></figcaption></figure>

Cedana checkpoint times are the fastest across the board.

### Save Migrate Resume

Below, you can see results for smaller models (GPT2). Left bars (shades of gray) are CRIU CUDA save migrate resume times, right bars (shades of blue) are cold starts using Cedana. The stacks, from bottom to top, denote save, migrate, and resume, respectively.

<figure><img src="/files/s9yh8RTFqEdy2wiz0ViE" alt=""><figcaption><p>Save migrate resume (GPT2 models)</p></figcaption></figure>

For larger models, we observe similar results. Just like for[ cold start time](#cold-start-time), we are missing CRIU CUDA results for the *gemma-2-9b*, and *stablelm-2-12b* models, as CRIU CUDA failed to checkpoint these models in every sample.

<figure><img src="/files/c3Yl62wkJYzVZj4Z63OR" alt=""><figcaption><p>Save migrate resume (popular LLMs)</p></figcaption></figure>

### vLLM Throughput

Below are the results from running [this benchmark](https://github.com/vllm-project/vllm/blob/main/benchmarks/benchmark_throughput.py) on *LLaMa 3.1 8B* model comparing runtime throughput of using Cedana (that uses GPU interception) with native.

<table><thead><tr><th width="218">Throughput</th><th>Native</th><th>Cedana</th></tr></thead><tbody><tr><td>Requests/s</td><td>11.69</td><td>13.85</td></tr><tr><td>Total tokens/s</td><td>4833.43</td><td>5725.69</td></tr><tr><td>Output tokens/s</td><td>2318.23</td><td>2746.18</td></tr></tbody></table>

Runtime throughput when running with Cedana is about **11% faster**. This is surprising, because using GPU interception for enabling GPU checkpoint/restore typically introduces some overhead to runtime performance. However, this overhead has been mitigated by optimizations that are only possible due to the asynchronous design of our GPU virtual machine (internally referred to as the GPU controller). This design allows the GPU controller to make decisions before actually executing CUDA driver API calls intercepted during operation. For example, it can combine multiple driver API calls or cancel redundant ones, effectively working like a[ just-in-time compiler (JIT)](https://en.wikipedia.org/wiki/Just-in-time_compilation).

### Setup

*Cedana version: v0.9.240-35-g9bd7886e*\
*Cedana GPU plugin version: v0.4.7-9-g1062be1*\
*CRIU version: v4.0*

The benchmarks were run on the following machine:

<table data-header-hidden><thead><tr><th width="431"></th><th></th></tr></thead><tbody><tr><td>CPU cache (L1 data)</td><td>1.9 MiB (30 instances)</td></tr><tr><td>CPU cache (L2)</td><td>15 MiB (30 instances)</td></tr><tr><td>CPU cache (L3)</td><td>480 MiB (30 instances)</td></tr><tr><td>CPU cores</td><td>30</td></tr><tr><td>CPU memory (DRAM)</td><td>216.26 GiB</td></tr><tr><td>CPU model</td><td>AMD EPYC 7J13 64-Core Processor</td></tr><tr><td>CPU threads/core</td><td>1</td></tr><tr><td>Disk read speed</td><td>7.410 GiB/s</td></tr><tr><td>Disk write speed</td><td>.67225325884543761638 GiB/s</td></tr><tr><td>GPU API</td><td>12.8</td></tr><tr><td>GPU SM clock speed (max)</td><td>1410 MHz</td></tr><tr><td>GPU compute capability</td><td>8.0</td></tr><tr><td>GPU driver</td><td>570.124.04</td></tr><tr><td>GPU memory (total)</td><td>40960 MiB</td></tr><tr><td>GPU memory clock speed (max)</td><td>1215 MHz</td></tr><tr><td>GPU model</td><td>NVIDIA A100-SXM4-40GB</td></tr><tr><td>Mock internet speed</td><td>500 MiB/s</td></tr></tbody></table>

## Why Cedana?

The above performance results make up a good case for why we continue to advance our interception-based GPU checkpoint/restore solution. As highlighted in this [paper](https://arxiv.org/abs/2502.16631), there are several challenges to testing and maintaining an interception-based solution, but we believe it’s worth it.

1. **Checkpoint/restore performance** – As in [benchmarks](#benchmarks), our checkpoint/restore solution is much faster than CRIU CUDA. GPU interception provides enhanced visibility into program execution, enabling optimization decisions like identifying memory regions for checkpointing and determining which CUDA calls to replay or skip during restore. This confers additional benefits, such as incremental checkpointing.
2. **Runtime performance** – GPU interception enables our GPU controller to function like a JIT compiler, allowing real-time optimizations such as merging multiple CUDA graph API calls, cancelling redundancies, etc. Even with our current minimal set of optimizations, we’ve observed a 10-12% runtime performance improvement on the [vLLM throughput benchmarks](#vllm-throughput). There’s substantial untapped potential that can only be unlocked through this level of control.
3. **Multi-GPU / Multi-node scaling** – For workloads distributed across multiple GPUs—whether on the same host or across different hosts—transparent checkpoint/restore requires synchronization that is only possible through knowledge of the GPU state. CRIU CUDA currently does **not** support NCCL-accelerated workloads. While application-aware C/R is always an option, achieving true transparency without modifying the application requires this approach.
4. **Beyond checkpoint/restore** – GPU interception enables far more than just checkpoint/restore. It lays the groundwork for automatic GPU failover, live GPU scaling, and live GPU migration and more!

## References

1. [CRIUgpu: Transparent Checkpointing of GPU-Accelerated Workloads](https://arxiv.org/abs/2502.16631)
2. [Singularity: Planet-Scale, Preemptive and Elastic Scheduling of AI Workloads](https://arxiv.org/pdf/2202.07848)


# Redis Save Migrate & Resume (SMR) on Kubernetes

Performing a save/migrate/resume of an in-cluster redis db.

{% hint style="warning" %}
This example is outdated. Please look at our other examples.
{% endhint %}

## Setup

Let's first set up a sample redis database on k8s. Create a namespace called `cedana-examples` and install `redis-example.yaml` , which can be found here: <https://github.com/cedana/cedana-helm-charts/tree/main/examples>.

```bash
kubectl create namespace cedana-examples
kubectl apply -f redis-example.yaml
```

Now let's port-forward the service on 127.0.0.1 and connect to the database:

```bash
kubectl port-forward service/redis -n cedana-examples 6379:6379
redis-cli -h 127.0.0.1
```

Lets store some data in the db:

```bash
HSET 'user:001' first_name 'John' last_name 'doe' dob '12-JUN-1970'
HSET 'user:002' first_name 'David' last_name 'Bloom' dob '03-MAR-1981'
```

Listing all the pods in the `cedana-examples` namespace using the `/list` endpoint gives us all the information we need to do a checkpoint and restore.

```bash
curl -X GET -H 'Content-Type: application/json' -d '{
  "root": "'$ROOT'"
}' $CONTROLLER_URL:1324/list/cedana-examples
```

Great! Now its time to checkpoint the container. Lets set the necessary environment variables before we proceed, which were present in the output of the `/list` endpoint. The following variables should work on most default containerd clusters.

```bash
export CHECKPOINT_CONTAINER=redis \
export CHECKPOINT_SANDBOX=redis-6b5bcbb6b6-tdb4p \
export RESTORE_CONTAINER=redis-restore \
export RESTORE_SANDBOX=redis-restore-c6c794b64-h7ccs \
export NAMESPACE=cedana-examples \
export CONTROLLER_URL=localhost \
export ROOT=/run/containerd/runc/k8s.io \
export CHECKPOINT_PATH=/tmp/ckpt-redis
```

## Checkpoint

```bash
curl -X POST -H "Content-Type: application/json" -d '{
  "checkpoint_data": {
    "container_name": "'$CHECKPOINT_CONTAINER'",
    "sandbox_name": "'$CHECKPOINT_SANDBOX'",
    "namespace": "'$NAMESPACE'",
    "checkpoint_path": "'$CHECKPOINT_PATH'",
    "root": "'$ROOT'"
  }
}' http://$CONTROLLER_URL:1324/checkpoint
```

## Restore

Once this completes, we need a new pod to restore the redis checkpoint into - effectively acting as a sleeping pod that we morph into a restored redis pod. We do this to avoid colliding with Kubernetes' scheduling and state management, so the users have full control over when pods are being restored.

```bash
k apply -f redis-restore-example.yaml
```

Then, performing a restore is as simple as another `curl` call:

```bash
curl -X POST -H "Content-Type: application/json" -d '{
  "checkpoint_data": {
    "container_name": "'$RESTORE_CONTAINER'",
    "sandbox_name": "'$RESTORE_SANDBOX'",
    "namespace": "'$NAMESPACE'",
    "checkpoint_path": "'$CHECKPOINT_PATH'",
    "root": "'$ROOT'"
  }
}' http://$CONTROLLER_URL:1324/restore
```

Finally connect to redis-cli once again to check if the new restored container has the previously set data:

```bash
HGETALL user:001
HGETALL user:002
```


# LLaMA Inference GPU Save, Migrate & Resume (SMR)

Performing an SMR of a running LLaMA inference task using HuggingFace weights.

Save, Migrate and Resume (SMR) has enormouse value for running inference workloads, especially when you're sensitive to cold starts. By virtue of what we're collecting from the GPU on a save (pretty much everything sitting in VRAM at the time) you can bypass all the initialization time and model optimizations that PyTorch or other inference engines (like vLLM or transformers-inference) do, and start inference workloads significantly faster.

Here's some benchmarking data to support that, which compares time to first token (TTFT) for a native start vs restoring from our checkpoint:

<figure><img src="/files/XXRcWdkAQCkKdGeKABtu" alt=""><figcaption></figcaption></figure>

Cedana is consistently faster, and generally gets faster for even larger models; which tracks with the amount of work that needs to be done by an inference engine to prepare weights for inference.

## Setup

Follow the instructions in [installation](/daemon/get-started/installation), to get started with Cedana locally. Optionally, take a look at [checkpoint/restore with GPUs](broken://spaces/Su8hW4oAhjiIohf3AFfl/pages/ieK7Li9lPJmOK4Jjfpem) to get an idea of how to use it.

## Running LLaMA 8B

A simple python script that uses `llama-3.1-8b` would look like:

```python
#!/usr/bin/env python3

import argparse
import time
from transformers import AutoModelForCausalLM, AutoTokenizer


# Load the tokenizer and model
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B")
model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-3.1-8B",
    torch_dtype="auto",
)
model.cuda()

while True:
    user_input = "some prompt"

    # Tokenize input
    inputs = tokenizer(user_input, return_tensors="pt").to(model.device)

    # Generate tokens
    tokens = model.generate(
        **inputs,
        max_new_tokens=64,
        temperature=0.70,
        top_p=0.95,
        do_sample=True,
    )

    output = tokenizer.decode(tokens[0], skip_special_tokens=True)
    print(f"Generated Output:\n{output}")

```

This will download weights from HuggingFace the first time, so would ensure that the weights download correctly first by running it separately (with `python3 llama_inference.py`). You can find more workloads you can test with [here](https://github.com/cedana/cedana-samples/)!

## Save

Start your workload with:

```bash
cedana run process -ga -j llama_inference -- python3 -u llama.py 
```

To perform save, it's as simple as:

```bash
cedana dump job llama_inference --compression=none
```

Use `cedana dump job --help` to see additional options (such as different compression schemes). You can also use `cedana ps`to inspect the running workload.

## Resume

To restore from a previously taken save:

```bash
cedana restore job llama_inference -a
```

You can restore from the same save indefinitely - so you can think of the file as information that stores model weights (as they're represented in VRAM) and everything in CPU state that coordinates execution.

A pretty powerful way some customers are using us is using a save as a proxy to model weights entirely - so now instead of loading model weights you just resume from the file - everywhere you need inference!


# API

Reference for the latest version of the API (sandbox.cedana.ai). If your deployment is not at latest, please use the API reference for your deployment (\<org>.cedana.ai/v2/scalar).


# User

Cedana API to get user information

## Get user

> Used to validate authentication token

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"User","description":"Cedana API to get user information"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/user":{"get":{"tags":["User"],"summary":"Get user","description":"Used to validate authentication token","operationId":"get","responses":{"200":{"description":"Returns UUID","content":{"text/plain":{"schema":{"type":"string"}}}},"401":{"description":"Invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Service

Cedana API for service discovery

## GET /v2/discover/{name}

> Service discovery

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Service","description":"Cedana API for service discovery"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/discover/{name}":{"get":{"tags":["Service"],"summary":"Service discovery","operationId":"discovery","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Returns url for the service named","content":{"text/plain":{"schema":{"type":"string"}}}},"404":{"description":"Service not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to fetch service configuration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Checkpoints

Cedana API for checkpoints

## List checkpoints

> Use query params to filter checkpoints. Supports filtering by \`ids\` (comma-separated UUIDs for single or multiple checkpoints)

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Checkpoints","description":"Cedana API for checkpoints"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"Checkpoint":{"type":"object","description":"Checkpoint is basic unit for cedana service operation\nit stores all the information regarding the snapshot we can use to save and then restore state","required":["id","status","gpu","platform"],"properties":{"checksum":{"type":["string","null"]},"gpu":{"type":"string"},"id":{"type":"string","format":"uuid"},"info":{},"name":{"type":["string","null"]},"platform":{"type":"string"},"status":{"$ref":"#/components/schemas/CheckpointStatus"}}},"CheckpointStatus":{"type":"string","enum":["initializing","updated_info","possibly_uploaded","ready","deprecated"]},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/checkpoints":{"get":{"tags":["Checkpoints"],"summary":"List checkpoints","description":"Use query params to filter checkpoints. Supports filtering by `ids` (comma-separated UUIDs for single or multiple checkpoints)","operationId":"list","parameters":[{"name":"ids","in":"query","description":"Comma-separated list of checkpoint UUIDs to filter by","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"description":"Returns checkpoints","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Checkpoint"}}}}},"400":{"description":"Invalid query parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to connect/fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## Create checkpoint

> Builds a new checkpoint without the metadata and information about the checkpoint with status initializing

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Checkpoints","description":"Cedana API for checkpoints"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/checkpoints":{"post":{"tags":["Checkpoints"],"summary":"Create checkpoint","description":"Builds a new checkpoint without the metadata and information about the checkpoint with status initializing","operationId":"add","responses":{"200":{"description":"Returns the checkpoint ID for the new checkpoint","content":{"text/plain":{"schema":{"type":"string"}}}},"500":{"description":"Failed to create checkpoint in database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## Deprecate checkpoint

> Marks checkpoint as deprecated, so that they can be removed on next internal state cleanup

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Checkpoints","description":"Cedana API for checkpoints"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/checkpoints/deprecate/{id}":{"patch":{"tags":["Checkpoints"],"summary":"Deprecate checkpoint","description":"Marks checkpoint as deprecated, so that they can be removed on next internal state cleanup","operationId":"deprecate","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully deprecated checkpoint and returns id","content":{"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"Invalid UUID provided","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to execute request against database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## Put checkpoint info

> Add information about the checkpoint

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Checkpoints","description":"Cedana API for checkpoints"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"CheckpointInfo":{"type":"object","required":["gpu","platform"],"properties":{"gpu":{"type":"string"},"info":{},"platform":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/checkpoints/info/{id}":{"put":{"tags":["Checkpoints"],"summary":"Put checkpoint info","description":"Add information about the checkpoint","operationId":"update_info","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckpointInfo"}}},"required":true},"responses":{"200":{"description":"Successfully updated checkpoint info and returns ID","content":{"text/plain":{"schema":{"type":"string"}}}},"500":{"description":"Failed to execute request against database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## Uploaded checkpoint

> Marks checkpoint as successfully uploaded and ready for restore

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Checkpoints","description":"Cedana API for checkpoints"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"CheckpointSuccessInfo":{"type":"object","properties":{"restore_path":{"type":["string","null"]}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/checkpoints/uploaded/{id}":{"post":{"tags":["Checkpoints"],"summary":"Uploaded checkpoint","description":"Marks checkpoint as successfully uploaded and ready for restore","operationId":"uploaded","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckpointSuccessInfo"}}},"required":true},"responses":{"200":{"description":"Marks the checkpoint as successfully uploaded","content":{"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to update checkpoint in database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Restores

Cedana API for restores

## Put restore info

> Add information about a restore

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Restores","description":"Cedana API for restores"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"RestoreInfo":{"type":"object","properties":{"error":{"type":["string","null"]},"profiling":{},"total_duration":{"type":["integer","null"],"format":"int64"},"total_io":{"type":["integer","null"],"format":"int64"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/restores/info/{id}":{"put":{"tags":["Restores"],"summary":"Put restore info","description":"Add information about a restore","operationId":"update_info","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreInfo"}}},"required":true},"responses":{"200":{"description":"Successfully updated restore info and returns ID","content":{"text/plain":{"schema":{"type":"string"}}}},"500":{"description":"Failed to execute request against database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Actions

Cedana API for actions

## GET /v2/actions

> List actions

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Actions","description":"Cedana API for actions"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"Action":{"type":"object","required":["action_id","checkpoint_id","status","type","details","gpu","platform"],"properties":{"action_id":{"type":"string","format":"uuid"},"action_timestamp":{"type":["string","null"],"format":"date-time"},"checkpoint_completed_timestamp":{"type":["string","null"],"format":"date-time"},"checkpoint_id":{"type":"string","format":"uuid"},"details":{},"gpu":{"type":"string"},"node_name":{"type":["string","null"]},"platform":{"type":"string"},"reason":{"type":["string","null"]},"status":{"type":"string"},"total_duration":{"type":["integer","null"],"format":"int64"},"total_io":{"type":["integer","null"],"format":"int64"},"type":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/actions":{"get":{"tags":["Actions"],"summary":"List actions","operationId":"list","parameters":[{"name":"type","in":"query","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"description":"Returns the actions with status","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Action"}}}}},"400":{"description":"Failed list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to connect/fetch from jobs table from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/actions/from\_pod/{id}

> Get latest action belonging to a pod

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Actions","description":"Cedana API for actions"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/actions/from_pod/{id}":{"get":{"tags":["Actions"],"summary":"Get latest action belonging to a pod","operationId":"latest_pod_action_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The action_id of the given pod_id has been fetched successfully","content":{"text/plain":{"schema":{"type":"string"}}}},"404":{"description":"Failed to get action_id for the given pod_id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to connect/fetch from pods_to_actions table from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## POST /v2/actions/upload

> Upload pod spec

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Actions","description":"Cedana API for actions"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"CheckpointStatusWithPodSpec":{"type":"object","required":["status","action_id"],"properties":{"action_id":{"type":"string"},"persistent_volume_claim":{},"pod_id":{"type":["string","null"]},"pod_metadata_spec":{},"pod_spec":{},"status":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/actions/upload":{"post":{"tags":["Actions"],"summary":"Upload pod spec","operationId":"upload_podspec","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckpointStatusWithPodSpec"}}},"required":true},"responses":{"200":{"description":"Success","content":{"text/plain":{"schema":{"type":"string"}}}},"404":{"description":"Failed to get action_id within the db","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to connect/fetch from pods_to_actions table from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## Get path of latest checkpoint

> Returns the path of the latest successful checkpoint for a given checkpoint name

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Actions","description":"Cedana API for actions"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/checkpoint/path":{"get":{"tags":["Actions"],"summary":"Get path of latest checkpoint","description":"Returns the path of the latest successful checkpoint for a given checkpoint name","operationId":"get_latest_checkpoint_for_container_in_action","responses":{"200":{"description":"Returns the restore path","content":{"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"Failed to get action for request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to connect/fetch from jobs table from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## POST /v2/checkpoint/pod

> Checkpoint pod

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Actions","description":"Cedana API for actions"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"CheckpointPod":{"type":"object","properties":{"action_id":{"type":["string","null"],"readOnly":true},"cluster_id":{"type":["string","null"]},"kind":{"$ref":"#/components/schemas/CheckpointKind"},"namespace":{"type":["string","null"]},"overrides":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/CheckpointOverrides"}]},"pod_id":{"type":["string","null"]},"pod_name":{"type":["string","null"]},"reason":{"$ref":"#/components/schemas/CheckpointReason"}}},"CheckpointKind":{"type":"string","enum":["simple","rootfs","rootfsonly"]},"CheckpointOverrides":{"type":"object","properties":{"asynchronous":{"type":"boolean"},"compression":{"type":["string","null"]},"criu_opts":{"type":["string","null"]},"directory":{"type":["string","null"]},"streams":{"type":"integer","format":"int32"}}},"CheckpointReason":{"type":"string","enum":["heartbeat","manual"]},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/checkpoint/pod":{"post":{"tags":["Actions"],"summary":"Checkpoint pod","operationId":"checkpoint_pod","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckpointPod"}}},"required":true},"responses":{"200":{"description":"Returns the ID for the task","content":{"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Failed to find checkpointable resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to create checkpoint or connect to eventstream","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## Get status of checkpoint action

> Returns the current status of a checkpoint action

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Actions","description":"Cedana API for actions"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"StatusResponse":{"type":"object","required":["status"],"properties":{"details":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/CheckpointOperationStatus"}}},"CheckpointOperationStatus":{"type":"string","enum":["initialized","processing","checkpoint_created","ready","error","not_found"]},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/checkpoint/status/{action_id}":{"get":{"tags":["Actions"],"summary":"Get status of checkpoint action","description":"Returns the current status of a checkpoint action","operationId":"get_checkpoint_status","parameters":[{"name":"action_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Returns the current status of the checkpoint operation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponse"}}}},"404":{"description":"Action ID not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to retrieve status from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## POST /v2/restore/pod

> Restore pod

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Actions","description":"Cedana API for actions"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"RestorePod":{"type":"object","required":["action_id","reason"],"properties":{"action_id":{"type":"string"},"cluster_id":{"type":"string"},"overrides":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RestoreOverrides"}]},"reason":{"$ref":"#/components/schemas/RestoreReason"}}},"RestoreOverrides":{"type":"object","properties":{"criu_opts":{"type":["string","null"]},"pod_name":{"type":["string","null"]}}},"RestoreReason":{"type":"string","enum":["nodeTermination","nodeUnschedulable","manual"]},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/restore/pod":{"post":{"tags":["Actions"],"summary":"Restore pod","operationId":"restore_pod","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestorePod"}}},"required":true},"responses":{"200":{"description":"Returns the action ID for the new restore","content":{"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"Invalid action_id or request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to create restore or connect to eventstream","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Files

Cedana API for files

## GET /v2/files/dir/{path}

> Read directory contents

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Files","description":"Cedana API for files"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/files/dir/{path}":{"get":{"tags":["Files"],"summary":"Read directory contents","operationId":"read_dir","parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Returns the list of files in the directory","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}}}}},"500":{"description":"Failed to list directory contents","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/files/{path}

> Download file

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Files","description":"Cedana API for files"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/files/{path}":{"get":{"tags":["Files"],"summary":"Download file","operationId":"get_file","parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Returns the URL to download the file from","content":{"text/plain":{"schema":{"type":"string"}}}},"500":{"description":"Failed to generate download URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## PUT /v2/files/{path}

> Upload file

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Files","description":"Cedana API for files"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/files/{path}":{"put":{"tags":["Files"],"summary":"Upload file","operationId":"push_files","parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Returns the URL to upload the file to","content":{"text/plain":{"schema":{"type":"string"}}}},"500":{"description":"Failed to generate upload URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Resources

Cedana API for resources

## GET /v2/cluster/count

> Get clusters total count

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"TotalCountResponse":{"type":"object","required":["total_count"],"properties":{"total_count":{"type":"integer","format":"int64"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/cluster/count":{"get":{"tags":["Resources"],"summary":"Get clusters total count","operationId":"clusters_count","responses":{"200":{"description":"Total count retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TotalCountResponse"}}}},"500":{"description":"Database error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/jobs

> List jobs

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"JobResponse":{"type":"object","required":["id","name","namespace","status","age","monitored_by_policies","policy_count","pod_ids"],"properties":{"age":{"type":"string"},"completions":{"type":["integer","null"],"format":"int32"},"duration":{"type":["string","null"]},"id":{"type":"string","format":"uuid"},"monitored_by_policies":{"type":"array","items":{"type":"string"}},"name":{"type":"string"},"namespace":{"type":"string"},"pod_ids":{"type":"array","items":{"type":"string"}},"policy_count":{"type":"integer","format":"int64"},"priority":{"type":["integer","null"],"format":"int32"},"start_time":{"type":["string","null"]},"status":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/jobs":{"get":{"tags":["Resources"],"summary":"List jobs","operationId":"job_list","responses":{"200":{"description":"Returns jobs","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/JobResponse"}}}}},"500":{"description":"Failed to fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/jobs/count

> Get total count of jobs

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"TotalCountResponse":{"type":"object","required":["total_count"],"properties":{"total_count":{"type":"integer","format":"int64"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/jobs/count":{"get":{"tags":["Resources"],"summary":"Get total count of jobs","operationId":"jobs_count","responses":{"200":{"description":"Total count retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TotalCountResponse"}}}},"500":{"description":"Database error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/jobs/filter

>

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"paths":{"/v2/jobs/filter":{"get":{"tags":["Resources"],"operationId":"jobs_filter","parameters":[{"name":"priority","in":"query","required":false,"schema":{"type":["integer","null"],"format":"int32"}},{"name":"namespace","in":"query","required":false,"schema":{"type":["string","null"]}},{"name":"status","in":"query","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"description":"List of jobs with applied filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FilteredJobResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}},"components":{"schemas":{"FilteredJobResponse":{"type":"object","required":["jobs","total_count","available_priorities"],"properties":{"available_priorities":{"type":"array","items":{"type":"integer","format":"int32"}},"jobs":{"type":"array","items":{"$ref":"#/components/schemas/JobFilterResponse"}},"total_count":{"type":"integer","format":"int64"}}},"JobFilterResponse":{"type":"object","required":["id","name","namespace","status","pod_count"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"namespace":{"type":"string"},"pod_count":{"type":"integer","format":"int64"},"priority":{"type":["integer","null"],"format":"int32"},"start_time":{"type":["string","null"]},"status":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}}}
```

## GET /v2/jobs/namespaces

> Get job namespaces

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"NamespacesResponse":{"type":"object","required":["namespaces"],"properties":{"namespaces":{"type":"array","items":{"type":"string"}}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/jobs/namespaces":{"get":{"tags":["Resources"],"summary":"Get job namespaces","operationId":"job_namespaces","responses":{"200":{"description":"Available namespaces retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NamespacesResponse"}}}},"500":{"description":"Database error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/jobs/paginated

> List jobs (paginated)

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"PaginatedJobResponse":{"type":"object","required":["jobs","total_count"],"properties":{"available_filters":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/AvailableFilters"}]},"jobs":{"type":"array","items":{"$ref":"#/components/schemas/JobResponse"}},"total_count":{"type":"integer","format":"int64"}}},"AvailableFilters":{"type":"object","required":["statuses","namespaces"],"properties":{"namespaces":{"type":"array","items":{"type":"string"}},"statuses":{"type":"array","items":{"type":"string"}}}},"JobResponse":{"type":"object","required":["id","name","namespace","status","age","monitored_by_policies","policy_count","pod_ids"],"properties":{"age":{"type":"string"},"completions":{"type":["integer","null"],"format":"int32"},"duration":{"type":["string","null"]},"id":{"type":"string","format":"uuid"},"monitored_by_policies":{"type":"array","items":{"type":"string"}},"name":{"type":"string"},"namespace":{"type":"string"},"pod_ids":{"type":"array","items":{"type":"string"}},"policy_count":{"type":"integer","format":"int64"},"priority":{"type":["integer","null"],"format":"int32"},"start_time":{"type":["string","null"]},"status":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/jobs/paginated":{"get":{"tags":["Resources"],"summary":"List jobs (paginated)","operationId":"job_list_paginated","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":["integer","null"],"format":"int64"}},{"name":"offset","in":"query","required":false,"schema":{"type":["integer","null"],"format":"int64"}},{"name":"sort","in":"query","required":false,"schema":{"type":["string","null"]}},{"name":"ascending","in":"query","required":false,"schema":{"type":["boolean","null"]}},{"name":"status","in":"query","required":false,"schema":{"type":["string","null"]}},{"name":"namespace","in":"query","required":false,"schema":{"type":["string","null"]}},{"name":"job_name","in":"query","description":"job name to query against (uses postgres ILIKE pattern search)","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"description":"Returns paginated jobs with total count and available filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedJobResponse"}}}},"500":{"description":"Failed to fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/jobs/priorities

> Get available job priorities with counts

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"security":[{"api_key":[]}],"components":{"securitySchemes":{},"schemas":{"JobPrioritiesResponse":{"type":"object","required":["priorities","priority_counts"],"properties":{"priorities":{"type":"array","items":{"type":"integer","format":"int32"}},"priority_counts":{"type":"object","additionalProperties":{"type":"integer","format":"int64"},"propertyNames":{"type":"string"}}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/jobs/priorities":{"get":{"tags":["Resources"],"summary":"Get available job priorities with counts","operationId":"job_priorities","responses":{"200":{"description":"Job priorities retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobPrioritiesResponse"}}}},"500":{"description":"Database error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/jobs/priority/{priority}

>

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"paths":{"/v2/jobs/priority/{priority}":{"get":{"tags":["Resources"],"operationId":"jobs_by_priority","parameters":[{"name":"priority","in":"path","description":"Priority value to filter jobs by","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"List of jobs filtered by priority","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedJobResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}},"components":{"schemas":{"PaginatedJobResponse":{"type":"object","required":["jobs","total_count"],"properties":{"available_filters":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/AvailableFilters"}]},"jobs":{"type":"array","items":{"$ref":"#/components/schemas/JobResponse"}},"total_count":{"type":"integer","format":"int64"}}},"AvailableFilters":{"type":"object","required":["statuses","namespaces"],"properties":{"namespaces":{"type":"array","items":{"type":"string"}},"statuses":{"type":"array","items":{"type":"string"}}}},"JobResponse":{"type":"object","required":["id","name","namespace","status","age","monitored_by_policies","policy_count","pod_ids"],"properties":{"age":{"type":"string"},"completions":{"type":["integer","null"],"format":"int32"},"duration":{"type":["string","null"]},"id":{"type":"string","format":"uuid"},"monitored_by_policies":{"type":"array","items":{"type":"string"}},"name":{"type":"string"},"namespace":{"type":"string"},"pod_ids":{"type":"array","items":{"type":"string"}},"policy_count":{"type":"integer","format":"int64"},"priority":{"type":["integer","null"],"format":"int32"},"start_time":{"type":["string","null"]},"status":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}}}
```

## GET /v2/jobs/statuses

> Get job statuses

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"StatusesResponse":{"type":"object","required":["statuses"],"properties":{"statuses":{"type":"array","items":{"type":"string"}}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/jobs/statuses":{"get":{"tags":["Resources"],"summary":"Get job statuses","operationId":"job_statuses","responses":{"200":{"description":"Available statuses retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusesResponse"}}}},"500":{"description":"Database error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/jobs/{job\_id}/pods

>

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"paths":{"/v2/jobs/{job_id}/pods":{"get":{"tags":["Resources"],"operationId":"job_pods","parameters":[{"name":"job_id","in":"path","description":"Job ID to get pods for","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"List of pods managed by the job","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobPodsResponse"}}}},"404":{"description":"Job not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}},"components":{"schemas":{"JobPodsResponse":{"type":"object","required":["job_id","job_name","pods","total_count"],"properties":{"job_id":{"type":"string","format":"uuid"},"job_name":{"type":"string"},"pods":{"type":"array","items":{"$ref":"#/components/schemas/JobPodResponse"}},"total_count":{"type":"integer","format":"int64"}}},"JobPodResponse":{"type":"object","required":["id","name","namespace","status"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"namespace":{"type":"string"},"owner_reference":{"type":["string","null"]},"status":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}}}
```

## List nodes

> Will only return nodes from clusters with status 'active' if no params are provided. Also, nodes\
> with last\_sync older than 5 minutes are not returned.

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"NodeResponse":{"type":"object","required":["id","name","status","cluster_name","compute_type","instance_type","region"],"properties":{"cluster_name":{"type":"string"},"compute_type":{"type":"string"},"id":{"type":"string","format":"uuid"},"instance_type":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"},"status":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/nodes":{"get":{"tags":["Resources"],"summary":"List nodes","description":"Will only return nodes from clusters with status 'active' if no params are provided. Also, nodes\nwith last_sync older than 5 minutes are not returned.","operationId":"node_list","parameters":[{"name":"id","in":"query","required":false,"schema":{"type":["string","null"],"format":"uuid"}}],"responses":{"200":{"description":"Returns nodes","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NodeResponse"}}}}},"500":{"description":"Failed to fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/nodes/count

> Get nodes total count

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"TotalCountResponse":{"type":"object","required":["total_count"],"properties":{"total_count":{"type":"integer","format":"int64"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/nodes/count":{"get":{"tags":["Resources"],"summary":"Get nodes total count","operationId":"nodes_count","responses":{"200":{"description":"Total count retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TotalCountResponse"}}}},"500":{"description":"Database error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## List pods

> Will not return pods with status 'deleted', and only from clusters with status 'active' and\
> pods belonging to nodes whose last\_sync is within the last 5 minutes.

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"PodResponse":{"type":"object","required":["id","name","namespace","status","age","ready","node","restarts","monitored_by_policies"],"properties":{"age":{"type":"string"},"id":{"type":"string","format":"uuid"},"monitored_by_policies":{"type":"array","items":{"type":"string"}},"name":{"type":"string"},"namespace":{"type":"string"},"node":{"type":"string"},"ready":{"type":"string"},"restarts":{"type":"integer","format":"int32"},"start_time":{"type":["string","null"]},"status":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/pods":{"get":{"tags":["Resources"],"summary":"List pods","description":"Will not return pods with status 'deleted', and only from clusters with status 'active' and\npods belonging to nodes whose last_sync is within the last 5 minutes.","operationId":"pod_list","parameters":[{"name":"id","in":"query","required":false,"schema":{"type":["string","null"],"format":"uuid"}}],"responses":{"200":{"description":"Returns pods","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PodResponse"}}}}},"500":{"description":"Failed to fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/pods/count

> Get total count of pods

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"TotalCountResponse":{"type":"object","required":["total_count"],"properties":{"total_count":{"type":"integer","format":"int64"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/pods/count":{"get":{"tags":["Resources"],"summary":"Get total count of pods","operationId":"pods_count","responses":{"200":{"description":"Total count retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TotalCountResponse"}}}},"500":{"description":"Database error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/pods/namespaces

> List pod namespaces

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"NamespacesResponse":{"type":"object","required":["namespaces"],"properties":{"namespaces":{"type":"array","items":{"type":"string"}}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/pods/namespaces":{"get":{"tags":["Resources"],"summary":"List pod namespaces","operationId":"pod_namespaces","responses":{"200":{"description":"Returns distinct pod namespaces","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NamespacesResponse"}}}},"500":{"description":"Failed to fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/pods/paginated

> List pods (paginated)

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"PaginatedPodResponse":{"type":"object","required":["pods","total_count"],"properties":{"available_filters":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/AvailableFilters"}]},"pods":{"type":"array","items":{"$ref":"#/components/schemas/PodResponse"}},"total_count":{"type":"integer","format":"int64"}}},"AvailableFilters":{"type":"object","required":["statuses","namespaces"],"properties":{"namespaces":{"type":"array","items":{"type":"string"}},"statuses":{"type":"array","items":{"type":"string"}}}},"PodResponse":{"type":"object","required":["id","name","namespace","status","age","ready","node","restarts","monitored_by_policies"],"properties":{"age":{"type":"string"},"id":{"type":"string","format":"uuid"},"monitored_by_policies":{"type":"array","items":{"type":"string"}},"name":{"type":"string"},"namespace":{"type":"string"},"node":{"type":"string"},"ready":{"type":"string"},"restarts":{"type":"integer","format":"int32"},"start_time":{"type":["string","null"]},"status":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/pods/paginated":{"get":{"tags":["Resources"],"summary":"List pods (paginated)","operationId":"pod_list_paginated","parameters":[{"name":"id","in":"query","required":false,"schema":{"type":["string","null"],"format":"uuid"}},{"name":"limit","in":"query","required":false,"schema":{"type":["integer","null"],"format":"int64"}},{"name":"offset","in":"query","required":false,"schema":{"type":["integer","null"],"format":"int64"}},{"name":"sort","in":"query","required":false,"schema":{"type":["string","null"]}},{"name":"ascending","in":"query","required":false,"schema":{"type":["boolean","null"]}},{"name":"status","in":"query","required":false,"schema":{"type":["string","null"]}},{"name":"namespace","in":"query","required":false,"schema":{"type":["string","null"]}},{"name":"pod_name","in":"query","description":"pod name to query against (uses postgres ILIKE pattern search)","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"description":"Returns paginated pods with total count and available filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedPodResponse"}}}},"500":{"description":"Failed to fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/pods/statuses

> List pod statuses

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Resources","description":"Cedana API for resources"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"StatusesResponse":{"type":"object","required":["statuses"],"properties":{"statuses":{"type":"array","items":{"type":"string"}}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/pods/statuses":{"get":{"tags":["Resources"],"summary":"List pod statuses","operationId":"pod_statuses","responses":{"200":{"description":"Returns distinct pod statuses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusesResponse"}}}},"500":{"description":"Failed to fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Clusters

Cedana API for clusters

## List clusters

> Returns all clusters associated with the authenticated user's organization

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Clusters","description":"Cedana API for clusters"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"Cluster":{"type":"object","required":["id","name","status"],"properties":{"id":{"type":"string","format":"uuid"},"last_sync":{"type":["string","null"],"format":"date-time"},"metadata":{},"name":{"type":"string"},"status":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/cluster":{"get":{"tags":["Clusters"],"summary":"List clusters","description":"Returns all clusters associated with the authenticated user's organization","operationId":"list","responses":{"200":{"description":"Returns a list of clusters","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Cluster"}}}}},"500":{"description":"Failed to fetch clusters from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## Create cluster

> Creates or updates info regarding a Kubernetes cluster

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Clusters","description":"Cedana API for clusters"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"CreateClusterRequest":{"type":"object","description":"CreateClusterRequest is the request body for creating a cluster","required":["cluster_name"],"properties":{"cluster_name":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/cluster":{"post":{"tags":["Clusters"],"summary":"Create cluster","description":"Creates or updates info regarding a Kubernetes cluster","operationId":"create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateClusterRequest"}}},"required":true},"responses":{"200":{"description":"Returns the cluster id for the newly created or updated cluster","content":{"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"Bad request or missing cluster name","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to create cluster in database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## Sync cluster

> Syncs cluster resources such as pods, jobs, and nodes

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Clusters","description":"Cedana API for clusters"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"ClusterSyncRequest":{"type":"object","properties":{"cluster_id":{"type":["string","null"],"format":"uuid"},"metadata":{},"resource":{"$ref":"#/components/schemas/K8sResource"}}},"K8sResource":{"oneOf":[{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["None"]}}},{"allOf":[{"$ref":"#/components/schemas/Pod"},{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["Pod"]}}}]},{"allOf":[{"$ref":"#/components/schemas/Node"},{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["Node"]}}}]},{"allOf":[{"$ref":"#/components/schemas/Job"},{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["Job"]}}}]}]},"Pod":{"type":"object","title":"Pod","description":"Entire json for the Kubernetes "},"Node":{"type":"object","title":"Node","description":"Entire json for the Kubernetes Node"},"Job":{"type":"object","title":"Job","description":"Entire json for the Kubernetes Job"},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/cluster/sync":{"post":{"tags":["Clusters"],"summary":"Sync cluster","description":"Syncs cluster resources such as pods, jobs, and nodes","operationId":"sync","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClusterSyncRequest"}}},"required":true},"responses":{"200":{"description":"Resource id registered internally","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Cluster or node not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to sync resource to database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## Create workload

> Takes a cluster name and workload specification, then creates a Kubernetes job\
> on the specified cluster

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Clusters","description":"Cedana API for clusters"}],"paths":{"/v2/cluster/workload":{"post":{"tags":["Clusters"],"summary":"Create workload","description":"Takes a cluster name and workload specification, then creates a Kubernetes job\non the specified cluster","operationId":"create_workload","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkloadReq"}}},"required":true},"responses":{"200":{"description":"Added workload to queue","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"400":{"description":"Error parsing body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}},"components":{"schemas":{"WorkloadReq":{"type":"object","required":["cluster_id"],"properties":{"cluster_id":{"type":"string"},"cluster_name":{"type":["string","null"],"deprecated":true},"deployment":{},"job":{},"pod":{}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}}}
```

## Delete cluster

> This endpoint deletes a cluster and all its dependent entities in a single transaction\
> which is rolled back if any part of the deletion fails

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Clusters","description":"Cedana API for clusters"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/cluster/{id}":{"delete":{"tags":["Clusters"],"summary":"Delete cluster","description":"This endpoint deletes a cluster and all its dependent entities in a single transaction\nwhich is rolled back if any part of the deletion fails","operationId":"delete","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Delete the given cluster, and return Status OK"},"404":{"description":"Cluster not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to delete cluster from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Policy

Cedana API for policies

## POST /v2/policy/create

> Create policy

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Policy","description":"Cedana API for policies"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"PolicyRequest":{"type":"object","required":["heartbeat_time","resource_ids","cluster_id"],"properties":{"cluster_id":{"type":"string"},"heartbeat_time":{"type":"integer","format":"int64","minimum":0},"id":{"type":["string","null"]},"job_filter":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/JobFilter"}]},"policy_type":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/PolicyType"}]},"resource":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/PolicyResource"}]},"resource_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"resource_name":{"type":"string"},"runc_root":{"type":["string","null"]}}},"JobFilter":{"type":"object","properties":{"namespace":{"type":["string","null"]},"priority":{"type":["integer","null"],"format":"int32"}}},"PolicyType":{"type":"string","enum":["heartbeat"]},"PolicyResource":{"type":"string","enum":["pods","namespace","jobs"]},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/policy/create":{"post":{"tags":["Policy"],"summary":"Create policy","operationId":"policy_create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyRequest"}}},"required":true},"responses":{"200":{"description":"Policy created successfully","content":{"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to create policy in policy table","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## DELETE /v2/policy/delete

> Delete policy

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Policy","description":"Cedana API for policies"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"PolicyDeleteRequest":{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"uuid"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/policy/delete":{"delete":{"tags":["Policy"],"summary":"Delete policy","operationId":"policy_delete","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyDeleteRequest"}}},"required":true},"responses":{"200":{"description":"Policy deleted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to delete policy from policy table","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/policy/list

> List policies

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Policy","description":"Cedana API for policies"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"PolicyResponse":{"type":"object","required":["id","status","policy_type","input","resource","resource_list","pod_count"],"properties":{"id":{"type":"string"},"input":{"type":"integer","format":"int64"},"job_count":{"type":["integer","null"],"format":"int64"},"pod_count":{"type":"integer","format":"int64"},"policy_type":{"type":"string"},"resource":{"type":"string"},"resource_list":{"type":"array","items":{"type":"string"}},"status":{"type":"string"},"timestamp":{"type":["string","null"],"format":"date-time"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/policy/list":{"get":{"tags":["Policy"],"summary":"List policies","operationId":"policy_list","responses":{"200":{"description":"Policies retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PolicyResponse"}}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to retriev policies from policy table","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## POST /v2/policy/sync-jobs

> Sync job policies manually

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Policy","description":"Cedana API for policies"}],"security":[{"api_key":[]}],"components":{"securitySchemes":{},"schemas":{"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/policy/sync-jobs":{"post":{"tags":["Policy"],"summary":"Sync job policies manually","operationId":"sync_job_policies","responses":{"200":{"description":"Job policies synced successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to sync job policies"}}}}}}
```

## POST /v2/policy/update

> Update policy

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Policy","description":"Cedana API for policies"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"PolicyRequest":{"type":"object","required":["heartbeat_time","resource_ids","cluster_id"],"properties":{"cluster_id":{"type":"string"},"heartbeat_time":{"type":"integer","format":"int64","minimum":0},"id":{"type":["string","null"]},"job_filter":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/JobFilter"}]},"policy_type":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/PolicyType"}]},"resource":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/PolicyResource"}]},"resource_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"resource_name":{"type":"string"},"runc_root":{"type":["string","null"]}}},"JobFilter":{"type":"object","properties":{"namespace":{"type":["string","null"]},"priority":{"type":["integer","null"],"format":"int32"}}},"PolicyType":{"type":"string","enum":["heartbeat"]},"PolicyResource":{"type":"string","enum":["pods","namespace","jobs"]},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/policy/update":{"post":{"tags":["Policy"],"summary":"Update policy","operationId":"policy_update","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyRequest"}}},"required":true},"responses":{"200":{"description":"Policy updated successfully","content":{"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to update policy from policy table","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/policy/{policy\_id}/job-status

> Get job policy tracking status

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Policy","description":"Cedana API for policies"}],"security":[{"api_key":[]}],"components":{"securitySchemes":{},"schemas":{"JobPolicyStatus":{"type":"object","required":["policy_id","job_ids","tracked_pods","pod_count"],"properties":{"job_ids":{"type":"array","items":{"type":"string"}},"job_status":{"type":["string","null"]},"last_updated":{"type":["string","null"]},"pod_count":{"type":"integer","format":"int64"},"policy_id":{"type":"string"},"tracked_pods":{"type":"array","items":{"type":"string"}}}}}},"paths":{"/v2/policy/{policy_id}/job-status":{"get":{"tags":["Policy"],"summary":"Get job policy tracking status","operationId":"get_job_policy_status","parameters":[{"name":"policy_id","in":"path","description":"Policy ID to get status for","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Job policy status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobPolicyStatus"}}}},"404":{"description":"Policy not found"},"500":{"description":"Internal server error"}}}}}}
```

## GET /v2/policy/{policy\_id}/jobs

> Get jobs affected by a policy

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Policy","description":"Cedana API for policies"}],"security":[{"api_key":[]}],"components":{"securitySchemes":{},"schemas":{"PolicyJobsResponse":{"type":"object","required":["policy_id","affected_jobs","count"],"properties":{"affected_jobs":{"type":"array","items":{"$ref":"#/components/schemas/PolicyJobInfo"}},"count":{"type":"integer","format":"int64"},"policy_id":{"type":"string"}}},"PolicyJobInfo":{"type":"object","required":["id","name","namespace","status","pod_count"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"namespace":{"type":"string"},"pod_count":{"type":"integer","format":"int64"},"priority":{"type":["integer","null"],"format":"int32"},"status":{"type":"string"}}}}},"paths":{"/v2/policy/{policy_id}/jobs":{"get":{"tags":["Policy"],"summary":"Get jobs affected by a policy","operationId":"policy_jobs","parameters":[{"name":"policy_id","in":"path","description":"Policy ID to get affected jobs for","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Jobs affected by the policy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyJobsResponse"}}}},"404":{"description":"Policy not found or not a job policy"},"500":{"description":"Internal server error"}}}}}}
```

## GET /v2/policy/{policy\_id}/pods

> Get pods monitored by a specific policy

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Policy","description":"Cedana API for policies"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"PolicyPodResponse":{"type":"object","required":["id","name","namespace","status"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"namespace":{"type":"string"},"status":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/policy/{policy_id}/pods":{"get":{"tags":["Policy"],"summary":"Get pods monitored by a specific policy","operationId":"policy_pods","parameters":[{"name":"policy_id","in":"path","description":"Policy UUID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Returns pods currently monitored by the policy","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PolicyPodResponse"}}}}},"400":{"description":"Invalid policy_id format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Policy not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to connect/fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Cloud Bursting

Cedana API for cloud bursting

## GET /v2/instances

> List instances

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Cloud Bursting","description":"Cedana API for cloud bursting"}],"paths":{"/v2/instances":{"get":{"tags":["Cloud Bursting"],"summary":"List instances","operationId":"list_instances","responses":{"200":{"description":"List of instances","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InstanceInfo"}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}},"components":{"schemas":{"InstanceInfo":{"type":"object","required":["id","name","status","cloud_provider","region","instance_type"],"properties":{"cloud_provider":{"type":"string"},"created_at":{"type":["string","null"]},"id":{"type":"string"},"instance_type":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"},"status":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}}}
```

## POST /v2/instances

> Create instance

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Cloud Bursting","description":"Cedana API for cloud bursting"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"CreateInstanceRequest":{"type":"object","required":["cloud","region","shade_instance_type","shade_cloud","name"],"properties":{"alert":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Alert"}]},"auto_delete":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/AutoDelete"}]},"cloud":{"type":"string"},"envs":{"type":["array","null"],"items":{"$ref":"#/components/schemas/EnvironmentVariable"}},"launch_configuration":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/LaunchConfiguration"}]},"name":{"type":"string"},"os":{"type":["string","null"]},"region":{"type":"string"},"shade_cloud":{"type":"boolean"},"shade_instance_type":{"type":"string"},"ssh_key_id":{"type":["string","null"]},"tags":{"type":["array","null"],"items":{"type":"string"}},"template_id":{"type":["string","null"]},"volume_ids":{"type":["array","null"],"items":{"type":"string"}},"volume_mount":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/VolumeMount"}]}}},"Alert":{"type":"object","properties":{"date_threshold":{"type":["string","null"]},"spend_threshold":{"type":["string","null"]}}},"AutoDelete":{"type":"object","properties":{"date_threshold":{"type":["string","null"]},"spend_threshold":{"type":["string","null"]}}},"EnvironmentVariable":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string"},"value":{"type":"string"}}},"LaunchConfiguration":{"type":"object","required":["type"],"properties":{"docker_configuration":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/DockerConfiguration"}]},"script_configuration":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ScriptConfiguration"}]},"type":{"type":"string"}}},"DockerConfiguration":{"type":"object","required":["image"],"properties":{"args":{"type":["string","null"]},"envs":{"type":["array","null"],"items":{"$ref":"#/components/schemas/EnvironmentVariable"}},"image":{"type":"string"},"port_mappings":{"type":["array","null"],"items":{"$ref":"#/components/schemas/PortMapping"}},"registry_credentials":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RegistryCredentials"}]},"shared_memory_in_gb":{"type":["integer","null"],"format":"int32"},"volume_mounts":{"type":["array","null"],"items":{"$ref":"#/components/schemas/VolumeMapping"}}}},"PortMapping":{"type":"object","required":["host_port","container_port"],"properties":{"container_port":{"type":"integer","format":"int32"},"host_port":{"type":"integer","format":"int32"}}},"RegistryCredentials":{"type":"object","required":["username","password"],"properties":{"password":{"type":"string"},"username":{"type":"string"}}},"VolumeMapping":{"type":"object","required":["host_path","container_path"],"properties":{"container_path":{"type":"string"},"host_path":{"type":"string"}}},"ScriptConfiguration":{"type":"object","required":["base64_script"],"properties":{"base64_script":{"type":"string"}}},"VolumeMount":{"type":"object","properties":{"auto":{"type":["boolean","null"]}}},"CreateInstanceResponse":{"type":"object","required":["instance_id","status","cloud_provider","region","instance_type"],"properties":{"cloud_provider":{"type":"string"},"instance_id":{"type":"string"},"instance_type":{"type":"string"},"region":{"type":"string"},"status":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/instances":{"post":{"tags":["Cloud Bursting"],"summary":"Create instance","operationId":"create_instance","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInstanceRequest"}}},"required":true},"responses":{"200":{"description":"Instance created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInstanceResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/instances/bursting-status

> Get configuration status

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Cloud Bursting","description":"Cedana API for cloud bursting"}],"paths":{"/v2/instances/bursting-status":{"get":{"tags":["Cloud Bursting"],"summary":"Get configuration status","operationId":"get_bursting_status","responses":{"200":{"description":"Bursting configuration status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BurstingStatus"}}}}}}}},"components":{"schemas":{"BurstingStatus":{"type":"object","required":["status","message","can_use_bursting"],"properties":{"can_use_bursting":{"type":"boolean"},"message":{"type":"string"},"status":{"$ref":"#/components/schemas/BurstingConfigStatus"}}},"BurstingConfigStatus":{"type":"string","enum":["not_configured","configured","invalid"]}}}}
```

## GET /v2/instances/types

> Get available instance types

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Cloud Bursting","description":"Cedana API for cloud bursting"}],"paths":{"/v2/instances/types":{"get":{"tags":["Cloud Bursting"],"summary":"Get available instance types","operationId":"get_instance_types","parameters":[{"name":"num_gpus","in":"query","description":"Filter by number of GPUs","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"gpu_type","in":"query","description":"Filter by GPU type","required":false,"schema":{"type":"string"}},{"name":"sort","in":"query","description":"Sort results (e.g., 'price')","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Available instance types","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InstanceType"}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}},"components":{"schemas":{"InstanceType":{"type":"object","required":["cloud","shade_instance_type","cloud_instance_type","configuration","hourly_price","deployment_type","availability","boot_time"],"properties":{"availability":{"type":"array","items":{"$ref":"#/components/schemas/InstanceTypeAvailability"}},"boot_time":{"$ref":"#/components/schemas/InstanceTypeBootTime"},"cloud":{"type":"string"},"cloud_instance_type":{"type":"string"},"configuration":{"$ref":"#/components/schemas/InstanceTypeConfiguration"},"deployment_type":{"type":"string"},"hourly_price":{"type":"integer","format":"int32"},"shade_instance_type":{"type":"string"}}},"InstanceTypeAvailability":{"type":"object","required":["region","available","display_name"],"properties":{"available":{"type":"boolean"},"display_name":{"type":"string"},"region":{"type":"string"}}},"InstanceTypeBootTime":{"type":"object","required":["min_boot_in_sec","max_boot_in_sec"],"properties":{"max_boot_in_sec":{"type":"integer","format":"int32"},"min_boot_in_sec":{"type":"integer","format":"int32"}}},"InstanceTypeConfiguration":{"type":"object","required":["memory_in_gb","storage_in_gb","vcpus","num_gpus","gpu_type","interconnect","nvlink","vram_per_gpu_in_gb","os_options"],"properties":{"gpu_type":{"type":"string"},"interconnect":{"type":"string"},"memory_in_gb":{"type":"integer","format":"int32"},"num_gpus":{"type":"integer","format":"int32"},"nvlink":{"type":"boolean"},"os_options":{"type":"array","items":{"type":"string"}},"storage_in_gb":{"type":"integer","format":"int32"},"vcpus":{"type":"integer","format":"int32"},"vram_per_gpu_in_gb":{"type":"integer","format":"int32"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}}}
```

## DELETE /v2/instances/{instance\_id}

> Delete instance

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Cloud Bursting","description":"Cedana API for cloud bursting"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/instances/{instance_id}":{"delete":{"tags":["Cloud Bursting"],"summary":"Delete instance","operationId":"delete_instance","parameters":[{"name":"instance_id","in":"path","description":"Instance ID to delete","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Instance deleted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to delete instance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/instances/{instance\_id}/status

> Get instance status

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Cloud Bursting","description":"Cedana API for cloud bursting"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"InstanceStatus":{"type":"object","required":["instance_id","status","metadata"],"properties":{"created_at":{"type":["string","null"]},"instance_id":{"type":"string"},"ip_address":{"type":["string","null"]},"metadata":{},"ssh_port":{"type":["integer","null"],"format":"int32"},"ssh_user":{"type":["string","null"]},"status":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/instances/{instance_id}/status":{"get":{"tags":["Cloud Bursting"],"summary":"Get instance status","operationId":"get_instance_status","parameters":[{"name":"instance_id","in":"path","description":"Instance ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Instance status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceStatus"}}}},"404":{"description":"Instance not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to get status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Jobs (Slurm)

Cedana API for jobs (Slurm)

## List jobs

> Use query params to filter jobs

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Jobs (Slurm)","description":"Cedana API for jobs (Slurm)"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"SlurmJob":{"type":"object","required":["priority"],"properties":{"job_id":{"type":["string","null"]},"job_name":{"type":["string","null"]},"priority":{"type":"integer","format":"int32"},"state":{"type":["string","null"]}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/slurm/jobs":{"get":{"tags":["Jobs (Slurm)"],"summary":"List jobs","description":"Use query params to filter jobs","operationId":"list","responses":{"200":{"description":"Returns jobs","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SlurmJob"}}}}},"500":{"description":"Failed to connect/fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## List jobs (paginated)

> Use query params to filter jobs

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Jobs (Slurm)","description":"Cedana API for jobs (Slurm)"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"SlurmJob":{"type":"object","required":["priority"],"properties":{"job_id":{"type":["string","null"]},"job_name":{"type":["string","null"]},"priority":{"type":"integer","format":"int32"},"state":{"type":["string","null"]}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/slurm/jobs_paginated":{"get":{"tags":["Jobs (Slurm)"],"summary":"List jobs (paginated)","description":"Use query params to filter jobs","operationId":"list_paginated","parameters":[{"name":"offset","in":"query","description":"Number of records to skip (default: 0)","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"limit","in":"query","description":"Maximum number of records to return (default: 50, max: 100)","required":false,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Returns jobs","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SlurmJob"}}}}},"500":{"description":"Failed to connect/fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Nodes (Slurm)

Cedana API for nodes (Slurm)

## List nodes

> Use query params to filter nodes

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Nodes (Slurm)","description":"Cedana API for nodes (Slurm)"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"SlurmNode":{"type":"object","required":["id"],"properties":{"cpus":{"type":["integer","null"],"format":"int32"},"id":{"type":"string","format":"uuid"},"memory":{"type":["integer","null"],"format":"int64"},"name":{"type":["string","null"]},"status":{"type":["string","null"]}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/slurm/nodes":{"get":{"tags":["Nodes (Slurm)"],"summary":"List nodes","description":"Use query params to filter nodes","operationId":"list","responses":{"200":{"description":"Returns nodes","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SlurmNode"}}}}},"500":{"description":"Failed to connect/fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## List nodes (paginated)

> Use query params to filter nodes

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Nodes (Slurm)","description":"Cedana API for nodes (Slurm)"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"SlurmNode":{"type":"object","required":["id"],"properties":{"cpus":{"type":["integer","null"],"format":"int32"},"id":{"type":"string","format":"uuid"},"memory":{"type":["integer","null"],"format":"int64"},"name":{"type":["string","null"]},"status":{"type":["string","null"]}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/slurm/nodes_paginated":{"get":{"tags":["Nodes (Slurm)"],"summary":"List nodes (paginated)","description":"Use query params to filter nodes","operationId":"list_paginated","parameters":[{"name":"offset","in":"query","description":"Number of records to skip (default: 0)","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"limit","in":"query","description":"Maximum number of records to return (default: 50, max: 100)","required":false,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Returns nodes","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SlurmNode"}}}}},"500":{"description":"Failed to connect/fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Actions (Slurm)

Cedana API for actions (Slurm)

## POST /v2/slurm/checkpoint/job

> Checkpoint job

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Actions (Slurm)","description":"Cedana API for actions (Slurm)"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"CheckpointSlurmJob":{"type":"object","properties":{"action_id":{"type":["string","null"],"readOnly":true},"job_id":{"type":["string","null"]},"job_name":{"type":["string","null"]},"kind":{"$ref":"#/components/schemas/CheckpointKind"},"reason":{"$ref":"#/components/schemas/CheckpointReason"}}},"CheckpointKind":{"type":"string","enum":["simple","rootfs","rootfsonly"]},"CheckpointReason":{"type":"string","enum":["heartbeat","manual"]},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/slurm/checkpoint/job":{"post":{"tags":["Actions (Slurm)"],"summary":"Checkpoint job","operationId":"checkpoint_slurm_job","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckpointSlurmJob"}}},"required":true},"responses":{"200":{"description":"Returns the id for the task","content":{"text/plain":{"schema":{"type":"string"}}}},"404":{"description":"Failed to find checkpointable resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to connect/fetch from jobs table from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## POST /v2/slurm/restore/job

> Restore job

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Actions (Slurm)","description":"Cedana API for actions (Slurm)"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"RestoreSlurmJob":{"type":"object","required":["action_id","cluster_id","reason"],"properties":{"action_id":{"type":"string"},"cluster_id":{"type":"string"},"reason":{"$ref":"#/components/schemas/RestoreReason"}}},"RestoreReason":{"type":"string","enum":["nodeTermination","nodeUnschedulable","manual"]},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/slurm/restore/job":{"post":{"tags":["Actions (Slurm)"],"summary":"Restore job","operationId":"restore_slurm_job","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreSlurmJob"}}},"required":true},"responses":{"200":{"description":"Returns the checkpoint id for the new checkpoint","content":{"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"Failed create checkpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Failed create restore","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to connect/fetch from jobs table from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Clusters (Slurm)

Cedana API for clusters (Slurm)

## List clusters

> Use query params to filter clusters

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Clusters (Slurm)","description":"Cedana API for clusters (Slurm)"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"SlurmCluster":{"type":"object","required":["id","name","status"],"properties":{"id":{"type":"string","format":"uuid"},"metadata":{},"name":{"type":"string"},"status":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/slurm/clusters":{"get":{"tags":["Clusters (Slurm)"],"summary":"List clusters","description":"Use query params to filter clusters","operationId":"list","responses":{"200":{"description":"Returns clusters","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SlurmCluster"}}}}},"500":{"description":"Failed to connect/fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## List clusters (paginated)

> Use query params to filter clusters

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Clusters (Slurm)","description":"Cedana API for clusters (Slurm)"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"SlurmCluster":{"type":"object","required":["id","name","status"],"properties":{"id":{"type":"string","format":"uuid"},"metadata":{},"name":{"type":"string"},"status":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/slurm/clusters_paginated":{"get":{"tags":["Clusters (Slurm)"],"summary":"List clusters (paginated)","description":"Use query params to filter clusters","operationId":"list_paginated","parameters":[{"name":"offset","in":"query","description":"Number of records to skip (default: 0)","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"limit","in":"query","description":"Maximum number of records to return (default: 50, max: 100)","required":false,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Returns clusters","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SlurmCluster"}}}}},"500":{"description":"Failed to connect/fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Policy (Slurm)

Cedana API for policies (Slurm)

## List maintenance windows

> Returns all maintenance windows

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Policy (Slurm)","description":"Cedana API for policies (Slurm)"}],"security":[{"Auth Token":[]}],"components":{"securitySchemes":{},"schemas":{"SlurmMaintenanceWindow":{"type":"object","properties":{"created_at":{"type":["string","null"],"format":"date-time"},"end_time":{"type":["string","null"],"format":"date-time"},"id":{"type":["string","null"]},"nodes":{"type":["array","null"],"items":{"type":"string"}},"partitions":{"type":["array","null"],"items":{"type":"string"}},"reason":{"type":["string","null"]},"start_time":{"type":["string","null"],"format":"date-time"},"status":{"type":["string","null"]}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/slurm/maintenance_window":{"get":{"tags":["Policy (Slurm)"],"summary":"List maintenance windows","description":"Returns all maintenance windows","operationId":"list_maintenance_windows","responses":{"200":{"description":"Returns all SLURM maintenance windows","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SlurmMaintenanceWindow"}}}}},"500":{"description":"Failed to connect/fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## Create maintenance window

> Creates a new maintenance window for SLURM clusters

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Policy (Slurm)","description":"Cedana API for policies (Slurm)"}],"security":[{"Auth Token":[]}],"components":{"securitySchemes":{},"schemas":{"CreateMaintenanceWindow":{"type":"object","required":["start_time","end_time","reason"],"properties":{"end_time":{"type":"string","format":"date-time"},"nodes":{"type":["array","null"],"items":{"type":"string"}},"partitions":{"type":["array","null"],"items":{"type":"string"}},"reason":{"type":"string"},"start_time":{"type":"string","format":"date-time"},"status":{"type":["string","null"]}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/slurm/maintenance_window":{"post":{"tags":["Policy (Slurm)"],"summary":"Create maintenance window","description":"Creates a new maintenance window for SLURM clusters","operationId":"create_maintenance_window","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMaintenanceWindow"}}},"required":true},"responses":{"201":{"description":"Returns the maintenance window id for the new maintenance window","content":{"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to connect/execute request against database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## Get maintenance window

> Returns a specific maintenance window by ID

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Policy (Slurm)","description":"Cedana API for policies (Slurm)"}],"security":[{"Auth Token":[]}],"components":{"securitySchemes":{},"schemas":{"SlurmMaintenanceWindow":{"type":"object","properties":{"created_at":{"type":["string","null"],"format":"date-time"},"end_time":{"type":["string","null"],"format":"date-time"},"id":{"type":["string","null"]},"nodes":{"type":["array","null"],"items":{"type":"string"}},"partitions":{"type":["array","null"],"items":{"type":"string"}},"reason":{"type":["string","null"]},"start_time":{"type":["string","null"],"format":"date-time"},"status":{"type":["string","null"]}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/slurm/maintenance_window/{id}":{"get":{"tags":["Policy (Slurm)"],"summary":"Get maintenance window","description":"Returns a specific maintenance window by ID","operationId":"get_maintenance_window","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Returns the maintenance window","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SlurmMaintenanceWindow"}}}},"400":{"description":"Invalid UUID provided","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Maintenance window not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to connect/fetch from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## Update maintenance window

> Updates an existing maintenance window

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Policy (Slurm)","description":"Cedana API for policies (Slurm)"}],"security":[{"Auth Token":[]}],"components":{"securitySchemes":{},"schemas":{"UpdateMaintenanceWindow":{"type":"object","properties":{"end_time":{"type":["string","null"],"format":"date-time"},"nodes":{"type":["array","null"],"items":{"type":"string"}},"partitions":{"type":["array","null"],"items":{"type":"string"}},"reason":{"type":["string","null"]},"start_time":{"type":["string","null"],"format":"date-time"},"status":{"type":["string","null"]}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/slurm/maintenance_window/{id}":{"put":{"tags":["Policy (Slurm)"],"summary":"Update maintenance window","description":"Updates an existing maintenance window","operationId":"update_maintenance_window","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMaintenanceWindow"}}},"required":true},"responses":{"200":{"description":"Successfully updated maintenance window and returns id","content":{"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"Invalid UUID provided","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Maintenance window not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to connect/execute request against database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## Delete maintenance window

> Deletes a maintenance window by ID

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Policy (Slurm)","description":"Cedana API for policies (Slurm)"}],"security":[{"Auth Token":[]}],"components":{"securitySchemes":{},"schemas":{"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/slurm/maintenance_window/{id}":{"delete":{"tags":["Policy (Slurm)"],"summary":"Delete maintenance window","description":"Deletes a maintenance window by ID","operationId":"delete_maintenance_window","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully deleted maintenance window and returns id","content":{"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"Invalid UUID provided","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Maintenance window not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Failed to connect/execute request against database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Events

Cedana API for events

## List events

> Returns events within the specified time window, optionally filtered by operation or resource type.\
> The metadata field contains structured information about the event that can be used for filtering and display.

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Events","description":"Cedana API for events"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"Event":{"type":"object","description":"A single Event record with structured metadata","required":["id","status","operation","resource_type","message","metadata","source","timestamp"],"properties":{"id":{"type":"integer","format":"int64"},"message":{"type":"string"},"metadata":{},"operation":{"type":"string"},"resource_type":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"timestamp":{"type":"integer","minimum":0}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/events":{"get":{"tags":["Events"],"summary":"List events","description":"Returns events within the specified time window, optionally filtered by operation or resource type.\nThe metadata field contains structured information about the event that can be used for filtering and display.","operationId":"list_events","parameters":[{"name":"time","in":"query","description":"Time window in seconds (default: 3600 = 1 hour)","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"operation","in":"query","description":"Filter by operation (e.g., \"checkpoint\", \"restore\")","required":false,"schema":{"type":["string","null"]}},{"name":"resource_type","in":"query","description":"Filter by resource type (e.g., \"pod\", \"action\", \"checkpoint\")","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"description":"Returns list of events","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Event"}}}}},"500":{"description":"Failed to fetch events from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Metrics

Cedana API for metrics

## GET /v2/metrics/k8

> Get metrics (K8s)

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Metrics","description":"Cedana API for metrics"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"NodeResourceMetricList":{"type":"object","required":["name"],"properties":{"details":{"type":"array","items":{"$ref":"#/components/schemas/NodeMetricItem"}},"name":{"type":"string"}}},"NodeMetricItem":{"type":"object","required":["metric_name","collector","value","timestamp"],"properties":{"collector":{"type":"string"},"cpu_core":{"type":"string"},"cpu_mode":{"type":"string"},"filesystem":{"type":"string"},"metric_name":{"type":"string"},"mountpoint":{"type":"string"},"resource":{"type":["string","null"]},"timestamp":{"type":"integer","minimum":0},"value":{"type":"string"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/metrics/k8":{"get":{"tags":["Metrics"],"summary":"Get metrics (K8s)","operationId":"get_k8_metrics","responses":{"200":{"description":"Returns k8 metrics from duckdb","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NodeResourceMetricList"}}}}},"500":{"description":"Failed to connect/fetch from metrics table from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/metrics/slurm

> Get metrics (Slurm)

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Metrics","description":"Cedana API for metrics"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"SlurmMetric":{"type":"object","required":["id","name","timestamp"],"properties":{"counter_value":{"type":["number","null"],"format":"double"},"gauge_value":{"type":["number","null"],"format":"double"},"id":{"type":"integer","format":"int64"},"kind":{"type":["string","null"]},"name":{"type":"string"},"tags":{},"timestamp":{"type":"integer","minimum":0}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/metrics/slurm":{"get":{"tags":["Metrics"],"summary":"Get metrics (Slurm)","operationId":"get_slurm_metrics","responses":{"200":{"description":"Returns top 10 latest SLURM metrics from duckdb","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SlurmMetric"}}}}},"500":{"description":"Failed to connect/fetch from SLURM metrics table in database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/metrics/slurm/overview

> Get cluster overview (Slurm)

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Metrics","description":"Cedana API for metrics"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"SlurmClusterOverview":{"type":"object","required":["timestamp"],"properties":{"cpu_load":{"type":["number","null"],"format":"double"},"cpus_idle":{"type":["number","null"],"format":"double"},"cpus_total":{"type":["number","null"],"format":"double"},"mem_alloc":{"type":["number","null"],"format":"double"},"mem_free":{"type":["number","null"],"format":"double"},"mem_real":{"type":["number","null"],"format":"double"},"timestamp":{"type":"integer","minimum":0}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/metrics/slurm/overview":{"get":{"tags":["Metrics"],"summary":"Get cluster overview (Slurm)","operationId":"get_slurm_cluster_overview","responses":{"200":{"description":"Returns latest SLURM cluster overview statistics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SlurmClusterOverview"}}}},"500":{"description":"Failed to fetch SLURM cluster overview","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/metrics/slurm/overview/state

> Get state breakdown (Slurm)

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Metrics","description":"Cedana API for metrics"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"SlurmStateBreakdown":{"type":"object","required":["timestamp","cpus_by_state","nodes_by_state"],"properties":{"cpus_by_state":{"type":"array","items":{"$ref":"#/components/schemas/StateItem"}},"nodes_by_state":{"type":"array","items":{"$ref":"#/components/schemas/StateItem"}},"timestamp":{"type":"integer","minimum":0}}},"StateItem":{"type":"object","required":["state","value"],"properties":{"state":{"type":"string"},"value":{"type":"number","format":"double"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/metrics/slurm/overview/state":{"get":{"tags":["Metrics"],"summary":"Get state breakdown (Slurm)","operationId":"get_slurm_state_breakdown","responses":{"200":{"description":"Returns state breakdown for CPUs and nodes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SlurmStateBreakdown"}}}},"500":{"description":"Failed to fetch SLURM state breakdown","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/metrics/slurm/partitions

> Get partition statistics (Slurm)

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Metrics","description":"Cedana API for metrics"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"PartitionStats":{"type":"object","required":["partition_name","timestamp"],"properties":{"cpu_load":{"type":["number","null"],"format":"double"},"free_memory":{"type":["number","null"],"format":"double"},"idle_cpus":{"type":["number","null"],"format":"double"},"idle_nodes":{"type":["number","null"],"format":"double"},"partition_name":{"type":"string"},"real_memory":{"type":["number","null"],"format":"double"},"timestamp":{"type":"integer","minimum":0},"total_cpus":{"type":["number","null"],"format":"double"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/metrics/slurm/partitions":{"get":{"tags":["Metrics"],"summary":"Get partition statistics (Slurm)","operationId":"get_partition_stats","responses":{"200":{"description":"Returns list of all partitions with their statistics","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PartitionStats"}}}}},"500":{"description":"Failed to fetch partition statistics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## Get partition time series (Slurm)

> Returns CPU load and free memory time series for the specified partition over the last 10 data\
> points

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Metrics","description":"Cedana API for metrics"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"PartitionTimeSeries":{"type":"object","required":["partition_name","cpu_load","free_memory"],"properties":{"cpu_load":{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesDataPoint"}},"free_memory":{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesDataPoint"}},"partition_name":{"type":"string"}}},"TimeSeriesDataPoint":{"type":"object","required":["timestamp","value"],"properties":{"timestamp":{"type":"integer","minimum":0},"value":{"type":"number","format":"double"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/metrics/slurm/partitions/{name}/timeseries":{"get":{"tags":["Metrics"],"summary":"Get partition time series (Slurm)","description":"Returns CPU load and free memory time series for the specified partition over the last 10 data\npoints","operationId":"get_partition_timeseries","parameters":[{"name":"name","in":"path","description":"Partition name to query timeseries for","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Returns time series data for the specified partition","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartitionTimeSeries"}}}},"500":{"description":"Failed to fetch partition time series","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/metrics/slurm/timeseries/cpu-load

> Get CPU load time series (Slurm)

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Metrics","description":"Cedana API for metrics"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"TimeSeriesDataPoint":{"type":"object","required":["timestamp","value"],"properties":{"timestamp":{"type":"integer","minimum":0},"value":{"type":"number","format":"double"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/metrics/slurm/timeseries/cpu-load":{"get":{"tags":["Metrics"],"summary":"Get CPU load time series (Slurm)","operationId":"get_cpu_load_timeseries","responses":{"200":{"description":"Returns CPU load time series (last 10 data points)","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesDataPoint"}}}}},"500":{"description":"Failed to fetch CPU load time series","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```

## GET /v2/metrics/slurm/timeseries/memory

> Get memory time series (Slurm)

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Metrics","description":"Cedana API for metrics"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"MemoryTimeSeries":{"type":"object","required":["free_memory","allocated_memory"],"properties":{"allocated_memory":{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesDataPoint"}},"free_memory":{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesDataPoint"}}}},"TimeSeriesDataPoint":{"type":"object","required":["timestamp","value"],"properties":{"timestamp":{"type":"integer","minimum":0},"value":{"type":"number","format":"double"}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/metrics/slurm/timeseries/memory":{"get":{"tags":["Metrics"],"summary":"Get memory time series (Slurm)","operationId":"get_memory_timeseries","responses":{"200":{"description":"Returns memory time series (last 10 data points for free and allocated)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemoryTimeSeries"}}}},"500":{"description":"Failed to fetch memory time series","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Logs

Cedana API for logs

## GET /v2/logs/k8

> Get logs (K8s)

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"tags":[{"name":"Logs","description":"Cedana API for logs"}],"security":[{"Token":[]}],"components":{"securitySchemes":{"Token":{"type":"http","scheme":"bearer"}},"schemas":{"PodLogList":{"type":"object","required":["pod_name","namespace"],"properties":{"logs":{"type":"array","items":{"$ref":"#/components/schemas/PodLogEntry"}},"namespace":{"type":"string"},"pod_name":{"type":"string"}}},"PodLogEntry":{"type":"object","required":["container_name","message","timestamp"],"properties":{"container_name":{"type":"string"},"message":{"type":"string"},"stream":{"type":["string","null"]},"timestamp":{"type":"integer","minimum":0}}},"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}},"paths":{"/v2/logs/k8":{"get":{"tags":["Logs"],"summary":"Get logs (K8s)","operationId":"get_k8_logs","parameters":[{"name":"pod","in":"query","required":false,"schema":{"type":["string","null"]}},{"name":"limit","in":"query","required":false,"schema":{"type":["integer","null"],"format":"int64"}}],"responses":{"200":{"description":"Returns k8 pod logs from duckdb","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PodLogList"}}}}},"500":{"description":"Failed to connect/fetch from logs table from database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}
```


# Models

## The Action object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"Action":{"type":"object","required":["action_id","checkpoint_id","status","type","details","gpu","platform"],"properties":{"action_id":{"type":"string","format":"uuid"},"action_timestamp":{"type":["string","null"],"format":"date-time"},"checkpoint_completed_timestamp":{"type":["string","null"],"format":"date-time"},"checkpoint_id":{"type":"string","format":"uuid"},"details":{},"gpu":{"type":"string"},"node_name":{"type":["string","null"]},"platform":{"type":"string"},"reason":{"type":["string","null"]},"status":{"type":"string"},"total_duration":{"type":["integer","null"],"format":"int64"},"total_io":{"type":["integer","null"],"format":"int64"},"type":{"type":"string"}}}}}}
```

## The Alert object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"Alert":{"type":"object","properties":{"date_threshold":{"type":["string","null"]},"spend_threshold":{"type":["string","null"]}}}}}}
```

## The ApiError object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"ApiError":{"type":"object","description":"Standard error response for API endpoints","required":["message"],"properties":{"code":{"type":["string","null"],"description":"HTTP status code"},"details":{"description":"Optional additional error details"},"message":{"type":"string","description":"Error message describing what went wrong"}}}}}}
```

## The AutoDelete object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"AutoDelete":{"type":"object","properties":{"date_threshold":{"type":["string","null"]},"spend_threshold":{"type":["string","null"]}}}}}}
```

## The AvailableFilters object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"AvailableFilters":{"type":"object","required":["statuses","namespaces"],"properties":{"namespaces":{"type":"array","items":{"type":"string"}},"statuses":{"type":"array","items":{"type":"string"}}}}}}}
```

## The BurstingConfigStatus object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"BurstingConfigStatus":{"type":"string","enum":["not_configured","configured","invalid"]}}}}
```

## The BurstingStatus object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"BurstingStatus":{"type":"object","required":["status","message","can_use_bursting"],"properties":{"can_use_bursting":{"type":"boolean"},"message":{"type":"string"},"status":{"$ref":"#/components/schemas/BurstingConfigStatus"}}},"BurstingConfigStatus":{"type":"string","enum":["not_configured","configured","invalid"]}}}}
```

## The Checkpoint object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"Checkpoint":{"type":"object","description":"Checkpoint is basic unit for cedana service operation\nit stores all the information regarding the snapshot we can use to save and then restore state","required":["id","status","gpu","platform"],"properties":{"checksum":{"type":["string","null"]},"gpu":{"type":"string"},"id":{"type":"string","format":"uuid"},"info":{},"name":{"type":["string","null"]},"platform":{"type":"string"},"status":{"$ref":"#/components/schemas/CheckpointStatus"}}},"CheckpointStatus":{"type":"string","enum":["initializing","updated_info","possibly_uploaded","ready","deprecated"]}}}}
```

## The CheckpointInfo object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"CheckpointInfo":{"type":"object","required":["gpu","platform"],"properties":{"gpu":{"type":"string"},"info":{},"platform":{"type":"string"}}}}}}
```

## The CheckpointKind object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"CheckpointKind":{"type":"string","enum":["simple","rootfs","rootfsonly"]}}}}
```

## The CheckpointOperationStatus object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"CheckpointOperationStatus":{"type":"string","enum":["initialized","processing","checkpoint_created","ready","error","not_found"]}}}}
```

## The CheckpointOverrides object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"CheckpointOverrides":{"type":"object","properties":{"asynchronous":{"type":"boolean"},"compression":{"type":["string","null"]},"criu_opts":{"type":["string","null"]},"directory":{"type":["string","null"]},"streams":{"type":"integer","format":"int32"}}}}}}
```

## The CheckpointPod object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"CheckpointPod":{"type":"object","properties":{"action_id":{"type":["string","null"],"readOnly":true},"cluster_id":{"type":["string","null"]},"kind":{"$ref":"#/components/schemas/CheckpointKind"},"namespace":{"type":["string","null"]},"overrides":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/CheckpointOverrides"}]},"pod_id":{"type":["string","null"]},"pod_name":{"type":["string","null"]},"reason":{"$ref":"#/components/schemas/CheckpointReason"}}},"CheckpointKind":{"type":"string","enum":["simple","rootfs","rootfsonly"]},"CheckpointOverrides":{"type":"object","properties":{"asynchronous":{"type":"boolean"},"compression":{"type":["string","null"]},"criu_opts":{"type":["string","null"]},"directory":{"type":["string","null"]},"streams":{"type":"integer","format":"int32"}}},"CheckpointReason":{"type":"string","enum":["heartbeat","manual"]}}}}
```

## The CheckpointReason object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"CheckpointReason":{"type":"string","enum":["heartbeat","manual"]}}}}
```

## The CheckpointSlurmJob object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"CheckpointSlurmJob":{"type":"object","properties":{"action_id":{"type":["string","null"],"readOnly":true},"job_id":{"type":["string","null"]},"job_name":{"type":["string","null"]},"kind":{"$ref":"#/components/schemas/CheckpointKind"},"reason":{"$ref":"#/components/schemas/CheckpointReason"}}},"CheckpointKind":{"type":"string","enum":["simple","rootfs","rootfsonly"]},"CheckpointReason":{"type":"string","enum":["heartbeat","manual"]}}}}
```

## The CheckpointStatus object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"CheckpointStatus":{"type":"string","enum":["initializing","updated_info","possibly_uploaded","ready","deprecated"]}}}}
```

## The CheckpointStatusWithPodSpec object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"CheckpointStatusWithPodSpec":{"type":"object","required":["status","action_id"],"properties":{"action_id":{"type":"string"},"persistent_volume_claim":{},"pod_id":{"type":["string","null"]},"pod_metadata_spec":{},"pod_spec":{},"status":{"type":"string"}}}}}}
```

## The CheckpointSuccessInfo object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"CheckpointSuccessInfo":{"type":"object","properties":{"restore_path":{"type":["string","null"]}}}}}}
```

## The Cluster object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"Cluster":{"type":"object","required":["id","name","status"],"properties":{"id":{"type":"string","format":"uuid"},"last_sync":{"type":["string","null"],"format":"date-time"},"metadata":{},"name":{"type":"string"},"status":{"type":"string"}}}}}}
```

## The ClusterSyncRequest object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"ClusterSyncRequest":{"type":"object","properties":{"cluster_id":{"type":["string","null"],"format":"uuid"},"metadata":{},"resource":{"$ref":"#/components/schemas/K8sResource"}}},"K8sResource":{"oneOf":[{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["None"]}}},{"allOf":[{"$ref":"#/components/schemas/Pod"},{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["Pod"]}}}]},{"allOf":[{"$ref":"#/components/schemas/Node"},{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["Node"]}}}]},{"allOf":[{"$ref":"#/components/schemas/Job"},{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["Job"]}}}]}]},"Pod":{"type":"object","title":"Pod","description":"Entire json for the Kubernetes "},"Node":{"type":"object","title":"Node","description":"Entire json for the Kubernetes Node"},"Job":{"type":"object","title":"Job","description":"Entire json for the Kubernetes Job"}}}}
```

## The CreateClusterRequest object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"CreateClusterRequest":{"type":"object","description":"CreateClusterRequest is the request body for creating a cluster","required":["cluster_name"],"properties":{"cluster_name":{"type":"string"}}}}}}
```

## The CreateInstanceRequest object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"CreateInstanceRequest":{"type":"object","required":["cloud","region","shade_instance_type","shade_cloud","name"],"properties":{"alert":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Alert"}]},"auto_delete":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/AutoDelete"}]},"cloud":{"type":"string"},"envs":{"type":["array","null"],"items":{"$ref":"#/components/schemas/EnvironmentVariable"}},"launch_configuration":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/LaunchConfiguration"}]},"name":{"type":"string"},"os":{"type":["string","null"]},"region":{"type":"string"},"shade_cloud":{"type":"boolean"},"shade_instance_type":{"type":"string"},"ssh_key_id":{"type":["string","null"]},"tags":{"type":["array","null"],"items":{"type":"string"}},"template_id":{"type":["string","null"]},"volume_ids":{"type":["array","null"],"items":{"type":"string"}},"volume_mount":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/VolumeMount"}]}}},"Alert":{"type":"object","properties":{"date_threshold":{"type":["string","null"]},"spend_threshold":{"type":["string","null"]}}},"AutoDelete":{"type":"object","properties":{"date_threshold":{"type":["string","null"]},"spend_threshold":{"type":["string","null"]}}},"EnvironmentVariable":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string"},"value":{"type":"string"}}},"LaunchConfiguration":{"type":"object","required":["type"],"properties":{"docker_configuration":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/DockerConfiguration"}]},"script_configuration":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ScriptConfiguration"}]},"type":{"type":"string"}}},"DockerConfiguration":{"type":"object","required":["image"],"properties":{"args":{"type":["string","null"]},"envs":{"type":["array","null"],"items":{"$ref":"#/components/schemas/EnvironmentVariable"}},"image":{"type":"string"},"port_mappings":{"type":["array","null"],"items":{"$ref":"#/components/schemas/PortMapping"}},"registry_credentials":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RegistryCredentials"}]},"shared_memory_in_gb":{"type":["integer","null"],"format":"int32"},"volume_mounts":{"type":["array","null"],"items":{"$ref":"#/components/schemas/VolumeMapping"}}}},"PortMapping":{"type":"object","required":["host_port","container_port"],"properties":{"container_port":{"type":"integer","format":"int32"},"host_port":{"type":"integer","format":"int32"}}},"RegistryCredentials":{"type":"object","required":["username","password"],"properties":{"password":{"type":"string"},"username":{"type":"string"}}},"VolumeMapping":{"type":"object","required":["host_path","container_path"],"properties":{"container_path":{"type":"string"},"host_path":{"type":"string"}}},"ScriptConfiguration":{"type":"object","required":["base64_script"],"properties":{"base64_script":{"type":"string"}}},"VolumeMount":{"type":"object","properties":{"auto":{"type":["boolean","null"]}}}}}}
```

## The CreateInstanceResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"CreateInstanceResponse":{"type":"object","required":["instance_id","status","cloud_provider","region","instance_type"],"properties":{"cloud_provider":{"type":"string"},"instance_id":{"type":"string"},"instance_type":{"type":"string"},"region":{"type":"string"},"status":{"type":"string"}}}}}}
```

## The CreateMaintenanceWindow object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"CreateMaintenanceWindow":{"type":"object","required":["start_time","end_time","reason"],"properties":{"end_time":{"type":"string","format":"date-time"},"nodes":{"type":["array","null"],"items":{"type":"string"}},"partitions":{"type":["array","null"],"items":{"type":"string"}},"reason":{"type":"string"},"start_time":{"type":"string","format":"date-time"},"status":{"type":["string","null"]}}}}}}
```

## The DockerConfiguration object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"DockerConfiguration":{"type":"object","required":["image"],"properties":{"args":{"type":["string","null"]},"envs":{"type":["array","null"],"items":{"$ref":"#/components/schemas/EnvironmentVariable"}},"image":{"type":"string"},"port_mappings":{"type":["array","null"],"items":{"$ref":"#/components/schemas/PortMapping"}},"registry_credentials":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RegistryCredentials"}]},"shared_memory_in_gb":{"type":["integer","null"],"format":"int32"},"volume_mounts":{"type":["array","null"],"items":{"$ref":"#/components/schemas/VolumeMapping"}}}},"EnvironmentVariable":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string"},"value":{"type":"string"}}},"PortMapping":{"type":"object","required":["host_port","container_port"],"properties":{"container_port":{"type":"integer","format":"int32"},"host_port":{"type":"integer","format":"int32"}}},"RegistryCredentials":{"type":"object","required":["username","password"],"properties":{"password":{"type":"string"},"username":{"type":"string"}}},"VolumeMapping":{"type":"object","required":["host_path","container_path"],"properties":{"container_path":{"type":"string"},"host_path":{"type":"string"}}}}}}
```

## The EnvironmentVariable object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"EnvironmentVariable":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string"},"value":{"type":"string"}}}}}}
```

## The Event object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"Event":{"type":"object","description":"A single Event record with structured metadata","required":["id","status","operation","resource_type","message","metadata","source","timestamp"],"properties":{"id":{"type":"integer","format":"int64"},"message":{"type":"string"},"metadata":{},"operation":{"type":"string"},"resource_type":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"timestamp":{"type":"integer","minimum":0}}}}}}
```

## The FilteredJobResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"FilteredJobResponse":{"type":"object","required":["jobs","total_count","available_priorities"],"properties":{"available_priorities":{"type":"array","items":{"type":"integer","format":"int32"}},"jobs":{"type":"array","items":{"$ref":"#/components/schemas/JobFilterResponse"}},"total_count":{"type":"integer","format":"int64"}}},"JobFilterResponse":{"type":"object","required":["id","name","namespace","status","pod_count"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"namespace":{"type":"string"},"pod_count":{"type":"integer","format":"int64"},"priority":{"type":["integer","null"],"format":"int32"},"start_time":{"type":["string","null"]},"status":{"type":"string"}}}}}}
```

## The InstanceInfo object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"InstanceInfo":{"type":"object","required":["id","name","status","cloud_provider","region","instance_type"],"properties":{"cloud_provider":{"type":"string"},"created_at":{"type":["string","null"]},"id":{"type":"string"},"instance_type":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"},"status":{"type":"string"}}}}}}
```

## The InstanceStatus object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"InstanceStatus":{"type":"object","required":["instance_id","status","metadata"],"properties":{"created_at":{"type":["string","null"]},"instance_id":{"type":"string"},"ip_address":{"type":["string","null"]},"metadata":{},"ssh_port":{"type":["integer","null"],"format":"int32"},"ssh_user":{"type":["string","null"]},"status":{"type":"string"}}}}}}
```

## The InstanceType object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"InstanceType":{"type":"object","required":["cloud","shade_instance_type","cloud_instance_type","configuration","hourly_price","deployment_type","availability","boot_time"],"properties":{"availability":{"type":"array","items":{"$ref":"#/components/schemas/InstanceTypeAvailability"}},"boot_time":{"$ref":"#/components/schemas/InstanceTypeBootTime"},"cloud":{"type":"string"},"cloud_instance_type":{"type":"string"},"configuration":{"$ref":"#/components/schemas/InstanceTypeConfiguration"},"deployment_type":{"type":"string"},"hourly_price":{"type":"integer","format":"int32"},"shade_instance_type":{"type":"string"}}},"InstanceTypeAvailability":{"type":"object","required":["region","available","display_name"],"properties":{"available":{"type":"boolean"},"display_name":{"type":"string"},"region":{"type":"string"}}},"InstanceTypeBootTime":{"type":"object","required":["min_boot_in_sec","max_boot_in_sec"],"properties":{"max_boot_in_sec":{"type":"integer","format":"int32"},"min_boot_in_sec":{"type":"integer","format":"int32"}}},"InstanceTypeConfiguration":{"type":"object","required":["memory_in_gb","storage_in_gb","vcpus","num_gpus","gpu_type","interconnect","nvlink","vram_per_gpu_in_gb","os_options"],"properties":{"gpu_type":{"type":"string"},"interconnect":{"type":"string"},"memory_in_gb":{"type":"integer","format":"int32"},"num_gpus":{"type":"integer","format":"int32"},"nvlink":{"type":"boolean"},"os_options":{"type":"array","items":{"type":"string"}},"storage_in_gb":{"type":"integer","format":"int32"},"vcpus":{"type":"integer","format":"int32"},"vram_per_gpu_in_gb":{"type":"integer","format":"int32"}}}}}}
```

## The InstanceTypeAvailability object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"InstanceTypeAvailability":{"type":"object","required":["region","available","display_name"],"properties":{"available":{"type":"boolean"},"display_name":{"type":"string"},"region":{"type":"string"}}}}}}
```

## The InstanceTypeBootTime object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"InstanceTypeBootTime":{"type":"object","required":["min_boot_in_sec","max_boot_in_sec"],"properties":{"max_boot_in_sec":{"type":"integer","format":"int32"},"min_boot_in_sec":{"type":"integer","format":"int32"}}}}}}
```

## The InstanceTypeConfiguration object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"InstanceTypeConfiguration":{"type":"object","required":["memory_in_gb","storage_in_gb","vcpus","num_gpus","gpu_type","interconnect","nvlink","vram_per_gpu_in_gb","os_options"],"properties":{"gpu_type":{"type":"string"},"interconnect":{"type":"string"},"memory_in_gb":{"type":"integer","format":"int32"},"num_gpus":{"type":"integer","format":"int32"},"nvlink":{"type":"boolean"},"os_options":{"type":"array","items":{"type":"string"}},"storage_in_gb":{"type":"integer","format":"int32"},"vcpus":{"type":"integer","format":"int32"},"vram_per_gpu_in_gb":{"type":"integer","format":"int32"}}}}}}
```

## The Job object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"Job":{"type":"object","title":"Job","description":"Entire json for the Kubernetes Job"}}}}
```

## The JobFilter object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"JobFilter":{"type":"object","properties":{"namespace":{"type":["string","null"]},"priority":{"type":["integer","null"],"format":"int32"}}}}}}
```

## The JobFilterResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"JobFilterResponse":{"type":"object","required":["id","name","namespace","status","pod_count"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"namespace":{"type":"string"},"pod_count":{"type":"integer","format":"int64"},"priority":{"type":["integer","null"],"format":"int32"},"start_time":{"type":["string","null"]},"status":{"type":"string"}}}}}}
```

## The JobPodResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"JobPodResponse":{"type":"object","required":["id","name","namespace","status"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"namespace":{"type":"string"},"owner_reference":{"type":["string","null"]},"status":{"type":"string"}}}}}}
```

## The JobPodsResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"JobPodsResponse":{"type":"object","required":["job_id","job_name","pods","total_count"],"properties":{"job_id":{"type":"string","format":"uuid"},"job_name":{"type":"string"},"pods":{"type":"array","items":{"$ref":"#/components/schemas/JobPodResponse"}},"total_count":{"type":"integer","format":"int64"}}},"JobPodResponse":{"type":"object","required":["id","name","namespace","status"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"namespace":{"type":"string"},"owner_reference":{"type":["string","null"]},"status":{"type":"string"}}}}}}
```

## The JobPolicyStatus object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"JobPolicyStatus":{"type":"object","required":["policy_id","job_ids","tracked_pods","pod_count"],"properties":{"job_ids":{"type":"array","items":{"type":"string"}},"job_status":{"type":["string","null"]},"last_updated":{"type":["string","null"]},"pod_count":{"type":"integer","format":"int64"},"policy_id":{"type":"string"},"tracked_pods":{"type":"array","items":{"type":"string"}}}}}}}
```

## The JobPrioritiesResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"JobPrioritiesResponse":{"type":"object","required":["priorities","priority_counts"],"properties":{"priorities":{"type":"array","items":{"type":"integer","format":"int32"}},"priority_counts":{"type":"object","additionalProperties":{"type":"integer","format":"int64"},"propertyNames":{"type":"string"}}}}}}}
```

## The JobResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"JobResponse":{"type":"object","required":["id","name","namespace","status","age","monitored_by_policies","policy_count","pod_ids"],"properties":{"age":{"type":"string"},"completions":{"type":["integer","null"],"format":"int32"},"duration":{"type":["string","null"]},"id":{"type":"string","format":"uuid"},"monitored_by_policies":{"type":"array","items":{"type":"string"}},"name":{"type":"string"},"namespace":{"type":"string"},"pod_ids":{"type":"array","items":{"type":"string"}},"policy_count":{"type":"integer","format":"int64"},"priority":{"type":["integer","null"],"format":"int32"},"start_time":{"type":["string","null"]},"status":{"type":"string"}}}}}}
```

## The K8sResource object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"K8sResource":{"oneOf":[{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["None"]}}},{"allOf":[{"$ref":"#/components/schemas/Pod"},{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["Pod"]}}}]},{"allOf":[{"$ref":"#/components/schemas/Node"},{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["Node"]}}}]},{"allOf":[{"$ref":"#/components/schemas/Job"},{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["Job"]}}}]}]},"Pod":{"type":"object","title":"Pod","description":"Entire json for the Kubernetes "},"Node":{"type":"object","title":"Node","description":"Entire json for the Kubernetes Node"},"Job":{"type":"object","title":"Job","description":"Entire json for the Kubernetes Job"}}}}
```

## The LaunchConfiguration object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"LaunchConfiguration":{"type":"object","required":["type"],"properties":{"docker_configuration":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/DockerConfiguration"}]},"script_configuration":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ScriptConfiguration"}]},"type":{"type":"string"}}},"DockerConfiguration":{"type":"object","required":["image"],"properties":{"args":{"type":["string","null"]},"envs":{"type":["array","null"],"items":{"$ref":"#/components/schemas/EnvironmentVariable"}},"image":{"type":"string"},"port_mappings":{"type":["array","null"],"items":{"$ref":"#/components/schemas/PortMapping"}},"registry_credentials":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RegistryCredentials"}]},"shared_memory_in_gb":{"type":["integer","null"],"format":"int32"},"volume_mounts":{"type":["array","null"],"items":{"$ref":"#/components/schemas/VolumeMapping"}}}},"EnvironmentVariable":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string"},"value":{"type":"string"}}},"PortMapping":{"type":"object","required":["host_port","container_port"],"properties":{"container_port":{"type":"integer","format":"int32"},"host_port":{"type":"integer","format":"int32"}}},"RegistryCredentials":{"type":"object","required":["username","password"],"properties":{"password":{"type":"string"},"username":{"type":"string"}}},"VolumeMapping":{"type":"object","required":["host_path","container_path"],"properties":{"container_path":{"type":"string"},"host_path":{"type":"string"}}},"ScriptConfiguration":{"type":"object","required":["base64_script"],"properties":{"base64_script":{"type":"string"}}}}}}
```

## The MemoryTimeSeries object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"MemoryTimeSeries":{"type":"object","required":["free_memory","allocated_memory"],"properties":{"allocated_memory":{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesDataPoint"}},"free_memory":{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesDataPoint"}}}},"TimeSeriesDataPoint":{"type":"object","required":["timestamp","value"],"properties":{"timestamp":{"type":"integer","minimum":0},"value":{"type":"number","format":"double"}}}}}}
```

## The NamespacesResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"NamespacesResponse":{"type":"object","required":["namespaces"],"properties":{"namespaces":{"type":"array","items":{"type":"string"}}}}}}}
```

## The Node object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"Node":{"type":"object","title":"Node","description":"Entire json for the Kubernetes Node"}}}}
```

## The NodeMetricItem object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"NodeMetricItem":{"type":"object","required":["metric_name","collector","value","timestamp"],"properties":{"collector":{"type":"string"},"cpu_core":{"type":"string"},"cpu_mode":{"type":"string"},"filesystem":{"type":"string"},"metric_name":{"type":"string"},"mountpoint":{"type":"string"},"resource":{"type":["string","null"]},"timestamp":{"type":"integer","minimum":0},"value":{"type":"string"}}}}}}
```

## The NodeResourceMetricList object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"NodeResourceMetricList":{"type":"object","required":["name"],"properties":{"details":{"type":"array","items":{"$ref":"#/components/schemas/NodeMetricItem"}},"name":{"type":"string"}}},"NodeMetricItem":{"type":"object","required":["metric_name","collector","value","timestamp"],"properties":{"collector":{"type":"string"},"cpu_core":{"type":"string"},"cpu_mode":{"type":"string"},"filesystem":{"type":"string"},"metric_name":{"type":"string"},"mountpoint":{"type":"string"},"resource":{"type":["string","null"]},"timestamp":{"type":"integer","minimum":0},"value":{"type":"string"}}}}}}
```

## The NodeResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"NodeResponse":{"type":"object","required":["id","name","status","cluster_name","compute_type","instance_type","region"],"properties":{"cluster_name":{"type":"string"},"compute_type":{"type":"string"},"id":{"type":"string","format":"uuid"},"instance_type":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"},"status":{"type":"string"}}}}}}
```

## The PaginatedJobResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"PaginatedJobResponse":{"type":"object","required":["jobs","total_count"],"properties":{"available_filters":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/AvailableFilters"}]},"jobs":{"type":"array","items":{"$ref":"#/components/schemas/JobResponse"}},"total_count":{"type":"integer","format":"int64"}}},"AvailableFilters":{"type":"object","required":["statuses","namespaces"],"properties":{"namespaces":{"type":"array","items":{"type":"string"}},"statuses":{"type":"array","items":{"type":"string"}}}},"JobResponse":{"type":"object","required":["id","name","namespace","status","age","monitored_by_policies","policy_count","pod_ids"],"properties":{"age":{"type":"string"},"completions":{"type":["integer","null"],"format":"int32"},"duration":{"type":["string","null"]},"id":{"type":"string","format":"uuid"},"monitored_by_policies":{"type":"array","items":{"type":"string"}},"name":{"type":"string"},"namespace":{"type":"string"},"pod_ids":{"type":"array","items":{"type":"string"}},"policy_count":{"type":"integer","format":"int64"},"priority":{"type":["integer","null"],"format":"int32"},"start_time":{"type":["string","null"]},"status":{"type":"string"}}}}}}
```

## The PaginatedPodResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"PaginatedPodResponse":{"type":"object","required":["pods","total_count"],"properties":{"available_filters":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/AvailableFilters"}]},"pods":{"type":"array","items":{"$ref":"#/components/schemas/PodResponse"}},"total_count":{"type":"integer","format":"int64"}}},"AvailableFilters":{"type":"object","required":["statuses","namespaces"],"properties":{"namespaces":{"type":"array","items":{"type":"string"}},"statuses":{"type":"array","items":{"type":"string"}}}},"PodResponse":{"type":"object","required":["id","name","namespace","status","age","ready","node","restarts","monitored_by_policies"],"properties":{"age":{"type":"string"},"id":{"type":"string","format":"uuid"},"monitored_by_policies":{"type":"array","items":{"type":"string"}},"name":{"type":"string"},"namespace":{"type":"string"},"node":{"type":"string"},"ready":{"type":"string"},"restarts":{"type":"integer","format":"int32"},"start_time":{"type":["string","null"]},"status":{"type":"string"}}}}}}
```

## The PartitionStats object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"PartitionStats":{"type":"object","required":["partition_name","timestamp"],"properties":{"cpu_load":{"type":["number","null"],"format":"double"},"free_memory":{"type":["number","null"],"format":"double"},"idle_cpus":{"type":["number","null"],"format":"double"},"idle_nodes":{"type":["number","null"],"format":"double"},"partition_name":{"type":"string"},"real_memory":{"type":["number","null"],"format":"double"},"timestamp":{"type":"integer","minimum":0},"total_cpus":{"type":["number","null"],"format":"double"}}}}}}
```

## The PartitionTimeSeries object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"PartitionTimeSeries":{"type":"object","required":["partition_name","cpu_load","free_memory"],"properties":{"cpu_load":{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesDataPoint"}},"free_memory":{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesDataPoint"}},"partition_name":{"type":"string"}}},"TimeSeriesDataPoint":{"type":"object","required":["timestamp","value"],"properties":{"timestamp":{"type":"integer","minimum":0},"value":{"type":"number","format":"double"}}}}}}
```

## The Pod object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"Pod":{"type":"object","title":"Pod","description":"Entire json for the Kubernetes "}}}}
```

## The PodLogEntry object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"PodLogEntry":{"type":"object","required":["container_name","message","timestamp"],"properties":{"container_name":{"type":"string"},"message":{"type":"string"},"stream":{"type":["string","null"]},"timestamp":{"type":"integer","minimum":0}}}}}}
```

## The PodLogList object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"PodLogList":{"type":"object","required":["pod_name","namespace"],"properties":{"logs":{"type":"array","items":{"$ref":"#/components/schemas/PodLogEntry"}},"namespace":{"type":"string"},"pod_name":{"type":"string"}}},"PodLogEntry":{"type":"object","required":["container_name","message","timestamp"],"properties":{"container_name":{"type":"string"},"message":{"type":"string"},"stream":{"type":["string","null"]},"timestamp":{"type":"integer","minimum":0}}}}}}
```

## The PodResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"PodResponse":{"type":"object","required":["id","name","namespace","status","age","ready","node","restarts","monitored_by_policies"],"properties":{"age":{"type":"string"},"id":{"type":"string","format":"uuid"},"monitored_by_policies":{"type":"array","items":{"type":"string"}},"name":{"type":"string"},"namespace":{"type":"string"},"node":{"type":"string"},"ready":{"type":"string"},"restarts":{"type":"integer","format":"int32"},"start_time":{"type":["string","null"]},"status":{"type":"string"}}}}}}
```

## The PolicyDeleteRequest object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"PolicyDeleteRequest":{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"uuid"}}}}}}
```

## The PolicyJobInfo object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"PolicyJobInfo":{"type":"object","required":["id","name","namespace","status","pod_count"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"namespace":{"type":"string"},"pod_count":{"type":"integer","format":"int64"},"priority":{"type":["integer","null"],"format":"int32"},"status":{"type":"string"}}}}}}
```

## The PolicyJobsResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"PolicyJobsResponse":{"type":"object","required":["policy_id","affected_jobs","count"],"properties":{"affected_jobs":{"type":"array","items":{"$ref":"#/components/schemas/PolicyJobInfo"}},"count":{"type":"integer","format":"int64"},"policy_id":{"type":"string"}}},"PolicyJobInfo":{"type":"object","required":["id","name","namespace","status","pod_count"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"namespace":{"type":"string"},"pod_count":{"type":"integer","format":"int64"},"priority":{"type":["integer","null"],"format":"int32"},"status":{"type":"string"}}}}}}
```

## The PolicyPodResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"PolicyPodResponse":{"type":"object","required":["id","name","namespace","status"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"namespace":{"type":"string"},"status":{"type":"string"}}}}}}
```

## The PolicyRequest object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"PolicyRequest":{"type":"object","required":["heartbeat_time","resource_ids","cluster_id"],"properties":{"cluster_id":{"type":"string"},"heartbeat_time":{"type":"integer","format":"int64","minimum":0},"id":{"type":["string","null"]},"job_filter":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/JobFilter"}]},"policy_type":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/PolicyType"}]},"resource":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/PolicyResource"}]},"resource_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"resource_name":{"type":"string"},"runc_root":{"type":["string","null"]}}},"JobFilter":{"type":"object","properties":{"namespace":{"type":["string","null"]},"priority":{"type":["integer","null"],"format":"int32"}}},"PolicyType":{"type":"string","enum":["heartbeat"]},"PolicyResource":{"type":"string","enum":["pods","namespace","jobs"]}}}}
```

## The PolicyResource object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"PolicyResource":{"type":"string","enum":["pods","namespace","jobs"]}}}}
```

## The PolicyResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"PolicyResponse":{"type":"object","required":["id","status","policy_type","input","resource","resource_list","pod_count"],"properties":{"id":{"type":"string"},"input":{"type":"integer","format":"int64"},"job_count":{"type":["integer","null"],"format":"int64"},"pod_count":{"type":"integer","format":"int64"},"policy_type":{"type":"string"},"resource":{"type":"string"},"resource_list":{"type":"array","items":{"type":"string"}},"status":{"type":"string"},"timestamp":{"type":["string","null"],"format":"date-time"}}}}}}
```

## The PolicyType object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"PolicyType":{"type":"string","enum":["heartbeat"]}}}}
```

## The PortMapping object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"PortMapping":{"type":"object","required":["host_port","container_port"],"properties":{"container_port":{"type":"integer","format":"int32"},"host_port":{"type":"integer","format":"int32"}}}}}}
```

## The RegistryCredentials object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"RegistryCredentials":{"type":"object","required":["username","password"],"properties":{"password":{"type":"string"},"username":{"type":"string"}}}}}}
```

## The RestoreInfo object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"RestoreInfo":{"type":"object","properties":{"error":{"type":["string","null"]},"profiling":{},"total_duration":{"type":["integer","null"],"format":"int64"},"total_io":{"type":["integer","null"],"format":"int64"}}}}}}
```

## The RestoreOverrides object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"RestoreOverrides":{"type":"object","properties":{"criu_opts":{"type":["string","null"]},"pod_name":{"type":["string","null"]}}}}}}
```

## The RestorePod object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"RestorePod":{"type":"object","required":["action_id","reason"],"properties":{"action_id":{"type":"string"},"cluster_id":{"type":"string"},"overrides":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RestoreOverrides"}]},"reason":{"$ref":"#/components/schemas/RestoreReason"}}},"RestoreOverrides":{"type":"object","properties":{"criu_opts":{"type":["string","null"]},"pod_name":{"type":["string","null"]}}},"RestoreReason":{"type":"string","enum":["nodeTermination","nodeUnschedulable","manual"]}}}}
```

## The RestoreReason object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"RestoreReason":{"type":"string","enum":["nodeTermination","nodeUnschedulable","manual"]}}}}
```

## The RestoreSlurmJob object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"RestoreSlurmJob":{"type":"object","required":["action_id","cluster_id","reason"],"properties":{"action_id":{"type":"string"},"cluster_id":{"type":"string"},"reason":{"$ref":"#/components/schemas/RestoreReason"}}},"RestoreReason":{"type":"string","enum":["nodeTermination","nodeUnschedulable","manual"]}}}}
```

## The ScriptConfiguration object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"ScriptConfiguration":{"type":"object","required":["base64_script"],"properties":{"base64_script":{"type":"string"}}}}}}
```

## The SlurmCluster object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"SlurmCluster":{"type":"object","required":["id","name","status"],"properties":{"id":{"type":"string","format":"uuid"},"metadata":{},"name":{"type":"string"},"status":{"type":"string"}}}}}}
```

## The SlurmClusterOverview object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"SlurmClusterOverview":{"type":"object","required":["timestamp"],"properties":{"cpu_load":{"type":["number","null"],"format":"double"},"cpus_idle":{"type":["number","null"],"format":"double"},"cpus_total":{"type":["number","null"],"format":"double"},"mem_alloc":{"type":["number","null"],"format":"double"},"mem_free":{"type":["number","null"],"format":"double"},"mem_real":{"type":["number","null"],"format":"double"},"timestamp":{"type":"integer","minimum":0}}}}}}
```

## The SlurmJob object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"SlurmJob":{"type":"object","required":["priority"],"properties":{"job_id":{"type":["string","null"]},"job_name":{"type":["string","null"]},"priority":{"type":"integer","format":"int32"},"state":{"type":["string","null"]}}}}}}
```

## The SlurmMaintenanceWindow object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"SlurmMaintenanceWindow":{"type":"object","properties":{"created_at":{"type":["string","null"],"format":"date-time"},"end_time":{"type":["string","null"],"format":"date-time"},"id":{"type":["string","null"]},"nodes":{"type":["array","null"],"items":{"type":"string"}},"partitions":{"type":["array","null"],"items":{"type":"string"}},"reason":{"type":["string","null"]},"start_time":{"type":["string","null"],"format":"date-time"},"status":{"type":["string","null"]}}}}}}
```

## The SlurmMetric object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"SlurmMetric":{"type":"object","required":["id","name","timestamp"],"properties":{"counter_value":{"type":["number","null"],"format":"double"},"gauge_value":{"type":["number","null"],"format":"double"},"id":{"type":"integer","format":"int64"},"kind":{"type":["string","null"]},"name":{"type":"string"},"tags":{},"timestamp":{"type":"integer","minimum":0}}}}}}
```

## The SlurmNode object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"SlurmNode":{"type":"object","required":["id"],"properties":{"cpus":{"type":["integer","null"],"format":"int32"},"id":{"type":"string","format":"uuid"},"memory":{"type":["integer","null"],"format":"int64"},"name":{"type":["string","null"]},"status":{"type":["string","null"]}}}}}}
```

## The SlurmStateBreakdown object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"SlurmStateBreakdown":{"type":"object","required":["timestamp","cpus_by_state","nodes_by_state"],"properties":{"cpus_by_state":{"type":"array","items":{"$ref":"#/components/schemas/StateItem"}},"nodes_by_state":{"type":"array","items":{"$ref":"#/components/schemas/StateItem"}},"timestamp":{"type":"integer","minimum":0}}},"StateItem":{"type":"object","required":["state","value"],"properties":{"state":{"type":"string"},"value":{"type":"number","format":"double"}}}}}}
```

## The StateItem object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"StateItem":{"type":"object","required":["state","value"],"properties":{"state":{"type":"string"},"value":{"type":"number","format":"double"}}}}}}
```

## The StatusResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"StatusResponse":{"type":"object","required":["status"],"properties":{"details":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/CheckpointOperationStatus"}}},"CheckpointOperationStatus":{"type":"string","enum":["initialized","processing","checkpoint_created","ready","error","not_found"]}}}}
```

## The StatusesResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"StatusesResponse":{"type":"object","required":["statuses"],"properties":{"statuses":{"type":"array","items":{"type":"string"}}}}}}}
```

## The TimeSeriesDataPoint object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"TimeSeriesDataPoint":{"type":"object","required":["timestamp","value"],"properties":{"timestamp":{"type":"integer","minimum":0},"value":{"type":"number","format":"double"}}}}}}
```

## The TotalCountResponse object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"TotalCountResponse":{"type":"object","required":["total_count"],"properties":{"total_count":{"type":"integer","format":"int64"}}}}}}
```

## The UpdateMaintenanceWindow object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"UpdateMaintenanceWindow":{"type":"object","properties":{"end_time":{"type":["string","null"],"format":"date-time"},"nodes":{"type":["array","null"],"items":{"type":"string"}},"partitions":{"type":["array","null"],"items":{"type":"string"}},"reason":{"type":["string","null"]},"start_time":{"type":["string","null"],"format":"date-time"},"status":{"type":["string","null"]}}}}}}
```

## The VolumeMapping object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"VolumeMapping":{"type":"object","required":["host_path","container_path"],"properties":{"container_path":{"type":"string"},"host_path":{"type":"string"}}}}}}
```

## The VolumeMount object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"VolumeMount":{"type":"object","properties":{"auto":{"type":["boolean","null"]}}}}}}
```

## The WorkloadReq object

```json
{"openapi":"3.1.0","info":{"title":"Cedana API","version":"0.0.0-staging"},"components":{"schemas":{"WorkloadReq":{"type":"object","required":["cluster_id"],"properties":{"cluster_id":{"type":"string"},"cluster_name":{"type":["string","null"],"deprecated":true},"deployment":{},"job":{},"pod":{}}}}}}
```


# Cedana Daemon

<figure><img src="/files/eIjvd6wIFUJv5KrXZmsW" alt=""><figcaption></figcaption></figure>

Here, you will find information on running the Cedana daemon on your machine, system architecture, and the various features of both the daemon and CLI.

The daemon is designed to manage the lifecycle of processes/containers, including checkpoint/restore, in the larger Cedana system. However, it can be installed and used independently as a checkpoint/restore tool with its convenient defaults and a friendly command-line interface.

{% hint style="info" %}
For detailed documentation on our managed Kubernetes or the larger Cedana system, please see [here](https://docs.cedana.ai).
{% endhint %}

### Quick start

First, ensure that you have Cedana installed on your machine, and the daemon is running. See [installation](/daemon/get-started/installation).

#### Run a new job

```sh
cedana run process --attach test/workloads/date-loop.sh
```

Any process/container you spawn using `cedana run` creates a managed job. To view all managed jobs:

```sh
cedana ps
```

```
JOB               TYPE       PID  STATUS  GPU  CHECKPOINT  SIZE  LOG
personal_hopper9  process  32646  sleep   no                     [Attachable]
```

#### Checkpoint the job

```sh
cedana dump job personal_hopper9
```

If you view the jobs again, you will see that it was checkpointed:

```sh
JOB               TYPE       PID  STATUS  GPU  CHECKPOINT     SIZE     LOG
personal_hopper9  process  32646  halted  no   2 seconds ago  644 KiB
```

#### Restore the job

```sh
cedana restore job --attach personal_hopper9
```

For specific usage, check out the [guides](#guides). For information on architecture or to get started with contributing, check out the [developer guides](#developer-guides).

{% hint style="info" %}
For all available CLI options, see [CLI reference](/daemon/references/cli/cedana). Directly interacting with daemon is also possible through gRPC, see [API reference](/daemon/references/api).
{% endhint %}

### Get started

* [Quick start](#quick-start)
* [Installation](/daemon/get-started/installation)
* [Authentication](/daemon/get-started/authentication)
* [Configuration](/daemon/get-started/configuration)
* [Health checks](/daemon/get-started/health)
* [Plugins](/daemon/get-started/plugins)
* [Features](/daemon/get-started/features)

### Checkpoint/restore

* [Managed process/container](/daemon/checkpoint-restore/managed)
* [Checkpoint/restore basics](/daemon/checkpoint-restore/cr)
* [Checkpoint/restore with GPUs](/daemon/checkpoint-restore/cr-1)
* [Checkpoint/restore runc](/daemon/checkpoint-restore/cr-2)
* [Checkpoint/restore containerd](/daemon/checkpoint-restore/cr-2)
* [Checkpoint/restore streamer](/daemon/checkpoint-restore/cr-4)
* [Checkpoint/restore kubernetes](/daemon/checkpoint-restore/cr-5)

### Storage

* [Amazon S3](/daemon/storage/s3)
* [Google Cloud Storage](/daemon/storage/gcs)
* [Cedana Storage](/daemon/storage/cedana)

### Developer guides

* [Architecture](/daemon/developer-guides/architecture)
* [Profiling](/daemon/developer-guides/profiling)
* [Testing](/daemon/developer-guides/testing)
* [Writing plugins](/daemon/developer-guides/writing_plugins)

### References

* [CLI reference](/daemon/references/cli/cedana)
* [API reference](/daemon/references/api)


# Installation

For now, you can either install the daemon from source, or use the released binaries.

## Prerequisites

Since Cedana depends on [CRIU](https://criu.org), you will need to ensure its dependencies are installed.

#### Using apt (Ubuntu/Debian)

```sh
apt-get install -y libnet-dev libprotobuf-c-dev libnl-3-dev libbsd-dev libcap-dev libseccomp-dev libgpgme11-dev libnftables-dev
```

#### Using dnf/yum (Fedora/CentOS)

```sh
yum install -y libnet-devel protobuf-c-devel libnl3-devel libbsd-devel libcap-devel libseccomp-devel gpgme-devel nftables-devel
```

## Download latest release

{% hint style="info" %}
Cedana is supported on both linux/amd64 and linux/arm64 platforms.
{% endhint %}

Using public installer:

```sh
curl -fsSL https://github.com/cedana/cedana/releases/latest/download/install-release.sh | sudo -E bash
```

Using authenticated installer (see [Authentication](/daemon/get-started/authentication)):

```sh
export CEDANA_URL=https://myorg.cedana.ai/v1
export CEDANA_AUTH_TOKEN=your_auth_token

curl -fsSL "${CEDANA_URL}/install?version=latest" -H "Authorization: Bearer ${CEDANA_AUTH_TOKEN}" | sudo -E bash
```

Or, to install an alpha version:

```sh
export CEDANA_URL=https://myorg.cedana.ai/v1
export CEDANA_AUTH_TOKEN=your_auth_token

curl -fsSL "${CEDANA_URL}/install?build=alpha&version=main" -H "Authorization: Bearer ${CEDANA_AUTH_TOKEN}" | sudo -E bash
```

{% hint style="info" %}
You can also find the latest binaries at [releases](https://github.com/cedana/cedana/releases). Ensure `/usr/local/bin` is in your `PATH`.
{% endhint %}

## Build from source

Clone the [cedana repository](https://github.com/cedana/cedana) and navigate into it.

#### Build

```sh
make cedana
```

#### Install

```sh
make install
```

{% hint style="info" %}
Try `make help` to see all available targets.
{% endhint %}

## Install CRIU

{% hint style="success" %}
To install a plugin from the online registry, you need to be [authenticated](/daemon/get-started/authentication). See [plugins](/daemon/get-started/plugins) for more information.
{% endhint %}

A modified version of CRIU is shipped as a plugin for Cedana, so you don't need to install it separately. You can simply do:

```sh
sudo cedana plugin install criu
```

This version of CRIU is not a requirement for Cedana, but it is recommended for certain features, such as [checkpoint/restore streamer](/daemon/checkpoint-restore/cr-4).

{% hint style="info" %}
To install CRIU independently, see the [CRIU installation guide](https://criu.org/Installation).
{% endhint %}

## Start the daemon

{% hint style="warning" %}
The daemon requires root privileges for checkpoint/restore operations. Check the [CLI reference](/daemon/references/cli/cedana) for all options.
{% endhint %}

#### Direct

You can directly start the daemon with:

```sh
sudo cedana daemon start
```

#### Systemd

If you're a *systemd* user, you may also install it as a service (if built from source):

```sh
make install-service
```

{% hint style="info" %}
Try `make help` to see all available targets.
{% endhint %}

## Health check the daemon

The daemon can be health checked to ensure it fully supports the system and is ready to accept requests. See [health checks](/daemon/get-started/health) for more information.


# Authentication

Create an account at [auth.ui.cedana.com](https://auth.ui.cedana.com).

Once logged in, you'll be redirected to an account management page, where you can create an API key. If you've logged in via your organization's email address, you'll be able to create and manage organization-wide API keys as well.

Once you have obtained an API key, you must set it as the auth token in the [configuration](/daemon/get-started/configuration). You must have received a unique URL for your organization; if not, use `https://sandbox.cedana.ai`.

Once you have set both the auth token and URL, Cedana will automatically authenticate your requests.


# Configuration

Cedana configuration lives in `/etc/cedana/config.json`. You can initialize this file with default values by using the `--init-config` flag (e.g. `sudo cedana daemon start --init-config`). Any configuration in environment variables will override the default values when this file is initialized. You may also merge currently set environment variables into an existing configuration file with the `--merge-config` flag (e.g. `sudo cedana daemon start --merge-config`).

## Environment variables

You may also override the configuration file using environment variables. The environment variables are prefixed with `CEDANA_` and are in uppercase. For example, `Checkpoint.Dir` can be set with `CEDANA_CHECKPOINT_DIR`. Similarly, `Connection.URL` can be set with `CEDANA_CONNECTION_URL`, or its alias `CEDANA_URL`.

Each of the below fields can also be set through an environment variable with the same name, prefixed, and in uppercase. E.g. `Checkpoint.Dir` can be set with `CEDANA_CHECKPOINT_DIR`. The `env_aliases` tag below specifies alternative (alias) environment variable names (comma-separated).

## [Config](https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L10-L43)

{% @github-files/github-code-block url="<https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L10-L43>" %}

## [CRIU](https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L108-L117)

{% @github-files/github-code-block url="<https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L108-L117>" %}

## [Checkpoint](https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L69-L85)

{% @github-files/github-code-block url="<https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L69-L85>" %}

## [Client](https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L103-L106)

{% @github-files/github-code-block url="<https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L103-L106>" %}

## [Connection](https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L60-L67)

{% @github-files/github-code-block url="<https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L60-L67>" %}

## [DB](https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L87-L92)

{% @github-files/github-code-block url="<https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L87-L92>" %}

## [GPU](https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L119-L132)

{% @github-files/github-code-block url="<https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L119-L132>" %}

## [Plugins](https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L134-L143)

{% @github-files/github-code-block url="<https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L134-L143>" %}

## [Profiling](https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L94-L101)

{% @github-files/github-code-block url="<https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L94-L101>" %}

## [AWS](https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L145-L154)

{% @github-files/github-code-block url="<https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L145-L154>" %}

## [SLURM](https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L45-L58)

{% @github-files/github-code-block url="<https://github.com/cedana/cedana/blob/d7e70263c563d6b24367f105be4fdc4ecd13aeb1/pkg/config/types.go#L45-L58>" %}


# Health checks

Cedana can be health checked to ensure it fully supports the system and is ready to accept requests.

## Basic

To do a simple health check, ensure the daemon is running, and then run:

```sh
cedana daemon check
```

This just checks for basic checkpoint/restore capabilities on the host.

## Complete

To do a more complete health check, ensure the daemon is running, and then run:

```sh
cedana daemon check --full
```

This health checks all the installed plugins, including some optional checks. If you have installed plugins, you should see an output similar to:

```
CRIU
version                40100                                     ✔
features               available                                 ✔

GPU
status                 available                                 ✔
version                                                          ✔
device count           1                                         ✔
driver API             12040                                     ✔

STREAMER
version                v0.0.6                                    ✔
criu                   supported                                 ✔
pipe pages soft limit  16 KiB                                    •  For optimal performance, `echo 0 >
                                                                    /proc/sys/fs/pipe-user-pages-soft`
pipe pages hard limit  unlimited                                 ✔
pipe max size          1 MiB                                     •  For optimal performance, `echo 4194304 >
                                                                    /proc/sys/fs/pipe-max-size`

RUNC
version                v0.9.239-1-g9acef6f                       ✔
runc binary            available                                 ✔
runc version           1.2.4                                     ✔
runc spec              1.2.0                                     ✔
runc libseccomp        2.5.5                                     ✔

CONTAINERD
version                v0.9.239-1-g9acef6f                       ✔
containerd version     v2.0.1                                    ✔
containerd revision    88aa2f531d6c2922003cc7929e51daf1c14caa0a  ✔
containerd runtime     io.containerd.runc.v2                     ✔

Looks good, with 2 warning(s).

```

## Without daemon

You can also run the health check directly, without the daemon:

```sh
cedana check --full
```

Warnings are shown in yellow and are usually related to system configuration or performance. They are not critical but may affect the performance of Cedana.


# Plugins

Plugins extend the support of Cedana's checkpoint/restore to various container runtimes, GPUs, etc. Plugins can either be installed from the online registry or built locally.

## Online registry

{% hint style="success" %}
To access released plugins, you need to be authenticated. See [authentication](/daemon/get-started/authentication).
{% endhint %}

You can list all available plugins with:

```sh
cedana plugin list
```

```
PLUGIN      SIZE    STATUS     INSTALLED VERSION    AVAILABLE VERSION  PUBLISHED
criu        6 MiB   outdated   v3.9                 v4.0               one month ago
runc        35 MiB  installed  v0.9.239             v0.9.239           2 hours ago
containerd  38 MiB  installed  v0.9.239             v0.9.239           2 hours ago
crio        27 MiB  installed  v0.9.239             v0.9.239           2 hours ago
k8s         32 MiB  installed  v0.9.239             v0.9.239           2 hours ago
gpu         32 MiB  available                       v0.4.7             2 minutes ago
streamer    1 MiB   available                       v0.0.6             9 days ago

7 installed, 0 available
```

This will show you all the plugins that are available, installed, or outdated.

You can also list specific plugins by name & version:

```sh
cedana plugin list gpu@v0.5.0 streamer@v0.0.5
```

```sh
PLUGIN    SIZE    STATUS     INSTALLED VERSION  AVAILABLE VERSION  PUBLISHED
gpu       48 MiB  available                     v0.5.0             one day ago
streamer  6 MiB   available                     v0.0.5             4 months ago

0 installed, 2 available
```

## Locally built plugins

If plugins are built locally (in the current directory), running `cedana plugin list` in the current directory will show the locally built plugins instead:

```
PLUGIN      SIZE    STATUS     INSTALLED VERSION    AVAILABLE VERSION  PUBLISHED
criu        6 MiB   outdated   v3.9                 v4.0               one month ago
runc        35 MiB  installed  v0.9.239             local              2 hours ago
containerd  38 MiB  installed  v0.9.239             local              2 hours ago
crio        27 MiB  installed  v0.9.239             local              2 hours ago
k8s         32 MiB  installed  v0.9.239             local              2 hours ago
gpu         32 MiB  available                       v0.4.7             2 minutes ago
streamer    1 MiB   available                       v0.0.6             9 days ago

7 installed, 0 available
```

Notice the `LATEST VERSION` column shows `local` for locally built plugins.

Instead of depending on current directory, you can also specify the paths to search for locally built plugins by setting the `CEDANA_PLUGINS_LOCAL_SEARCH_PATH` (paths are colon-separated just like the `PATH` env var). This is convenient for developers who are working on multiple plugins at once.

{% hint style="info" %}
Check out the guide on [writing plugins](/daemon/developer-guides/writing_plugins) if you're interested in building your own plugins.
{% endhint %}

## Install

Once a plugin appears in the list, you can install it with:

```sh
sudo cedana plugin install <plugin>@<version> <plugin> ...
```

## Uninstall

To uninstall a plugin, use:

```sh
sudo cedana plugin remove <plugin> <plugin> ...
```

## Features

To see which features are supported by the installed plugins, use:

```sh
cedana plugin features
```

{% hint style="info" %}
See [features](/daemon/get-started/features) for more information.
{% endhint %}

## Health check

The full health check command will also check the health of all installed plugins. See [health checks](/daemon/get-started/health).

{% hint style="info" %}
Check out the [CLI reference](/daemon/references/cli/cedana_plugin) for all plugin-related subcommands.
{% endhint %}


# Features

Run `cedana features` (shorthand for `cedana plugin features`) to see the features currently supported by each plugin.

```
                  FEATURE  CLOUD-HYPERVISOR  RUNC  CONTAINERD  CRIO  KATA  STORAGE/CEDANA  STORAGE/S3  STORAGE/GCS  K8S  SLURM
             Dump command          •           ✔        ✔        •     •          •             •           •        •     —
          Restore command          •           ✔        ✔        •     •          •             •           •        •     —
              Run command          •           ✔        ✔        •     •          •             •           •        •     —
           Manage command          •           ✔        ✔        •     •          •             •           •        •     —
           Freeze command          •           ✔        ✔        •     •          •             •           •        •     —
         Unfreeze command          •           ✔        ✔        •     •          •             •           •        •     —
            Query command          •           ✔        ✔        •     •          •             •           •        ✔     —
        Helper command(s)          •           •        •        •     •          •             •           •        ✔     —

          Dump middleware          •           ✔        ✔        ✔     •          •             •           •        •     —
             Dump handler          •           •        •        •     •          •             •           •        •     —
       Dump VM middleware          ✔           •        •        •     ✔          •             •           •        •     —
          Dump VM handler          ✔           •        •        •     •          •             •           •        •     —
       Restore middleware          •           ✔        ✔        ✔     •          •             •           •        •     —
Restore middleware (late)          •           ✔        •        •     •          •             •           •        •     —
          Restore handler          •           •        ✔        •     •          •             •           •        •     —
    Restore VM middleware          ✔           •        •        •     ✔          •             •           •        •     —
       Restore VM handler          ✔           •        •        •     •          •             •           •        •     —
           Freeze handler          •           ✔        ✔        •     •          •             •           •        •     —
         Unfreeze handler          •           ✔        ✔        •     •          •             •           •        •     —

              Run handler          •           ✔        ✔        ✔     •          •             •           •        •     —
 Run handler (serverless)          •           ✔        •        •     •          •             •           •        •     —
           Run middleware          •           ✔        ✔        ✔     •          •             •           •        •     —
    Run middleware (late)          •           •        •        •     •          •             •           •        •     —
           Manage handler          •           ✔        ✔        •     •          •             •           •        •     —
       Custom kill signal          •           ✔        ✔        •     ✔          •             •           •        •     —
           Custom cleanup          •           ✔        ✔        •     •          •             •           •        •     —
            Custom reaper          •           ✔        •        •     •          •             •           •        •     —

         GPU interception          •           ✔        ✔        •     •          •             •           •        •     —
 GPU interception restore          •           ✔        ✔        •     •          •             •           •        •     —
              GPU tracing          •           ✔        ✔        •     •          •             •           •        •     —
      GPU tracing restore          •           ✔        ✔        •     •          •             •           •        •     —

       Checkpoint storage          •           •        •        •     •          ✔             ✔           •        •     —
            Query handler          •           ✔        ✔        •     •          •             •           •        ✔     —
            Health checks          •           ✔        ✔        •     ✔          ✔             ✔           •        •     —

✔ = implemented, • = unimplemented, — = not installed, ✖ = incompatible
Not showing external plugins: criu, criu/cuda, gpu, gpu/tracer, streamer, containerd/runtime-runc
```

When developing a new plugin, or adding a feature to a plugin, it's helpful to see more information on any compatibility issues. Use `cedana features --errors` to see any incompatibility errors.

{% hint style="info" %}
Check out the guide on [writing plugins](/daemon/developer-guides/writing_plugins) for more information.
{% endhint %}

{% hint style="info" %}
Check out the [CLI reference](/daemon/references/cli/cedana_plugin) for all plugin-related subcommands.
{% endhint %}


# Managed process/container

The Cedana daemon is designed to manage the entire lifecycle of a process/container, including checkpoint/restore, in the larger Cedana system.

Managed processes/containers are those that are spawned using `cedana run` ([CLI reference](/daemon/references/cli/cedana_run)). This command creates a managed job, which can be checkpointed and restored using `cedana dump job` and `cedana restore job` subcommands.

<figure><img src="/files/ZMZr0Ult95slMIDbhRWX" alt=""><figcaption></figcaption></figure>

By default, jobs are stored in a local DB (in `/tmp`). You may set the `db.path` in [configuration](/daemon/get-started/configuration) to change the path to persist it across restarts. If you're authenticated, you may set the `db.remote` to `true` in [configuration](/daemon/get-started/configuration) to use a remote DB at your specified Cedana endpoint instead.

## Create a new job

To run a new managed job:

```sh
cedana run <type> ...
```

Where `<type>` can be `process`, `containerd`, `runc`, etc. See [features](/daemon/get-started/features) for all plugins that support running managed jobs.

For example, to run a new managed process:

```sh
cedana run process --jid <job_id> -- echo "Hello, world!"
```

The `--jid` flag is optional, and if not provided, a random job ID will be generated.

## Manage an existing job

It's also possible to start managing an existing process/container:

```sh
cedana manage <type> ...
```

Where `<type>` can be `process`, `containerd`, `runc`, etc. See [features](/daemon/get-started/features) for all plugins that support managing existing jobs.

For example, to manage an existing process:

```sh
cedana manage process <PID> [args...]
```

## Manage an upcoming job

It's also possible to start managing an upcoming process/container:

```sh
cedana manage --upcoming <type> ...
```

Where `<type>` can be `process`, `containerd`, `runc`, etc. See [features](/daemon/get-started/features) for all plugins that support managing upcoming jobs. The manage command will block and wait for the process/container to become available.

For example, to manage an existing runc container:

```sh
cedana manage --upcoming runc <container-id> [args...]
```

## List managed jobs

The subcommand `cedana job` has many subcommands such as `list`, `kill`,m `delete`, etc. Check the [CLI reference](/daemon/references/cli/cedana_job) for all available subcommands.

```sh
cedana job list
```

```
JOB             TYPE      PID  STATUS  GPU  CHECKPOINT  SIZE  LOG
used_gould8     process  5336  halted  yes                    /var/log/cedana-output-used_gould8.log
clean_davinci7  runc     3680  halted  no
easy_tu9        process  3892  halted  yes
```

`cedana ps` is a shorthand for `cedana job list`.

## Attach I/O

To attach to the I/O of a job, use the `--attach` flag:

```sh
cedana run <type> --attach ...
```

This will attach the standard input, output, and error streams to the terminal, including the job's exit status. Press `Ctrl+C` to detach, and the job will continue running in the background.

If you list the jobs, you will see that the job is attachable:

```
JOB             TYPE      PID  STATUS  GPU  CHECKPOINT  SIZE  LOG
clean_davinci7  runc     3680  halted  no                     [Attachable]
```

To attach to the job again, use the `cedana job attach` subcommand:

```sh
cedana job attach <job_id>
```

Or the generic `cedana attach` if you want to attach using the job's PID:

```sh
cedana attach <PID>
```

If you want to make a job attachable, but not attach to it immediately, you can use the `--attachable` flag:

```sh
cedana run <type> --attachable ...
```

## View job logs

By default, the jobs stdout/stderr are stored in the `/var/log/` directory. If you do `cedana job list`, you will see the path to the log file.

```
JOB             TYPE      PID  STATUS  GPU  CHECKPOINT  SIZE  LOG
used_gould8     process  5336  halted  yes                    /var/log/cedana-output-used_gould8.log
```

You can also pass a custom log path. See [CLI reference](/daemon/references/cli/cedana_run) for `cedana run` subcommand.

If the job has attachable I/O, it will appear as such:

```
JOB             TYPE      PID  STATUS  GPU  CHECKPOINT  SIZE  LOG
used_gould8     process  5336  halted  yes                    [Attachable]
```

## Checkpoint/restore

Once the daemon has started managing a job, it can be checkpointed and restored using the `cedana dump job` and `cedana restore job` subcommands. See [managed checkpoint/restore basics](/daemon/checkpoint-restore/cr#managed-checkpoint-restore) for more information.

## Checkpoint/restore with GPUs

GPU C/R support is also available for managed jobs. Check out the [checkpoint/restore with GPUs](/daemon/checkpoint-restore/cr-1) guide for more information.


# Checkpoint/restore basics

The Cedana daemon is designed to checkpoint/restore processes as well as containers.

## Checkpoint

To checkpoint:

```sh
cedana dump <type> ...
```

Where `<type>` can be `process`, `containerd`, `runc`, `job`, etc. See [features](/daemon/get-started/features) for all plugins that support checkpointing.

For example, to checkpoint a process:

```sh
cedana dump process <PID> --dir /tmp
```

A `--dir` flag can be used to specify the *parent* directory where the checkpoint will be stored. If not provided, the checkpoint will be stored in the default checkpoint directory as specified in the [configuration](/daemon/get-started/configuration), or in `/tmp` if not set. You may also specify a `--name` flag to give a custom name to the checkpoint file.

{% hint style="info" %}
See [CLI reference](/daemon/references/cli/cedana_dump_process) for all available options for process checkpoint.
{% endhint %}

## Restore

### Using daemon

```sh
cedana restore <type> ...
```

Where `<type>` can be `process`, `containerd`, `runc`, `job`, etc. See [features](/daemon/get-started/features) for all plugins that support restoring.

For example, to restore a process:

```sh
cedana restore process --path <path-to-dump>
```

Notice that for restore the flag is called `--path` instead of `--dir` (as in dump), this is because it can be a path to a compressed file, or to a directory if not compressed.

### Without daemon

{% hint style="warning" %}
Not all plugins support restoring without the daemon. Please check [features](/daemon/get-started/features) for details.
{% endhint %}

It's also possible to restore directly as a child of the current shell command without the daemon:

```sh
cedana restore process --path <path-to-dump> --no-server
```

This is useful for scenarios where you want to restore a process as a child of the current shell, for example, to restore a shell process and interact with it directly.

{% hint style="info" %}
See [CLI reference](/daemon/references/cli/cedana_restore_process) for all available options for process restore.
{% endhint %}

## Managed checkpoint/restore

As explained in [managed process/container](/daemon/checkpoint-restore/managed), a job can be of any type, and thus can be checkpointed and restored using the `cedana dump job` and `cedana restore job` subcommands.

The `cedana dump/restore job` subcommands have the same options as their non-managed counterparts, but with pretty good defaults. For e.g., the `--path` flag is not required for `cedana restore job`, as the checkpoint path is stored in the job metadata.

If you do `cedana job list` after checkpointing a job, you will see the latest checkpoint time and size:

```
JOB             TYPE       PID  STATUS  GPU  CHECKPOINT     SIZE     LOG
famous_hopper7  process  32675  halted  no   3 seconds ago  610 KiB
```

To view all checkpoints for a job, use `cedana job checkpoints <job_id>`:

```
ID                                    TIME                 SIZE     PATH
141d52b4-0d1f-4911-a0da-abfab3358d16  2025-02-19 12:32:01  586 KiB  /tmp/dump-process-famous_hopper7-1739986321.tar
386dcce4-a29d-4acb-ab03-12d41b7c42ce  2025-02-19 12:30:36  610 KiB  /tmp/dump-process-famous_hopper7-1739986236.tar
```

## Compression

The `cedana dump` subcommand supports a `--compression` flag to specify the compression algorithm to use. For example:

```sh
cedana dump process <PID> --dir /tmp --name xyz --compression gzip
```

This will create a compressed checkpoint file with the path `/tmp/xyz.tar.gz`. The `--name` flag is optional, and if not provided, the daemon will choose a unique name based on some metadata.

When restoring, the daemon will automatically detect the compression algorithm used and decompress the file. Simply provide the path to the compressed file:

```sh
cedana restore process --path /tmp/xyz.tar.gz
```

Supported values for `--compression` are `none`, `tar`, `gzip`, `lz4`, `zlib`.

{% hint style="info" %}
You may also specify the default compression algorithm in the [configuration](/daemon/get-started/configuration).
{% endhint %}

## Remote storage

Cedana supports checkpointing/restoring to/from remote storage, through storage plugins. Check out the following guides for specific remote storage:

* [Amazon S3](/daemon/storage/s3)
* [Google Cloud Storage](/daemon/storage/gcs)
* [Cedana Storage](/daemon/storage/cedana)

## Advanced

* [Checkpoint/restore with GPUs](/daemon/checkpoint-restore/cr-1)
* [Checkpoint/restore runc](/daemon/checkpoint-restore/cr-2)
* [Checkpoint/restore containerd](/daemon/checkpoint-restore/cr-2)
* [Checkpoint/restore streamer](/daemon/checkpoint-restore/cr-4)
* [Checkpoint/restore kubernetes](/daemon/checkpoint-restore/cr-5)


# Checkpoint/restore with GPUs

{% hint style="warning" %}
Checkpoint/restore with GPUs is currently only supported for NVIDIA GPUs.
{% endhint %}

## Prerequisites

1. Create an account with Cedana, to get access to the GPU plugin. See [authentication](/daemon/get-started/authentication).
2. Set the Cedana URL & authentication token in the [configuration](/daemon/get-started/configuration).
3. Install a GPU plugin.

* **Option 1: GPU Plugin**

  The GPU plugin is Cedana's proprietary plugin for high performance GPU checkpoint/restore that supports multi-process/node. If unavailable to you, check option 2.

  ```sh
  sudo cedana plugin install gpu
  ```
* **Option 2: CRIU CUDA Plugin**

  The CRIU CUDA plugin (CRIUgpu) is developed by the CRIU community and uses the [NVIDIA CUDA checkpoint utility](https://github.com/NVIDIA/cuda-checkpoint) under the hood.

  ```sh
  sudo cedana plugin install criu/cuda
  ```

4. Ensure the daemon is running, see [installation](/daemon/get-started/installation).
5. Do a health check to ensure the plugin is ready, see [health checks](/daemon/get-started/health).

Check out [Cedana vs. CRIUgpu for GPU Checkpoint/Restore](/articles/cedana-vs.-criu-cuda-for-gpu-checkpoint-restore) for a performance comparison between the two plugins.

|                | Min driver | Max driver | Multi-GPU | Multi-process | Arch         |
| -------------- | ---------- | ---------- | --------- | ------------- | ------------ |
| **Cedana GPU** | 452        | 570        | ✅         | ✅             | amd64, arm64 |
| **CRIU CUDA**  | 570        | 570        | ✅         | ❌             | amd64        |

## Usage (GPU plugin)

### Single process

{% hint style="info" %}
Cedana GPU checkpoint/restore is only possible for managed processes/containers, i.e., those that are spawned using `cedana run --gpu-enabled` or managed using `cedana manage --gpu-enabled` (see [managed process/container](/daemon/checkpoint-restore/managed)). If you don't want to run as a managed process/container, you can use `ceadna run --no-server` that will spawn the process/container as a child process of the CLI instead of the daemon.
{% endhint %}

1. You may clone the [cedana-samples repository](https://github.com/cedana/cedana-samples) for some example GPU workloads.
2. Run a process with GPU support:

```sh
cedana run process --attach --gpu-enabled --jid <job_id> -- cedana-samples/gpu_smr/vector_add
```

3. Checkpoint:

```sh
cedana dump job <job_id>
```

4. Restore:

```sh
cedana restore job --attach <job_id>
```

### Multi-process/node

For multi-process/node workloads, you just need to specify the `--gpu-freeze-type` option during dump. If the workload is multi-process/multi-node and using [NCCL](https://developer.nvidia.com/nccl), use the `nccl` option.

```sh
cedana dump job <job_id> --gpu-freeze-type nccl
```

You can then restore as usual. You may also set the default GPU freeze type in the [configuration](/daemon/get-started/configuration).

## Usage (CRIU CUDA plugin)

### Single process

You can checkpoint/restore normally as you do for CPU workloads. See [checkpoint/restore basics](/daemon/checkpoint-restore/cr).

### Multi-process/node

This is currently not supported. You should use the Cedana GPU plugin for multi-process/node workloads.

{% hint style="info" %}
For all available CLI options, see [CLI reference](/daemon/references/cli/cedana). Directly interacting with daemon is also possible through gRPC, see [API reference](/daemon/references/api).
{% endhint %}


# Checkpoint/restore runc

## Prerequisites

1. Create an account with Cedana, to get access to the GPU plugin. See [authentication](/daemon/get-started/authentication).
2. Set the Cedana URL & authentication token in the [configuration](/daemon/get-started/configuration).
3. Install the **runc** plugin with `sudo cedana plugin install runc`.
4. Ensure the daemon is running, see [installation](/daemon/get-started/installation).
5. Do a health check to ensure the plugin is ready, see [health checks](/daemon/get-started/health).

## Basic

1. Run a new runc container, for example:

```sh
sudo runc run --detach <container_id> --bundle ./my-bundle
```

2. Checkpoint:

```sh
cedana dump runc <container_id> --dir <dump-dir>
```

3. Restore:

```sh
cedana restore runc --bundle ./my-bundle --path <path-to-dump>
```

## Managed

1. Run a new managed runc container:

```sh
cedana run runc --attach --jid <job_id> --bundle ./my-bundle
```

2. Checkpoint:

```sh
cedana dump job <job_id>
```

3. Restore:

```sh
cedana restore job --attach <job_id>
```

## GPU support

Just like for processes, as explained in [checkpoint/restore with GPUs](/daemon/checkpoint-restore/cr-1), GPU support is also available for managed runc containers.

1. Run a new managed runc container with GPU support:

```sh
cedana run runc --attach --gpu-enabled --jid <job_id> --bundle ./my-bundle
```

2. Checkpoint:

```sh
cedana dump job <job_id>
```

3. Restore:

```sh
cedana restore job --attach <job_id>
```

{% hint style="info" %}
For all available CLI options, see [CLI reference](/daemon/references/cli/cedana). Directly interacting with daemon is also possible through gRPC, see [API reference](/daemon/references/api).
{% endhint %}


# Checkpoint/restore containerd

## Prerequisites

1. Create an account with Cedana, to get access to the containerd plugin. See [authentication](/daemon/get-started/authentication).
2. Set the Cedana URL & authentication token in the [configuration](/daemon/get-started/configuration).
3. Install the **containerd** plugin with `sudo cedana plugin install containerd`.
4. Ensure the daemon is running, see [installation](/daemon/get-started/installation).
5. Do a health check to ensure the plugin is ready, see [health checks](/daemon/get-started/health).

## Basic

1. Run a new containerd container, for example:

```sh
sudo ctr run docker.io/library/nginx:latest <container_id>
```

2. Checkpoint:

```sh
cedana dump containerd <container_id> --dir <dump-dir>
```

3. Restore is currently WIP. However, you can restore this container as a runc container, see [checkpoint/restore runc](/daemon/checkpoint-restore/cr-2).

## Managed

1. Run a new managed containerd container:

```sh
cedana run containerd --attach --jid <job_id> --image docker.io/library/nginx:latest
```

2. Checkpoint:

```sh
cedana dump job <job_id>
```

3. Restore is currently WIP.

## GPU support

Just like for processes, as explained in [checkpoint/restore with GPUs](/daemon/checkpoint-restore/cr-1), GPU support is also available for managed containerd containers.

1. Run a new managed containerd container with GPU support:

```sh
cedana run containerd --attach --gpu-enabled --jid <job_id> --image docker.io/library/nginx:latest
```

2. Checkpoint:

```sh
cedana dump job <job_id>
```

3. Restore is currently WIP.

## Rootfs

To include the rootfs in the checkpoint, additionally set the `--image` flag with a new image name. For example:

```sh
cedana dump containerd <container_id> --dir <dump-dir> --image <new-image-name>
```

For checkpoint *only* the rootfs, set the `--rootfs-only` flag. For example:

```sh
cedana dump containerd <container_id> --dir <dump-dir> --image <new-image-name> --rootfs-only
```

{% hint style="info" %}
For all available CLI options, see [CLI reference](/daemon/references/cli/cedana). Directly interacting with daemon is also possible through gRPC, see [API reference](/daemon/references/api).
{% endhint %}


# Checkpoint/restore streamer

The Cedana daemon supports checkpoint/restore via high-performance low-overhead streaming. It's powered by the [streamer plugin](https://github.com/cedana/cedana-image-streamer), which is a fork of CRIU's [image streamer](https://github.com/checkpoint-restore/criu-image-streamer).

{% hint style="info" %}
Real benefits of streaming are realized only when checkpointing and restoring to/from a remote location. See [remote storage](#remote-storage).
{% endhint %}

## Prerequisites

1. Create an account with Cedana, to get access to the streamer plugin. See [authentication](/daemon/get-started/authentication).
2. Set the Cedana URL & authentication token in the [configuration](/daemon/get-started/configuration).
3. Install the streamer plugin with `sudo cedana plugin install streamer`.
4. Ensure the daemon is running, see [installation](/daemon/get-started/installation).
5. Do a health check to ensure the plugin is ready, see [health checks](/daemon/get-started/health).

## Checkpoint

The `cedana dump` subcommand supports a `--streams <n>` flag, where `n` is the number of parallel streams to use (minimum of 2). For example:

```sh
cedana dump process <pid> --streams 4
```

This will directly stream the checkpoint to a directory, using 4 parallel streams. You will notice that the checkpoint directory contains 4 separate image files:

```
-rw-r--r-- 1 root root 145K Feb 19 15:13 img-0
-rw-r--r-- 1 root root  17K Feb 19 15:13 img-1
-rw-r--r-- 1 root root 209K Feb 19 15:13 img-2
-rw-r--r-- 1 root root 188K Feb 19 15:13 img-3
```

## Restore

The `cedana restore` will automatically detect if the checkpoint was taken with streaming, and will use the same number of streams to restore. For example:

```sh
cedana restore process --path <path-to-dump>
```

## Compression

All compression algorithms supported for basic checkpoint/restore are supported. See [compression](/daemon/checkpoint-restore/cr#compression) for more information.

## Remote storage

Cedana supports streaming to/from remote storage, through storage plugins. Check out the following guides for specific remote storage:

* [Amazon S3](/daemon/storage/s3)
* [Google Cloud Storage](/daemon/storage/gcs)
* [Cedana Storage](/daemon/storage/cedana)

{% hint style="info" %}
The daemon simply reads/writes from the filesystem. This is also the case for streaming, with the additional requirement that the underlying filesystem must be [POSIX-compliant](https://grimoire.carcano.ch/blog/posix-compliant-filesystems/). To checkpoint/restore to/from a remote directory, you can also use a FUSE-based filesystem mount backed by your network storage. For Amazon's S3, check out [s3fs-fuse](https://github.com/s3fs-fuse/s3fs-fuse).
{% endhint %}

## Enable by default

To enable streaming by default, set the `Checkpoint.Stream` field in the [configuration](/daemon/get-started/configuration) to the desired number of parallel streams. Zero means no streaming.

{% hint style="info" %}
For all available CLI options, see [CLI reference](/daemon/references/cli/cedana). Directly interacting with daemon is also possible through gRPC, see [API reference](/daemon/references/api).
{% endhint %}


# Checkpoint/restore kubernetes

Checkpoint/restore of Kubernetes workloads is powered by the Cedana daemon too, but it's not as simple as a single container checkpoint/restore.

For detailed documentation on our managed Kubernetes or the larger Cedana system, please see [here](https://docs.cedana.ai).


# Amazon S3

Checkpoint/restore to/from Amazon S3 is as seamless as it is to/from local storage.

{% hint style="info" %}
Both [general-purpose](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html) and [directory](https://docs.aws.amazon.com/AmazonS3/latest/userguide/directory-buckets-overview.html) S3 buckets are supported. Use directory buckets for better performance for the cost of lower availability. See [Amazon S3 Storage Classes](https://aws.amazon.com/s3/storage-classes/#topic-0) for more details.
{% endhint %}

## Prerequisites

1. Create an account with Cedana, to get access to the GPU plugin. See [authentication](/daemon/get-started/authentication).
2. Set the Cedana URL & authentication token in the [configuration](/daemon/get-started/configuration).
3. Install the **storage/s3** plugin with `sudo cedana plugin install storage/s3`.
4. Set AWS credentials in the [configuration](/daemon/get-started/configuration).
5. Ensure the daemon is running, see [installation](/daemon/get-started/installation).
6. Do a health check to ensure the plugin is ready, see [health checks](/daemon/get-started/health).

## Checkpoint

To checkpoint to an S3 bucket, simply set the `--dir` to a path that starts with `s3://<bucket>`, for example:

```sh
cedana dump ... --dir s3://my-bucket/path/to/dir
```

For example, as explained in [managed checkpoint/restore](/daemon/checkpoint-restore/cr#managed-checkpoint-restore), to checkpoint a job to S3:

```sh
cedana dump job my-job-1 --dir s3://checkpoints-bucket
```

If you do `cedana job list`, you will see the latest checkpoint:

```
ID            TIME                 SIZE     PATH
my-job-1      2025-02-19 12:30:36  -        s3://checkpoints-bucket/dump-job.tar
```

## Restore

Similarly, to restore from an S3 bucket, simply set the `--path` to your checkpoint path in S3, for example:

```sh
cedana restore ... --path s3://my-bucket/path/to/dump.tar
```

For example, as explained in [managed checkpoint/restore](/daemon/checkpoint-restore/cr#managed-checkpoint-restore), to restore a job from S3:

```sh
cedana restore job --attach my-job-1
```

This will automatically restore from the latest checkpoint for `my-job-1`, which is stored in S3.

## Compression

All compression algorithms supported for basic checkpoint/restore are supported. See [compression](/daemon/checkpoint-restore/cr#compression) for more information.

{% hint style="info" %}
For better performance when remote checkpointing/restoring large processes/containers, especially when using [checkpoint/restore with GPUs](/daemon/checkpoint-restore/cr-1), always use compression. The `lz4` compression algorithm is a good compromise between speed and compression ratio.
{% endhint %}

## Streaming

High-performance low-overhead streaming of checkpoints is also supported by the `storage/s3` plugin. Follow instructions on [checkpoint/restore streamer](/daemon/checkpoint-restore/cr#checkpoint-restore-streamer) to use streaming with this plugin.

## Enable by default

To enable streaming by default, set the `Checkpoint.Dir` field in the [configuration](/daemon/get-started/configuration) to a path that starts with `s3://`.

## See also

* [Google Cloud Storage](/daemon/storage/gcs)
* [Cedana Storage](/daemon/storage/cedana)


# Google Cloud Storage

Checkpoint/restore to/from Google Cloud Storage is currently WIP.

## See also

* [Amazon S3](/daemon/storage/s3)
* [Cedana Storage](/daemon/storage/cedana)


# Cedana Storage

Cedana Storage is a global storage for checkpoints that is backed by multiple cloud providers, providing low latency and high availability. This is the fastest way to get started with remote checkpoint/restore, as you only need to be [authenticated](/daemon/get-started/authentication) with Cedana.

{% hint style="warning" %}
If you're using Cedana on an Amazon EKS cluster, you'll likely get higher performance using [Amazon S3](/daemon/storage/s3). Similarly, if you're using Cedana on a GKE cluster, you'll likely get higher performance using [Google Cloud Storage](/daemon/storage/gcs).
{% endhint %}

## Prerequisites

1. Create an account with Cedana, to get access to the GPU plugin. See [authentication](/daemon/get-started/authentication).
2. Set the Cedana URL & authentication token in the [configuration](/daemon/get-started/configuration).
3. Install the **storage/cedana** plugin with `sudo cedana plugin install storage/cedana`.
4. Ensure the daemon is running, see [installation](/daemon/get-started/installation).
5. Do a health check to ensure the plugin is ready, see [health checks](/daemon/get-started/health).

## Checkpoint

To checkpoint to Cedana Storage, simply set the `--dir` to a path that starts with `cedana://<path>`, for example:

```sh
cedana dump ... --dir cedana://path/to/dir
```

For example, as explained in [managed checkpoint/restore](/daemon/checkpoint-restore/cr#managed-checkpoint-restore), to checkpoint a job to Cedana Storage:

```sh
cedana dump job my-job-1 --dir cedana://my-checkpoints
```

If you do `cedana job list`, you will see the latest checkpoint:

```
ID            TIME                 SIZE     PATH
my-job-1      2025-02-19 12:30:36  -        cedana://my-checkpoints/dump-job.tar
```

## Restore

Similarly, to restore from Cedana Storage, simply set the `--path` to your checkpoint path in Cedana Storage, for example:

```sh
cedana restore ... --path cedana://path/to/dump.tar
```

For example, as explained in [managed checkpoint/restore](/daemon/checkpoint-restore/cr#managed-checkpoint-restore), to restore a job from Cedana Storage:

```sh
cedana restore job --attach my-job-1
```

This will automatically restore from the latest checkpoint for `my-job-1`, which is stored in Cedana Storage.

## Compression

All compression algorithms supported for basic checkpoint/restore are supported. See [compression](/daemon/checkpoint-restore/cr#compression) for more information.

{% hint style="info" %}
For better performance when remote checkpointing/restoring large processes/containers, especially when using [checkpoint/restore with GPUs](/daemon/checkpoint-restore/cr-1), always use compression. The `lz4` compression algorithm is a good compromise between speed and compression ratio.
{% endhint %}

## Streaming

High-performance low-overhead streaming of checkpoints is also supported by the `storage/cedana` plugin. Follow instructions on [checkpoint/restore streamer](/daemon/checkpoint-restore/cr#checkpoint-restore-streamer) to use streaming with this plugin.

## Enable by default

To enable streaming by default, set the `Checkpoint.Dir` field in the [configuration](/daemon/get-started/configuration) to a path that starts with `cedana://`.

## See also

* [Amazon S3](/daemon/storage/s3)
* [Google Cloud Storage](/daemon/storage/gcs)


# Architecture

The design mostly follows what's illustrated below. Below is a simplified runtime view of invoking `cedana dump runc ...`:

<figure><img src="https://github.com/user-attachments/assets/9e6842bd-03d1-4889-b23e-11dcbe7ea25f" alt="Cedana&#x27;s plugin architecture"><figcaption><p>Cedana's plugin architecture</p></figcaption></figure>

1. The subcommand `cedana dump runc ...` is only available if the runc plugin is exporting the `DumpCmd` symbol (check `plugins/runc/main.go`). The runc plugin only sets the *specific* flags it needs (such as `--id`, `--root`), while the parent cmd handles all the common flags, and sending the request to the daemon.
2. The daemon receives the request, and runs it through a list of adapters, before finally sending it to CRIU. If the request's `type` is `runc`, it will use the `DumpMiddleware` exported by the runc plugin and plug it in the adapter chain. See `internal/cedana/dump.go`:

{% @github-files/github-code-block url="<https://github.com/cedana/cedana/blob/3a6a8000e207f7480dbda977eb9181f09b514cc4/internal/cedana/dump.go#L30-L51>" %}

3. This way, the runc plugin only implements the specifics of the runc runtime, while the daemon handles the common logic, and invoking CRIU.
4. The same pattern is followed for `dump`, `restore`, `run`, and `manage`.

## Features

Symbols that can be exported by a plugin are well-typed and are defined in `pkg/features/supported.go`. A `feature` implements a convenient method called `IfAvailable(do func(), filter ...string)`, which is the *only* method you will ever need to access a feature exported by a plugin. An example usage:

{% @github-files/github-code-block url="<https://github.com/cedana/cedana/blob/3a6a8000e207f7480dbda977eb9181f09b514cc4/internal/cedana/dump.go#L98-L104>" %}

A useful helper command is `cedana features` (alias of `cedana plugin features`), which lists all the features supported by all the plugins. This is useful for debugging, when implementing a new feature, or when you want to know what a plugin supports. Use the `--errors` flag to also output all errors encountered while loading the plugins.

{% hint style="info" %}
See [features](/daemon/get-started/features) for more info.
{% endhint %}

![Output from cedana plugin features](https://github.com/user-attachments/assets/90578e51-c7f1-44b9-b056-dc1cbdd89785)


# Profiling

The profiling system tries to be contextual and *invisible*. Profiling data is sent as [gRPC Metadata](https://grpc.io/docs/guides/metadata/). To enable, set `Profiling.Enabled=true` in [configuration](/daemon/get-started/configuration).

Since each adapter to a request (see [architecture](/daemon/developer-guides/architecture)) is a well-defined single-responsibility function, it makes sense to profile each of them. When enabled, the daemon will profile each adapter, and send back flattened data as a gRPC trailer. For readability's sake, this profiling is completely invisible and handled by the adapter logic in `pkg/types/adapter.go` (also see `pkg/types/timer.go`). This flattened data is parsed by the `cmd` package and displayed as shown below. An example out of `cedana dump containerd ...` when profiling is enabled:

![Output from a cedana dump containerd](https://github.com/user-attachments/assets/977a5423-e4d3-423e-89af-653c72bfce03)

Above, you can see complete flow of the request before it reaches CRIU's dump function, including *which* plugin (2nd column) the adapter belongs to. For `containerd`, you can see that the request is largely handled by the low-level runtime `runc`'s plugin. The second table above shows a compressed view of the same data, with only the total time spent in each plugin/category. Note that, above there are some components that are executed concurrently, e.g. `rootfs`, so the time you see in the (flattened) data above is only the time spent *waiting* for `rootfs` to finish.

In many cases, we may need to add more context to this data, or add more components to it. Helpers defined in `pkg/profiling/timing.go` can be used. A good example is adding a new component to the `compression` category in `internal/server/filesystem/dump_adapters.go` as seen above:

{% @github-files/github-code-block url="<https://github.com/cedana/cedana/blob/9fa628d372cd71ba3bfea3437c9e3e4dc0a0bbe5/internal/cedana/filesystem/dump_adapters.go#L113-L115>" %}

These helpers use the passed `context` to store profiling data. If the `context` already has parent profiling data, the data is added as a component to the parent.

{% hint style="info" %}
Behind the scenes, if metrics is enabled ([configuration](/daemon/get-started/configuration) `Metrics=true`), this data is also captured as OTel spans.
{% endhint %}


# Testing

Tests are configured to run inside a Docker container, ridding the need for tedious setup scripts. This allows for testing locally, during development, without affecting the environment.

The test directory looks like this:

```
test
├── regression
│   ├── basic.bats
│   ├── cr.bats
│   ├── run.bats
│   ├── manage.bats
│   ├── profiling.bats
│   ├── plugins
│   │   ├── containerd.bats
│   │   ├── crio.bats
│   │   ├── gpu.bats
│   │   ├── gpu_runc.bats
│   │   ├── gpu_streamer.bats
│   │   ├── streamer.bats
│   │   ├── streamer_runc.bats
│   │   └── runc.bats
│   ├── helpers
│   │   └── ...
└── workloads
```

Tests are grouped by functionality, and each plugin has its own test file.

## Running tests

Running `make help` you'll see the following test commands:

```sh
Testing
  test                      Run all tests (PARALLELISM=<n>, GPU=[0|1], TAGS=<tags>, RETRIES=<retries>, DEBUG=[0|1])
  test-unit                 Run unit tests (with benchmarks)
  test-regression           Run regression tests (PARALLELISM=<n>, GPU=[0|1], TAGS=<tags>, RETRIES=<retries>, DEBUG=[0|1])
  test-k8s                  Run kubernetes e2e tests (PARALLELISM=<n>, GPU=[0|1], TAGS=<tags>, RETRIES=<retries>, DEBUG=[0|1], ...)
  test-enter                Enter the test environment
  test-enter-cuda           Enter the test environment (CUDA)
  test-k9s                  Enter k9s in the test environment

```

When running any of the test commands locally, the tests are automatically run inside a Docker container using `cedana/cedana-test:latest` or `cedana/cedana-test:cuda` if `GPU=1`. GPU tests are skipped by default, unless `GPU=1` is set.

## Running GPU tests

Use `GPU=1` to include all GPU tests. If `GPU=0`, any tests that require GPU-support automatically get skipped. You may want to specify a low `PARALLELISM` value when running GPU tests, as each test requires a significant amount of RAM.

## Running specific tests

Use `TAGS` to filter tests by tags. For example, `make test-regression TAGS=runc` will run all tests tagged with `runc`. `make test-regression TAGS=runc,gpu` will run all tests tagged with `runc` and `gpu`. If `gpu` tag is included, you must set `GPU=1` to run the tests, otherwise they will be skipped.

## Test modes

Each test command above runs the test suite **two times**, in different modes:

1. Unique daemon & DB instance for each test.
2. Single persistent daemon & DB instance across a test suite.

This is to allow catching bugs that may arise due to the daemon's state being persisted across tests.

Each test command is also configured to run parallel-y, configured by the `PARALLELISM` variable passed to the test command. E.g. `make test-regression PARALLELISM=4` will run at most 4 tests in parallel at a time.

For mode 1, parallelism offers no benefits apart from fast execution time, as each test is completely isolated. However, for mode 2, parallelism may shed light on bugs in the daemon when it's handling multiple requests concurrently.


# Writing plugins

Plugins are currently part of Cedana's source tree ([here](https://github.com/cedana/cedana/tree/main/plugins)) and are built and released together with the main Cedana binary. This guide will walk you through the process of writing a plugin for Cedana.

Check out [features](/daemon/get-started/features) to see which features are currently supported by each plugin.


# CLI


# cedana

Root command for Cedana

## Synopsis

```
 ________  _______   ________  ________  ________   ________
|\   ____\|\  ___ \ |\   ___ \|\   __  \|\   ___  \|\   __  \
\ \  \___|\ \   __/|\ \  \_|\ \ \  \|\  \ \  \\ \  \ \  \|\  \
 \ \  \    \ \  \_|/_\ \  \ \\ \ \   __  \ \  \\ \  \ \   __  \
  \ \  \____\ \  \_|\ \ \  \_\\ \ \  \ \  \ \  \\ \  \ \  \ \  \
   \ \_______\ \_______\ \_______\ \__\ \__\ \__\\ \__\ \__\ \__\
    \|_______|\|_______|\|_______|\|__|\|__|\|__| \|__|\|__|\|__|
```

Instance Brokerage, Orchestration and Migration System. Property of Cedana, Corp.

v0.9.279

## Options

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
  -h, --help                help for cedana
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana attach](/daemon/references/cli/cedana_attach) - Attach stdin/out/err to a process/container
* [cedana check](https://github.com/cedana/cedana/blob/main/docs/references/cli/cedana_check.md) - Health check
* [cedana checkpoint](/daemon/references/cli/cedana_checkpoint) - Manage job checkpoints (alias of `job checkpoint`)
* [cedana checkpoints](/daemon/references/cli/cedana_checkpoints) - List all checkpoints for a job (alias of `checkpoint list <JID>`)
* [cedana completion](/daemon/references/cli/cedana_completion) - Generate the autocompletion script for the specified shell
* [cedana daemon](/daemon/references/cli/cedana_daemon) - Manage the daemon
* [cedana delete](/daemon/references/cli/cedana_delete) - Delete a managed process/container (job) (alias of `job delete <JID>...`)
* [cedana dump](/daemon/references/cli/cedana_dump) - Dump a container/process
* [cedana dump-vm](https://github.com/cedana/cedana/blob/main/docs/references/cli/cedana_dump-vm.md) - Dump a VM
* [cedana exec](/daemon/references/cli/cedana_exec) - Run a managed process (job) (alias of `run process <path> [args...]`)
* [cedana features](/daemon/references/cli/cedana_features) - Show feature matrix of plugins (alias of `plugin features [plugin]...`)
* [cedana freeze](https://github.com/cedana/cedana/blob/main/docs/references/cli/cedana_freeze.md) - Freeze a container/process
* [cedana job](/daemon/references/cli/cedana_job) - Manage jobs
* [cedana jobs](/daemon/references/cli/cedana_jobs) - List all managed processes/containers (jobs) (alias of `job list`)
* [cedana k8s](https://github.com/cedana/cedana/blob/main/docs/references/cli/cedana_k8s.md) - Helper for setting up and running in Kubernetes
* [cedana kill](/daemon/references/cli/cedana_kill) - Kill a managed process/container (job) (alias of `job kill <JID>...`)
* [cedana manage](/daemon/references/cli/cedana_manage) - Manage an existing/upcoming process/container (create a job)
* [cedana plugin](/daemon/references/cli/cedana_plugin) - Manage plugins
* [cedana plugins](/daemon/references/cli/cedana_plugins) - List plugins (specify plugin @ to filter) (alias of `plugin list [plugin]...`)
* [cedana ps](/daemon/references/cli/cedana_ps) - List all managed processes/containers (jobs) (alias of `job list`)
* [cedana query](/daemon/references/cli/cedana_query) - Query containers/processes
* [cedana restore](/daemon/references/cli/cedana_restore) - Restore a container/process
* [cedana run](/daemon/references/cli/cedana_run) - Run a managed process/container (create a job)
* [cedana unfreeze](https://github.com/cedana/cedana/blob/main/docs/references/cli/cedana_unfreeze.md) - Unfreeze a container/process


# cedana attach

Attach stdin/out/err to a process/container

```
cedana attach <PID> [flags]
```

## Options

```
  -h, --help   help for attach
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana](/daemon/references/cli/cedana) - Root command for Cedana


# cedana check

Health check

```
cedana check [flags]
```

## Options

```
      --full   perform a full check (including plugins)
  -h, --help   help for check
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana](/daemon/references/cli/cedana) - Root command for Cedana


# cedana checkpoint

Manage job checkpoints (alias of `job checkpoint`)

## Synopsis

(alias of `job checkpoint`)

## Options

```
  -h, --help   help for checkpoint
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana](/daemon/references/cli/cedana) - Root command for Cedana
* [cedana checkpoint inspect](https://github.com/cedana/cedana/blob/main/docs/references/cli/cedana_checkpoint_inspect.md) - Inspect a checkpoint
* [cedana checkpoint list](https://github.com/cedana/cedana/blob/main/docs/references/cli/cedana_checkpoint_list.md) - List all checkpoints for a job


# cedana checkpoints

List all checkpoints for a job (alias of `checkpoint list <JID>`)

## Synopsis

(alias of `checkpoint list <JID>`)

```
cedana checkpoints <JID> [flags]
```

## Options

```
  -h, --help   help for list
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana](/daemon/references/cli/cedana) - Root command for Cedana


# cedana completion

Generate the autocompletion script for the specified shell

## Synopsis

Generate the autocompletion script for cedana for the specified shell. See each sub-command's help for details on how to use the generated script.

## Options

```
  -h, --help   help for completion
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana](/daemon/references/cli/cedana) - Root command for Cedana
* [cedana completion bash](/daemon/references/cli/cedana_completion_bash) - Generate the autocompletion script for bash
* [cedana completion fish](/daemon/references/cli/cedana_completion_fish) - Generate the autocompletion script for fish
* [cedana completion powershell](/daemon/references/cli/cedana_completion_powershell) - Generate the autocompletion script for powershell
* [cedana completion zsh](/daemon/references/cli/cedana_completion_zsh) - Generate the autocompletion script for zsh


# cedana completion bash

Generate the autocompletion script for bash

## Synopsis

Generate the autocompletion script for the bash shell.

This script depends on the 'bash-completion' package. If it is not installed already, you can install it via your OS's package manager.

To load completions in your current shell session:

```
source <(cedana completion bash)
```

To load completions for every new session, execute once:

### Linux:

```
cedana completion bash > /etc/bash_completion.d/cedana
```

### macOS:

```
cedana completion bash > $(brew --prefix)/etc/bash_completion.d/cedana
```

You will need to start a new shell for this setup to take effect.

```
cedana completion bash
```

## Options

```
  -h, --help              help for bash
      --no-descriptions   disable completion descriptions
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana completion](/daemon/references/cli/cedana_completion) - Generate the autocompletion script for the specified shell


# cedana completion fish

Generate the autocompletion script for fish

## Synopsis

Generate the autocompletion script for the fish shell.

To load completions in your current shell session:

```
cedana completion fish | source
```

To load completions for every new session, execute once:

```
cedana completion fish > ~/.config/fish/completions/cedana.fish
```

You will need to start a new shell for this setup to take effect.

```
cedana completion fish [flags]
```

## Options

```
  -h, --help              help for fish
      --no-descriptions   disable completion descriptions
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana completion](/daemon/references/cli/cedana_completion) - Generate the autocompletion script for the specified shell


# cedana completion powershell

Generate the autocompletion script for powershell

## Synopsis

Generate the autocompletion script for powershell.

To load completions in your current shell session:

```
cedana completion powershell | Out-String | Invoke-Expression
```

To load completions for every new session, add the output of the above command to your powershell profile.

```
cedana completion powershell [flags]
```

## Options

```
  -h, --help              help for powershell
      --no-descriptions   disable completion descriptions
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana completion](/daemon/references/cli/cedana_completion) - Generate the autocompletion script for the specified shell


# cedana completion zsh

Generate the autocompletion script for zsh

## Synopsis

Generate the autocompletion script for the zsh shell.

If shell completion is not already enabled in your environment you will need to enable it. You can execute the following once:

```
echo "autoload -U compinit; compinit" >> ~/.zshrc
```

To load completions in your current shell session:

```
source <(cedana completion zsh)
```

To load completions for every new session, execute once:

### Linux:

```
cedana completion zsh > "${fpath[1]}/_cedana"
```

### macOS:

```
cedana completion zsh > $(brew --prefix)/share/zsh/site-functions/_cedana
```

You will need to start a new shell for this setup to take effect.

```
cedana completion zsh [flags]
```

## Options

```
  -h, --help              help for zsh
      --no-descriptions   disable completion descriptions
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana completion](/daemon/references/cli/cedana_completion) - Generate the autocompletion script for the specified shell


# cedana daemon

Manage the daemon

## Options

```
  -h, --help   help for daemon
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana](/daemon/references/cli/cedana) - Root command for Cedana
* [cedana daemon check](/daemon/references/cli/cedana_daemon_check) - Health check the daemon
* [cedana daemon start](/daemon/references/cli/cedana_daemon_start) - Start the daemon


# cedana daemon check

Health check the daemon

```
cedana daemon check [flags]
```

## Options

```
      --full   perform a full check (including plugins)
  -h, --help   help for check
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana daemon](/daemon/references/cli/cedana_daemon) - Manage the daemon


# cedana daemon start

Start the daemon

```
cedana daemon start [flags]
```

## Options

```
      --db string   path to local database
  -h, --help        help for start
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana daemon](/daemon/references/cli/cedana_daemon) - Manage the daemon


# cedana delete

Delete a managed process/container (job) (alias of `job delete <JID>...`)

## Synopsis

(alias of `job delete <JID>...`)

```
cedana delete <JID>... [flags]
```

## Options

```
  -a, --all    delete all jobs
  -h, --help   help for delete
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana](/daemon/references/cli/cedana) - Root command for Cedana


# cedana dump

Dump a container/process

## Options

```
      --compression string   compression algorithm (none, tar, gzip, lz4, zlib)
      --criu-opts string     criu options JSON (overriddes individual CRIU flags)
  -d, --dir string           directory to dump into
      --external strings     resources from external namespaces (can be multiple)
      --file-locks           dump file locks
  -h, --help                 help for dump
      --leave-running        leave the process running after dump
      --link-remap           remap links to files in the dump
      --name string          name of the dump
      --shell-job            process is not session leader (shell job)
      --skip-in-flight       skip in-flight tcp connections
      --streams int32        number of streams to use for dump (0 for no streaming)
      --tcp-established      dump tcp established connections
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana](/daemon/references/cli/cedana) - Root command for Cedana
* [cedana dump containerd](/daemon/references/cli/cedana_dump_containerd) - Dump a containerd container (w/ rootfs)
* [cedana dump job](/daemon/references/cli/cedana_dump_job) - Dump a managed process/container (job)
* [cedana dump process](/daemon/references/cli/cedana_dump_process) - Dump a process
* [cedana dump runc](/daemon/references/cli/cedana_dump_runc) - Dump a runc container


# cedana dump containerd

Dump a containerd container (w/ rootfs)

## Synopsis

Dump a containerd container (w/ rootfs). If an image ref is provided, rootfs will also be dumped

```
cedana dump containerd <container-id> [flags]
```

## Options

```
      --address string     containerd socket address
  -h, --help               help for containerd
      --image string       image ref (rootfs). leave empty to skip rootfs
      --namespace string   containerd namespace
      --rootfs             dump with rootfs
      --rootfs-only        dump only the rootfs
```

## Options inherited from parent commands

```
      --compression string   compression algorithm (none, tar, gzip, lz4, zlib)
      --config string        one-time config JSON string (merge with existing config)
      --config-dir string    custom config directory
      --criu-opts string     criu options JSON (overriddes individual CRIU flags)
  -d, --dir string           directory to dump into
      --external strings     resources from external namespaces (can be multiple)
      --file-locks           dump file locks
      --leave-running        leave the process running after dump
      --link-remap           remap links to files in the dump
      --name string          name of the dump
      --profiling            enable profiling/show profiling data
      --protocol string      protocol to use (TCP, UNIX, VSOCK)
      --shell-job            process is not session leader (shell job)
      --skip-in-flight       skip in-flight tcp connections
      --streams int32        number of streams to use for dump (0 for no streaming)
      --tcp-established      dump tcp established connections
```

## SEE ALSO

* [cedana dump](/daemon/references/cli/cedana_dump) - Dump a container/process


# cedana dump job

Dump a managed process/container (job)

```
cedana dump job <JID> [flags]
```

## Options

```
      --address string     (containerd) containerd socket address
  -h, --help               help for job
      --image string       (containerd) image ref (rootfs). leave empty to skip rootfs
      --namespace string   (containerd) containerd namespace
      --root string        (runc) root
      --rootfs             (containerd) dump with rootfs
      --rootfs-only        (containerd) dump only the rootfs
```

## Options inherited from parent commands

```
      --compression string   compression algorithm (none, tar, gzip, lz4, zlib)
      --config string        one-time config JSON string (merge with existing config)
      --config-dir string    custom config directory
      --criu-opts string     criu options JSON (overriddes individual CRIU flags)
  -d, --dir string           directory to dump into
      --external strings     resources from external namespaces (can be multiple)
      --file-locks           dump file locks
      --leave-running        leave the process running after dump
      --link-remap           remap links to files in the dump
      --name string          name of the dump
      --profiling            enable profiling/show profiling data
      --protocol string      protocol to use (TCP, UNIX, VSOCK)
      --shell-job            process is not session leader (shell job)
      --skip-in-flight       skip in-flight tcp connections
      --streams int32        number of streams to use for dump (0 for no streaming)
      --tcp-established      dump tcp established connections
```

## SEE ALSO

* [cedana dump](/daemon/references/cli/cedana_dump) - Dump a container/process


# cedana dump process

Dump a process

```
cedana dump process <PID> [flags]
```

## Options

```
  -h, --help   help for process
```

## Options inherited from parent commands

```
      --address string       address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --compression string   compression algorithm (none, tar, gzip, lz4, zlib)
      --config string        one-time config JSON string (merge with existing config)
      --config-dir string    custom config directory
      --criu-opts string     criu options JSON (overriddes individual CRIU flags)
  -d, --dir string           directory to dump into
      --external strings     resources from external namespaces (can be multiple)
      --file-locks           dump file locks
      --leave-running        leave the process running after dump
      --link-remap           remap links to files in the dump
      --name string          name of the dump
      --profiling            enable profiling/show profiling data
      --protocol string      protocol to use (TCP, UNIX, VSOCK)
      --shell-job            process is not session leader (shell job)
      --skip-in-flight       skip in-flight tcp connections
      --streams int32        number of streams to use for dump (0 for no streaming)
      --tcp-established      dump tcp established connections
```

## SEE ALSO

* [cedana dump](/daemon/references/cli/cedana_dump) - Dump a container/process


# cedana dump runc

Dump a runc container

```
cedana dump runc <container-id> [flags]
```

## Options

```
  -h, --help          help for runc
      --root string   root
```

## Options inherited from parent commands

```
      --address string       address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --compression string   compression algorithm (none, tar, gzip, lz4, zlib)
      --config string        one-time config JSON string (merge with existing config)
      --config-dir string    custom config directory
      --criu-opts string     criu options JSON (overriddes individual CRIU flags)
  -d, --dir string           directory to dump into
      --external strings     resources from external namespaces (can be multiple)
      --file-locks           dump file locks
      --leave-running        leave the process running after dump
      --link-remap           remap links to files in the dump
      --name string          name of the dump
      --profiling            enable profiling/show profiling data
      --protocol string      protocol to use (TCP, UNIX, VSOCK)
      --shell-job            process is not session leader (shell job)
      --skip-in-flight       skip in-flight tcp connections
      --streams int32        number of streams to use for dump (0 for no streaming)
      --tcp-established      dump tcp established connections
```

## SEE ALSO

* [cedana dump](/daemon/references/cli/cedana_dump) - Dump a container/process


# cedana dump-vm

Dump a VM

## Options

```
  -d, --dir string   directory to dump into
  -h, --help         help for dump-vm
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana](/daemon/references/cli/cedana) - Root command for Cedana
* [cedana dump-vm cloud-hypervisor](https://github.com/cedana/cedana/blob/main/docs/references/cli/cedana_dump-vm_cloud-hypervisor.md) - Dump a clh vm
* [cedana dump-vm kata](https://github.com/cedana/cedana/blob/main/docs/references/cli/cedana_dump-vm_kata.md) - Dump a kata vm or container (w/o rootfs)


# cedana exec

Run a managed process (job) (alias of `run process <path> [args...]`)

## Synopsis

(alias of `run process <path> [args...]`)

```
cedana exec <path> [args...] [flags]
```

## Options

```
      --as-root   run as root
  -h, --help      help for exec
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
  -a, --attach              attach stdin/out/err
      --attachable          make it attachable, but don't attach
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
  -g, --gpu-enabled         enable GPU support
      --gpu-id string       specify existing GPU controller ID to attach (internal use only)
      --gpu-tracing         enable GPU tracing
  -j, --jid string          job id
      --no-server           run without server
  -o, --out string          file to forward stdout/err
      --pid-file string     file to write PID to
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana](/daemon/references/cli/cedana) - Root command for Cedana


# cedana features

Show feature matrix of plugins (alias of `plugin features [plugin]...`)

## Synopsis

(alias of `plugin features [plugin]...`)

```
cedana features [plugin]... [flags]
```

## Options

```
      --errors   Show all errors
  -h, --help     help for features
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana](/daemon/references/cli/cedana) - Root command for Cedana


# cedana freeze

Freeze a container/process

## Options

```
  -h, --help   help for freeze
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana](/daemon/references/cli/cedana) - Root command for Cedana
* [cedana freeze containerd](https://github.com/cedana/cedana/blob/main/docs/references/cli/cedana_freeze_containerd.md) - Freeze a containerd container
* [cedana freeze job](https://github.com/cedana/cedana/blob/main/docs/references/cli/cedana_freeze_job.md) - Freeze a managed process/container (job)
* [cedana freeze process](https://github.com/cedana/cedana/blob/main/docs/references/cli/cedana_freeze_process.md) - Freeze a process
* [cedana freeze runc](https://github.com/cedana/cedana/blob/main/docs/references/cli/cedana_freeze_runc.md) - Freeze a runc container


# cedana job

Manage jobs

## Options

```
  -h, --help   help for job
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana](/daemon/references/cli/cedana) - Root command for Cedana
* [cedana job attach](/daemon/references/cli/cedana_job_attach) - Attach stdin/out/err to a managed process/container (job)
* [cedana job checkpoint](/daemon/references/cli/cedana_job_checkpoint) - Manage job checkpoints
* [cedana job checkpoints](/daemon/references/cli/cedana_job_checkpoints) - List all checkpoints for a job (alias of `checkpoint list <JID>`)
* [cedana job delete](/daemon/references/cli/cedana_job_delete) - Delete a managed process/container (job)
* [cedana job inspect](/daemon/references/cli/cedana_job_inspect) - Inspect a managed process/container (job)
* [cedana job kill](/daemon/references/cli/cedana_job_kill) - Kill a managed process/container (job)
* [cedana job list](/daemon/references/cli/cedana_job_list) - List all managed processes/containers (jobs)


# cedana job attach

Attach stdin/out/err to a managed process/container (job)

```
cedana job attach <JID> [flags]
```

## Options

```
  -h, --help   help for attach
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana job](/daemon/references/cli/cedana_job) - Manage jobs


# cedana job checkpoint

Manage job checkpoints

## Options

```
  -h, --help   help for checkpoint
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana job](/daemon/references/cli/cedana_job) - Manage jobs
* [cedana job checkpoint inspect](/daemon/references/cli/cedana_job_checkpoint_inspect) - Inspect a checkpoint
* [cedana job checkpoint list](/daemon/references/cli/cedana_job_checkpoint_list) - List all checkpoints for a job


# cedana job checkpoint inspect

Inspect a checkpoint

```
cedana job checkpoint inspect <checkpoint-id> [flags]
```

## Options

```
  -h, --help          help for inspect
  -t, --type string   specify image file {ps|fd|mem|rss|sk|gpu}
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana job checkpoint](/daemon/references/cli/cedana_job_checkpoint) - Manage job checkpoints


# cedana job checkpoint list

List all checkpoints for a job

```
cedana job checkpoint list <JID> [flags]
```

## Options

```
  -h, --help   help for list
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana job checkpoint](/daemon/references/cli/cedana_job_checkpoint) - Manage job checkpoints


# cedana job checkpoints

List all checkpoints for a job (alias of `checkpoint list <JID>`)

## Synopsis

(alias of `checkpoint list <JID>`)

```
cedana job checkpoints <JID> [flags]
```

## Options

```
  -h, --help   help for checkpoints
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana job](/daemon/references/cli/cedana_job) - Manage jobs


# cedana job delete

Delete a managed process/container (job)

```
cedana job delete <JID>... [flags]
```

## Options

```
  -a, --all    delete all jobs
  -h, --help   help for delete
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana job](/daemon/references/cli/cedana_job) - Manage jobs


# cedana job inspect

Inspect a managed process/container (job)

```
cedana job inspect <JID> [flags]
```

## Options

```
  -h, --help   help for inspect
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana job](/daemon/references/cli/cedana_job) - Manage jobs


# cedana job kill

Kill a managed process/container (job)

```
cedana job kill <JID>... [flags]
```

## Options

```
  -a, --all    kill all jobs
  -h, --help   help for kill
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana job](/daemon/references/cli/cedana_job) - Manage jobs


# cedana job list

List all managed processes/containers (jobs)

```
cedana job list [flags]
```

## Options

```
  -a, --all    include jobs from remote hosts
  -h, --help   help for list
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana job](/daemon/references/cli/cedana_job) - Manage jobs


# cedana jobs

List all managed processes/containers (jobs) (alias of `job list`)

## Synopsis

(alias of `job list`)

```
cedana jobs  [flags]
```

## Options

```
  -a, --all    include jobs from remote hosts
  -h, --help   help for list
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana](/daemon/references/cli/cedana) - Root command for Cedana


# cedana k8s


# cedana kill

Kill a managed process/container (job) (alias of `job kill <JID>...`)

## Synopsis

(alias of `job kill <JID>...`)

```
cedana kill <JID>... [flags]
```

## Options

```
  -a, --all    kill all jobs
  -h, --help   help for kill
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana](/daemon/references/cli/cedana) - Root command for Cedana


# cedana manage

Manage an existing/upcoming process/container (create a job)

## Options

```
  -g, --gpu-enabled       enable GPU support
      --gpu-id string     specify existing GPU controller ID to attach (internal use only)
      --gpu-tracing       enable GPU tracing
  -h, --help              help for manage
  -j, --jid string        job id
      --pid-file string   file to write PID to
      --upcoming          wait for upcoming process/container
```

## Options inherited from parent commands

```
      --address string      address to use (host:port for TCP, path for UNIX, cid:port for VSOCK)
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
```

## SEE ALSO

* [cedana](/daemon/references/cli/cedana) - Root command for Cedana
* [cedana manage containerd](/daemon/references/cli/cedana_manage_containerd) - Manage a containerd container
* [cedana manage process](/daemon/references/cli/cedana_manage_process) - Managed existing process (job)
* [cedana manage runc](/daemon/references/cli/cedana_manage_runc) - manage an existing runc container


# cedana manage containerd

Manage a containerd container

```
cedana manage containerd <container-id> [flags]
```

## Options

```
      --address string     containerd socket address
  -h, --help               help for containerd
      --image string       image to use
      --namespace string   containerd namespace
```

## Options inherited from parent commands

```
      --config string       one-time config JSON string (merge with existing config)
      --config-dir string   custom config directory
  -g, --gpu-enabled         enable GPU support
      --gpu-id string       specify existing GPU controller ID to attach (internal use only)
      --gpu-tracing         enable GPU tracing
  -j, --jid string          job id
      --pid-file string     file to write PID to
      --profiling           enable profiling/show profiling data
      --protocol string     protocol to use (TCP, UNIX, VSOCK)
      --upcoming            wait for upcoming process/container
```

## SEE ALSO

* [cedana manage](/daemon/references/cli/cedana_manage) - Manage an existing/upcoming process/container (create a job)




---

[Next Page](/llms-full.txt/1)

