Skip to content

theredguild/ephemctl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ephemctl

Python CLI for ephemeral libvirt/QEMU VM templates and repeatable instance workflows.

Install

uv sync

Daily workflow

Start from the home dashboard:

uv run ephemctl

By default, the root state directory is created in the current working directory as ./ephemerals. If ephemctl finds an existing ephemerals/ or vms/ root marker in the current directory or one of its parents, it reuses that root instead. You can also override it explicitly with EPHEMCTL_ROOT=/path/to/root.

From there you can:

  • create a new instance from a built-in template
  • repeat the last recipe with a fresh name and management IP
  • clone a saved instance recipe
  • manage existing instances, including revive, activate, spice, and destroy

You can also work directly from the CLI:

uv run ephemctl templates
uv run ephemctl create headless-dev demo-headless
uv run ephemctl create browser-client demo-desktop
uv run ephemctl doctor

Templates and profiles

The core model is template-driven. Each built-in template has a profile such as headless or desktop, plus sensible defaults for CPU, memory, networking, and persistence.

The template catalog is materialized as a user-editable JSON file at <root>/recipes/templates.json. On first run, ephemctl writes the default templates there; after that you can add new templates or modify the existing ones without editing Python code.

The old worker and browser names still exist for compatibility in commands and internal state, but they are now examples of built-in templates rather than the primary UX model:

  • headless-dev and headless-heavy are headless templates
  • browser-client is a desktop template

Headless templates can optionally prompt for addons like repo clone, code-server, and a Podman container.

Template provisioning

Templates can now carry small cloud-init fragments directly in <root>/recipes/templates.json.

  • available_addons controls which interactive addons are offered in the wizard
  • provision.packages adds guest packages
  • provision.write_files writes files with simple placeholders like {guest_user}, {home_dir}, {workspace_dir}, {lab_pubkey}, or {lab_privkey_b64}
  • provision.root_commands runs root-level bootstrap commands
  • provision.user_commands runs guest-user commands through runuser

Minimal example:

{
  "custom-desktop": {
    "profile": "desktop",
    "description": "Desktop VM with a repo checkout",
    "name": "desk-001",
    "nat_network": "default",
    "cpus": "2",
    "memory": "4096",
    "disk_size": "20G",
    "mgmt_ip": "10.31.0.30",
    "guest_user": "dev",
    "transient": false,
    "available_addons": ["repo_clone"],
    "provision": {
      "packages": ["firefox"],
      "root_commands": ["touch /var/lib/custom-desktop.ready"]
    }
  }
}

The built-in headless-dev, headless-heavy, and browser-client templates already use this mechanism, so the profile-specific Python code stays small and the template file carries most of the guest bootstrap intent.

Notes

  • bare uv run ephemctl opens the interactive dashboard
  • instance metadata is stored under <root>/vm/instances/<name>/
  • repeat and clone reuse saved recipe data, then prompt for a new name and management IP
  • desktop instances use SPICE; headless instances default to transient mode

About

Ephemeral VMs & orchestration through templates and re-usability exploration tool

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages