====== 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 [[04_eve_os_images|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 ===== - Navigate to **Library** > **Images** - Click the **+** icon - **Identity**: Name (permanent), Title, Description, Project scope - **Image Type**: Edge App, Docker Compose, or Compose Runtime - **Image Format**: Container, ISO, QCOW2, or RAW - **Image Architecture**: AMD64 or ARM64 - **Datastore**: select up to 3 datastores (primary + fallback) - **Image URL**: relative path within the datastore (for files) or image:tag (for containers) - For file-based images: provide SHA256 and Size in bytes - 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": "", "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": "", "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: - The controller sends the app instance config to EVE-OS including the resolved image URL, credentials, format, SHA256, and size - 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. - 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. - Once downloaded, the image is cached locally. If another app instance on the same node references the same image, it reuses the cached copy. - 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. | ===== Related Resources ===== * [[02_datastores|Datastores]] * [[04_eve_os_images|EVE-OS Images]] * [[07_edge_apps|Edge Apps]]