# How to create a virtual machine image

Source: https://docs.quake.ai/docs/compute/how-to/create-image
Markdown: https://docs.quake.ai/docs/compute/how-to/create-image.md

---

# How to create a virtual machine image

Upload a custom OS image to your Quake AI project so you can use it to launch instances. Quake AI supports QCOW2, RAW, and ISO disk formats. Use QCOW2 for most use cases.

<PrerequisiteBlock methods={["console", "cli", "api"]}>

- A Quake AI account with a project
- For file uploads: the image file (`.qcow2`, `.raw`, or `.iso`) available on your local machine

</PrerequisiteBlock>

## Upload an image

<MethodTabs>
<Method label="Console">

1. Go to **Compute** > **Images** > **Create Image**.
2. Provide a name for the image.
3. Choose how to supply the image file from the two source tabs at the top of the form:
   - **Upload File**: select a file from your local machine. Quake AI sends the file directly to the image service.
   - **File URL**: provide the URL of a publicly accessible image file. Quake AI fetches the file from the URL.
4. Set the **Disk Format**: `QCOW2` for most images. Use `RAW` for direct disk copies, `ISO` for installation media.
5. Set **Container Format** to `Bare` (the only supported value; the API accepts the case-insensitive form and stores it as `bare`).
6. Set **OS** to your distribution. The dropdown lists eight families: `CentOS`, `Ubuntu`, `Fedora`, `Debian`, `CoreOS`, `Arch`, `FreeBSD`, `Rocky`. (`AlmaLinux` and `Alpine` images exist in the public catalog but the create-form dropdown does not list them; pick the closest family or use the CLI.)
7. Set **OS Version** to the distribution version (for example, `22.04` for Ubuntu).
8. Set **OS Admin** to the default login username for the distribution. The field is a free-text input and does not auto-populate from the OS dropdown. The form's helper text reads "In general, administrator for Windows, root for Linux, please fill by image uploading." Override the hint when the distribution uses a non-root default account (for example, set `ubuntu` for Ubuntu). Quake AI stores the value on the image as the `os_admin_user` property.
9. Set **Enable QEMU Guest Agent** to `Yes` if your image already contains the `qemu-guest-agent` package (recommended for production Linux images). Otherwise leave at the default `No`.
10. Optionally enter a **Description** for the image (free text).
11. Optionally expand **Advanced Options** to set minimums and tuning:
    - **Min System Disk (GiB)** and **Min Memory (GiB)**: refuse instance creation on flavors with less than these values.
    - **Protected**: prevents accidental deletion. Clear the flag before you delete the image.
    - **Interface Multiqueue**: enable multi-queue networking (default on). Leave at the default unless you have a specific tuning need.
    - **Disk Bus**: the virtual disk bus for instances created from this image (default `SCSI`).
    - **SCSI Model**: the SCSI HBA emulation (default `VirtIO SCSI`).
12. Select **Confirm** to create the image. New images are project-scoped (private) by default; making an image public requires the admin role and is reachable through the CLI (`openstack image set --public`).


The Skyline Create Image form does not accept arbitrary image metadata properties. To set properties beyond the form fields (Disk Bus, SCSI Model, QEMU Guest Agent, Protected, Interface Multiqueue, Min System Disk, Min Memory), such as `hw_firmware_type=uefi` for Windows Server, use the CLI or API method tabs and run `openstack image set --property KEY=VALUE` after creation.


</Method>
<Method label="CLI">

Upload a local QCOW2 file:

```bash
openstack image create \
  --disk-format qcow2 \
  --container-format bare \
  --file /path/to/image.qcow2 \
  --min-disk 10 \
  --min-ram 1024 \
  "My Custom Image"
```

Reference an image by URL (Quake AI fetches the file):

```bash
openstack image create \
  --disk-format qcow2 \
  --container-format bare \
  --location "https://example.com/image.qcow2" \
  "My Custom Image"
```

Set the OS admin username property so instances know the default login user:

```bash
openstack image set \
  --property os_admin_user=ubuntu \
  "My Custom Image"
```

</Method>
<Method label="API">

Create the image record:

```bash
curl -X POST "$OS_IMAGE_URL/v2/images" \
  -H "X-Auth-Token: $OS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Custom Image",
    "disk_format": "qcow2",
    "container_format": "bare",
    "visibility": "private",
    "min_disk": 10,
    "min_ram": 1024
  }'
```

Upload the image binary to the record returned above:

```bash
curl -X PUT "$OS_IMAGE_URL/v2/images/IMAGE_ID/file" \
  -H "X-Auth-Token: $OS_TOKEN" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @/path/to/image.qcow2
```

</Method>
</MethodTabs>

## Verify the image

<MethodTabs>
<Method label="Console">

Go to **Compute** > **Images**. The image appears in the list with status **Active** when the upload is complete.

</Method>
<Method label="CLI">

```bash
openstack image show "My Custom Image" -c status -c disk_format -c size
```

The status should be `active`.

</Method>
<Method label="API">

```bash
curl -s "$OS_IMAGE_URL/v2/images/IMAGE_ID" \
  -H "X-Auth-Token: $OS_TOKEN" | python3 -m json.tool
```

</Method>
</MethodTabs>

## Image format notes

| Format | Use case |
|--------|----------|
| QCOW2 | General purpose. Supports snapshots and compression. Recommended default. |
| RAW | Direct byte copy. Compatible with most tools, larger file size. |
| ISO | Installation media (CD/DVD image). Use for [booting from ISO](/docs/compute/how-to/boot-from-iso). |

Quake AI supports x86 architecture images only. Use KVM-compatible images when sourcing from public repositories.

## See also

- [Images concepts](/docs/compute/concepts/images)
- [Images console reference](/reference/compute/console/images)
- [Boot from ISO](/docs/compute/how-to/boot-from-iso)
- [OpenStack image guide](https://docs.openstack.org/image-guide/obtain-images.html)
