User Tools

Site Tools


workshop:03_images

Images

An Image in ZEDEDA Cloud is a metadata record that describes where an application image lives, what format it is, and how to verify it. ZEDEDA Cloud does not store the image binary – the edge node pulls it directly from the referenced Datastore at deployment time.

Every image belongs to a Datastore. Before creating an image record, the Datastore must already exist.

Image Types

image_type value GUI Label Used For
IMAGE_TYPE_APPLICATION Edge App VM disks (qcow2, raw, vmdk) and container images (OCI). The most common type.
IMAGE_TYPE_EVE EVE-OS EVE-OS firmware for edge node onboarding and OS upgrades. See EVE-OS Images.

Image Formats

image_format Category Description
CONTAINER Container OCI container image pulled from a registry by tag or digest
QCOW2 VM QEMU Copy-On-Write v2. Standard for KVM VMs on EVE-KVM. Recommended for Linux VMs.
RAW VM Raw disk image. Used for EVE-OS firmware and some VM images.
VMDK VM VMware disk format. Usable on EVE-KVM via QEMU.
VHD / VHDX VM Microsoft virtual disk formats.
OVA VM Open Virtualization Archive. Bundle of VMDK and descriptor.

Image Architecture

image_arch Meaning
AMD64 x86-64 nodes (Intel/AMD). Most common for edge servers and industrial PCs.
ARM64 64-bit ARM nodes (NVIDIA Jetson, Raspberry Pi 4/5, etc.).

An image record is tied to one architecture. You need separate records for AMD64 and ARM64 variants of the same software.

Key Fields

Field Required Notes
name Yes Unique across the enterprise. Cannot be changed after creation.
title Yes Display name. Can be changed.
datastore_id Yes Must reference an existing Datastore.
image_type Yes APPLICATION or EVE
image_format Yes CONTAINER, QCOW2, RAW, VMDK, VHD, VHDX, OVA
image_arch Yes AMD64 or ARM64
image_rel_url Yes For containers: the image name and tag (e.g. nodered/node-red:latest). For files: filename relative to the datastore path.
image_sha256 Recommended SHA-256 of the image file. EVE-OS verifies after download. Required for file-based images, optional for containers.
image_size_bytes Recommended Size in bytes. Set to 0 for containers (size unknown until pull).
project_access_list No Which projects can use this image. Empty list means all projects.

Terraform Examples

Container Image (Docker Hub)

Pulling a Node-RED container image from Docker Hub. No SHA or size needed – OCI layer integrity is handled by the registry.

resource "zedcloud_image" "demo_node_red_1" {
  datastore_id        = zedcloud_datastore.demo_docker_hub.id
  image_type          = "IMAGE_TYPE_APPLICATION"
  image_arch          = "AMD64"
  image_format        = "CONTAINER"
  image_size_bytes    = 0
  name                = "TF-NODE-RED-CONTAINER-IMAGE"
  title               = "TF-NODE-RED-CONTAINER-IMAGE"
  project_access_list = []
  image_rel_url       = "nodered/node-red:latest"
}

Notes: * image_rel_url uses the same format as docker pull: repo/image:tag * image_size_bytes = 0 is correct for containers * image_sha256 is omitted; OCI registries verify layer digests natively * To pin to a digest instead of a floating tag, use: nodered/node-red@sha256:abc123…

VM Image (QCOW2 from local HTTP)

Ubuntu 24.04 (Noble) cloud image from a local HTTP datastore. SHA256 and size are required for integrity verification.

resource "zedcloud_image" "demo_atl_ub_image_1" {
  datastore_id        = zedcloud_datastore.demo_atl_ds.id
  image_type          = "IMAGE_TYPE_APPLICATION"
  image_arch          = "AMD64"
  image_format        = "QCOW2"
  image_sha256        = "834af9cd766d1fd86eca156db7dff34c3713fbbc7f5507a3269be2a72d2d1820"
  image_size_bytes    = 618925568
  name                = "TF-ATL-UBUNTU-24-IMAGE"
  title               = "TF-UBUNTU-24-IMAGE"
  project_access_list = []
  image_rel_url       = "noble-server-cloudimg-amd64.img"
}

Notes: * image_rel_url is the filename at the root of the HTTP server. It combines with ds_path from the datastore to form the full URL. * image_sha256 – EVE-OS verifies the downloaded file against this hash. Mismatch = download rejected and app instance errors. * image_size_bytes – size in bytes of the qcow2 file on disk. * The Ubuntu cloud image is a sparse qcow2. The file on disk (618 MB) is much smaller than the virtual disk size. EVE-OS expands it when creating the volume.

Get SHA256 and size on Linux:

sha256sum noble-server-cloudimg-amd64.img
stat -c %s noble-server-cloudimg-amd64.img

On macOS:

shasum -a 256 noble-server-cloudimg-amd64.img
stat -f %z noble-server-cloudimg-amd64.img

On Windows (PowerShell):

Get-FileHash noble-server-cloudimg-amd64.img -Algorithm SHA256
(Get-Item noble-server-cloudimg-amd64.img).length

VM Image (Azure Blob)

Same Ubuntu image sourced from Azure Blob Storage instead of a local server:

resource "zedcloud_image" "demo_az_ub_image" {
  datastore_id        = zedcloud_datastore.demo_az_blob_ds.id
  image_type          = "IMAGE_TYPE_APPLICATION"
  image_arch          = "AMD64"
  image_format        = "QCOW2"
  image_sha256        = "834af9cd766d1fd86eca156db7dff34c3713fbbc7f5507a3269be2a72d2d1820"
  image_size_bytes    = 618925568
  name                = "TF-AZ-UBUNTU-24-IMAGE"
  title               = "TF-AZ-UBUNTU-24-IMAGE"
  project_access_list = []
  image_rel_url       = "vms/noble-server-cloudimg-amd64.img"
}

The image_rel_url is the blob path within the container (the ds_path from the datastore). The full resolved download URL EVE-OS uses would be: https://ACCOUNT.blob.core.windows.net/CONTAINER/vms/noble-server-cloudimg-amd64.img

Multiple Datastores (Fallback)

You can reference up to 3 datastores on a single image for redundancy. EVE-OS tries them in order. Useful for hybrid environments with a cloud primary and a local secondary.

resource "zedcloud_image" "demo_ub_with_fallback" {
  datastore_id        = zedcloud_datastore.demo_az_blob_ds.id
  image_type          = "IMAGE_TYPE_APPLICATION"
  image_arch          = "AMD64"
  image_format        = "QCOW2"
  image_sha256        = "834af9cd766d1fd86eca156db7dff34c3713fbbc7f5507a3269be2a72d2d1820"
  image_size_bytes    = 618925568
  name                = "TF-UBUNTU-24-WITH-FALLBACK"
  title               = "TF-UBUNTU-24-WITH-FALLBACK"
  project_access_list = []
  image_rel_url       = "noble-server-cloudimg-amd64.img"
  datastores          = [zedcloud_datastore.demo_atl_ds.id]
}

ZEDUI Walkthrough

  1. Navigate to Library > Images
  2. Click the + icon
  3. Identity: Name (permanent), Title, Description, Project scope
  4. Image Type: Edge App, Docker Compose, or Compose Runtime
  5. Image Format: Container, ISO, QCOW2, or RAW
  6. Image Architecture: AMD64 or ARM64
  7. Datastore: select up to 3 datastores (primary + fallback)
  8. Image URL: relative path within the datastore (for files) or image:tag (for containers)
  9. For file-based images: provide SHA256 and Size in bytes
  10. Click Add

ZCLI

# Container image
zcli image create TF-NODE-RED-CONTAINER-IMAGE \
  --datastore-name=TF-ZED-DEMO-DOCKER-HUB \
  --arch=AMD64 \
  --image-format=container \
  --image-url=nodered/node-red:latest \
  --type=Application \
  --title=TF-NODE-RED-CONTAINER-IMAGE
# QCOW2 VM image -- step 1: register the record
zcli image create TF-ATL-UBUNTU-24-IMAGE \
  --datastore-name=TF-ATL-ZED-DEMO-DS \
  --arch=AMD64 \
  --image-format=qcow2 \
  --title=TF-ATL-UBUNTU-24-IMAGE \
  --type=Application
# QCOW2 VM image -- step 2: uplink (associate SHA256 and size)
zcli image uplink TF-ATL-UBUNTU-24-IMAGE \
  --datastore-name=TF-ATL-ZED-DEMO-DS \
  --image-sha=834af9cd766d1fd86eca156db7dff34c3713fbbc7f5507a3269be2a72d2d1820 \
  --image-size=618925568

For file-based images, image create registers the metadata and image uplink associates the SHA256 and size. These are two separate ZCLI steps but a single Terraform resource block.

API

# Container image
POST /v1/images
{
  "name": "TF-NODE-RED-CONTAINER-IMAGE",
  "imageType": "IMAGE_TYPE_APPLICATION",
  "imageArch": "AMD64",
  "imageFormat": "CONTAINER",
  "datastoreId": "<docker_hub_datastore_id>",
  "imageRelUrl": "nodered/node-red:latest",
  "imageSizeBytes": 0
}
# QCOW2 VM image
POST /v1/images
{
  "name": "TF-ATL-UBUNTU-24-IMAGE",
  "imageType": "IMAGE_TYPE_APPLICATION",
  "imageArch": "AMD64",
  "imageFormat": "QCOW2",
  "datastoreId": "<http_datastore_id>",
  "imageRelUrl": "noble-server-cloudimg-amd64.img",
  "imageSha256": "834af9cd766d1fd86eca156db7dff34c3713fbbc7f5507a3269be2a72d2d1820",
  "imageSizeBytes": 618925568
}

What Happens on the Edge Node

The image record is never pushed to the node directly. It is used only when an app instance referencing it is deployed:

  1. The controller sends the app instance config to EVE-OS including the resolved image URL, credentials, format, SHA256, and size
  2. For CONTAINER format: EVE-OS authenticates to the registry and pulls OCI layers. Layers are stored in the containerd content store and deduped across images sharing base layers.
  3. For QCOW2/RAW/VMDK format: EVE-OS downloads the file from the datastore URL and verifies the SHA256 on completion. A mismatch aborts the download and errors the app instance.
  4. Once downloaded, the image is cached locally. If another app instance on the same node references the same image, it reuses the cached copy.
  5. For QCOW2 images, EVE-OS creates a copy-on-write overlay per app instance so multiple VMs can share one base image without writing to it.

Common VM Images for EVE-KVM

OS Format Notes
Ubuntu 24.04 (Noble) QCOW2 noble-server-cloudimg-amd64.img from cloud-images.ubuntu.com – cloud-init ready
Ubuntu 22.04 (Jammy) QCOW2 jammy-server-cloudimg-amd64.img from cloud-images.ubuntu.com
Debian 12 QCOW2 debian-12-genericcloud-amd64.qcow2 from cloud.debian.org
Windows Server VMDK/QCOW2 Must set disk controller to VirtIO before export, or VM will not find its disk on EVE-KVM
Red Hat / RHEL QCOW2 Available from Red Hat customer portal. VirtIO disk controller required.
workshop/03_images.txt · Last modified: by mc