User Tools

Site Tools


eve-kvm:creating-a-model

EVE-OS / ZEDEDA Hardware Model Creation

This page documents how to build a ZEDEDA Cloud hardware model for a new edge node, including a simpler alternative to the USB-round-trip and console/debug-shell methods.

The challenge

The two ways most people reach for to pull hardware spec info off a node running EVE-OS are:

  • USB install method — boot the EVE-OS installer from USB; EVE-OS writes a best-effort model file back to the inventory partition of the USB stick. Requires physically getting the USB stick back after install.
  • Console + debug shell method — get serial/KVM console access, drop into the EVE-OS debug shell, and run spec.sh manually. Requires ongoing console/KVM access to the device.

Both are fine if you have that physical/console access. The real problem shows up when you don't: a remote site, a device with no console port wired up, no one on hand to swap the USB stick back out, etc. In that case you're stuck — you can't SSH in to grab the info remotely, because SSH normally isn't available until the node is onboarded, and it can't be onboarded without knowing its hardware model.

There's actually a third, less well-known official option that solves exactly this: an EVE-OS installer image with SSH bootstrapped in. It still needs one physical flash-and-boot, but after that everything else — pulling spec.sh, lspci, etc. — happens over the network.

The simpler way: SSH-enabled EVE-OS image

You don't actually need onboarding to get SSH. EVE-OS supports a bootstrap SSH config baked into the installer image itself, via files placed on the config partition before flashing. This gets you a root shell over the network the moment the node boots — no console, no USB round-trip, no onboarding.

Prerequisites

  • Docker running on your workstation.
  • An SSH keypair (ssh-keygen -t ed25519 if you don't have one).

Steps

  1. Create the config staging directory:
mkdir -p /tmp/config/GlobalConfig
  1. Drop your public key in as authorized_keys:
PUBLIC_KEY_PATH=~/.ssh/id_ed25519.pub
cat "$PUBLIC_KEY_PATH" > /tmp/config/authorized_keys
  1. Add the controller FQDN in a server file:
cat <<EOF > /tmp/config/server
zedcloud.zededa.net
EOF
  1. Enable SSH via GlobalConfig/global.json (this file must exist for EVE-OS to load the bootstrap config at all):
cat <<EOF > /tmp/config/GlobalConfig/global.json
{
  "GlobalSettings": {
    "debug.enable.ssh": {
      "Key": "debug.enable.ssh",
      "ItemType": 3,
      "StrValue": "$(cat "$PUBLIC_KEY_PATH")"
    }
  }
}
EOF
  ''ItemType: 3'' = string value; ''debug.enable.ssh'' holds the actual public key, not a boolean.
  1. Build the installer image with the config folder mounted in:
docker run -v /tmp/config:/in --rm lfedge/eve:latest installer_raw > installer-ssh.raw
  1. Flash installer-ssh.raw to USB and boot the target device.
  1. SSH straight in:
ssh -i ~/.ssh/id_ed25519 root@<DEVICE_IP>

Note: this bootstrap SSH access only works before onboarding. Once the node onboards, these settings are ignored. If you want to keep SSH access afterward, re-enable it through ZCLI:

zcli edge-node update <edge-node-name> --config="debug.enable.ssh:$(cat ~/.ssh/id_ed25519.pub)"

Gathering the hardware spec over SSH

Once you have a shell, pull the same information the console/debug-shell method would give you, without needing physical access at all.

Get the best-effort model JSON

spec.sh

This produces a JSON blob (CPU count, memory, storage, and an ioMemberList of guessed adapters — VGA, USB, COM ports, NVMe, Ethernet, etc.). Save it, e.g. as MyModel.json. Treat it as a draft — EVE-OS's guesses are “best effort” and usually need correcting.

Validate/correct each adapter

  • Remove logo placeholders — logo_back/logo_front default to placeholder paths; blank them out or you'll get a cosmetic error.
  • PCI devices (VGA, USB, Ethernet, etc.):
lspci -k
  • IOMMU groupings (which devices share a passthrough group — matters for assigngrp):
find /sys/kernel/iommu_groups/ -type l
  • Serial/COM ports:
dmesg | grep -i ttyS
  • USB topology (to confirm which physical port maps to which controller):
lsusb
lsusb -t

Cross-check each entry in the ioMemberList against this output:

  • Fix or fill in empty PciLong / Ioports / assigngrp values.
  • Delete entries for ports that don't actually exist as separate controllers (e.g., a device with 4 physical USB ports but only 1-2 controllers in lspci/iommu output — the extra logical entries should be removed since they can't be independently passed through).
  • Omit adapters you don't intend to model (e.g., NVMe, if not relevant).

Validate the final file with a JSON linter before uploading.

Uploading the model to ZEDEDA Cloud (ZCLI)

  1. Copy the validated JSON into the ZCLI docker container:
docker cp /path/to/MyModel.json docker_containerID:/home/zcli
  1. Create the hardware brand, if it doesn't already exist:
zcli brand create NAME --title=TITLE
  1. Create the model, linking it to the JSON:
zcli model create NAME --hardware-details=PATH/TO/JSON --brand=BRAND [--title=TITLE]
  1. To revise a model later, edit the JSON and:
zcli model update NAME [--hardware-details=PATH/TO/JSON] [--brand=BRAND] [--title=TITLE]
  Changes propagate to every edge node currently using that model.

Onboarding the node

With the model created, onboard the edge node in ZEDEDA Cloud (GUI or ZCLI): pick the Brand/Model, choose a Hardware Identity method (Edge Node Certificate from the USB inventory partition, Onboarding Key + serial number, or a single-use installer), and finish the flow.

Good to know: for lab/test nodes, ZEDEDA Cloud lets you onboard with *any* placeholder model just to get connectivity up — you don't strictly need the final model in hand before the first boot. That's a second way to sidestep the chicken-and-egg problem: onboard with a generic model + Onboarding Key/soft-serial (no cert extraction needed at all), then once online, correct/replace the model later. The SSH-image method above is still preferable when you want the *real* model nailed down before onboarding at all, e.g. for image reuse across a fleet of identical devices.

Method comparison

Method Needs console/KVM Needs USB round-trip Needs onboarding first Notes
USB install dump No Yes No Best-effort model written back to USB inventory partition
Console + spec.sh Yes No No Manual, slow, needs physical/remote KVM access
SSH-enabled image No No (still need to flash once) No Recommended — full shell access pre-onboarding
Onboard w/ generic model No No N/A (this *is* onboarding) Fastest to get connectivity; still need to fix model later

Source references

eve-kvm/creating-a-model.txt · Last modified: by mc