Skip to main content

isard

PyPI Python License: MIT OR Apache-2.0

Manage your IsardVDI virtual desktops on the Gencat educational platform (elmeuescriptori.gestioeducativa.gencat.cat) from the command line.

isard login          # authenticate (SAML + JWT)
isard list           # your desktops
isard create dev     # a desktop from a template
isard start dev      # power on
isard view dev       # open in virt-viewer
isard ssh dev        # ssh into it

Install

uv tool install isard      # recommended
pipx install isard
pip install isard

Requires Python 3.11 or newer. uv tool install fetches a suitable Python for you if the system one is older.

Upgrade the same way you installed:

uv tool upgrade isard
pipx upgrade isard
pip install --upgrade isard

Authenticate

Running any command prompts for your credentials. To skip the prompt, set them in the environment:

export GENCAT_USERNAME="12345678a"     # @edu.gencat.cat is added for you
export GENCAT_PASSWORD="your-password"

…or drop a .env file in your working directory:

GENCAT_USERNAME=12345678a
GENCAT_PASSWORD=your-password

Sessions are cached in ~/.config/isard/ (%APPDATA%\isard\ on Windows) with chmod 600, and refresh themselves when they expire. isard logout clears them.

Commands

Command Description Options
login Authenticate and display session info
logout Delete cached sessions
version Show the installed version
list List desktops with state/IP/OS --hardware/-H, --name/-n
template / template list List available templates --category/-c, --hardware/-H, --filter
template create Pick a Fedora source, download the ISO, create fedora-<variant>-<version>, then detach + delete the media after install --seed-url
template promote Promote a stopped desktop into a template --name/-n, --description/-d, --disabled
build <profile.yaml> Build a template from a YAML profile: fetch the newest Ubuntu/Fedora ISO, hand you the installer in a viewer, then configure over SSH and promote --identity/-i, --keep-media, --no-promote, --no-viewer, --dry-run, --install-timeout
media / media list List your media (ISO library) --filter
media add <name> Register a new media by HTTPS URL --url, --description/-d, --no-wait, --timeout
media delete <name> Delete a media --yes/-y
seed cidata Build a NoCloud (CIDATA) seed ISO --user-data, --meta-data, --output/-o
seed oemdrv Build an Anaconda (OEMDRV) seed ISO --kickstart, --output/-o
create <name> Create a desktop from a template --template/-t, --description/-d, --category/-c, --filter
start <name> Start a stopped desktop --wait/-w, --timeout, --book/-b, --book-minutes
stop <name> Stop a running desktop --wait/-w, --timeout
delete <name> Delete a desktop (trash or permanent) --permanent, --yes/-y
view <name> Open the desktop in virt-viewer over SPICE --install/--no-install, --auto-resize, --debug
ssh <name> SSH in via the bastion --user/-l, --identity/-i, --password, --timeout, --dry-run
vpn / vpn status Is the WireGuard tunnel up?
vpn config Download this account's WireGuard config --output/-o, --show
vpn up / vpn down Join or leave the desktop network (installs wireguard-tools if missing) --refresh/--no-refresh, --install/--no-install, --dry-run

Full reference with every flag and behaviour: docs/commands.md, also published at https://isard.xtec.dev/commands.

Examples

isard list --hardware                  # add CPU + memory columns
isard template --filter fedora         # narrow the template list
isard create dev --template fedora     # fuzzy: resolves to fedora-server-44
isard start dev --wait --timeout 300   # block until it's running
isard start gpu-box --book             # book a vGPU slot first, then start
isard delete dev --permanent --yes     # skip the trash and the prompt
isard media add ubuntu-24 --url https://releases.ubuntu.com/24.04/…-amd64.iso

Name resolution

Desktop and template names resolve by exact match first, then Jaro-Winkler fuzzy matching, then substring. A typo still finds the right desktop; an ambiguous name opens a picker. In scripts (no TTY) an ambiguous name is an error rather than a guess.

SSH

isard ssh handles the plumbing: it resolves your private key (--identity, ~/.ssh/id_ed25519, ~/.ssh/id_rsa, or generates a new ed25519 key), registers the public key with the IsardVDI bastion, starts the desktop if it's stopped, and connects through port 443.

The first connection to a desktop shows its guest credentials half-masked and asks you to confirm them. Confirmed desktops are remembered in ~/.config/isard/desktop-creds.json, which holds ids only — no passwords. Use --password to set new guest credentials (the desktop is stopped, updated, and restarted).

If OpenSSH isn't installed, an embedded pure-Python client takes over.

virt-viewer

isard view installs remote-viewer if it's missing:

Platform Method
Windows Downloads and extracts the MSI from GitLab releases (no admin needed)
macOS Homebrew via the jeffreywildman/homebrew-virt-manager tap (builds from source — takes several minutes)
Fedora dnf install virt-viewer
Ubuntu/Debian apt install virt-viewer

Pass --no-install to skip that.

Building a template from a file

isard build takes one YAML file and gives back a finished template — newest ISO, a short manual install in a viewer, then packages and commands applied over the SSH bastion, and promote:

# ubuntu.yaml
image: { distro: ubuntu, variant: server, release: lts }
template: { name: ubuntu-lts-base, memory_gb: 8, disk_gb: 100 }
user:
  name: isard
  password_env: ISARD_TEMPLATE_PASSWORD
  ssh_key: ~/.ssh/id_ed25519.pub
packages: [git, curl, docker.io]
run:
  - systemctl enable --now docker
isard build ubuntu.yaml --dry-run   # see the plan without touching the API
isard build ubuntu.yaml

One step is yours: when the viewer opens, install the OS with the profile's username and password and an SSH server — three fields on the installer's own screens. Shut the machine down and the CLI takes over again. Full reference: docs/build-profiles.md, examples in examples/build/.

Unattended templates, by hand

The lower-level path is still there: build a seed ISO whose volume label the installer auto-discovers (CIDATA for cloud-init, OEMDRV for Anaconda), host it over HTTPS, and hand the URL to template create:

isard seed oemdrv --kickstart my-ks.cfg -o seed.iso
# host seed.iso somewhere IsardVDI can reach it
isard template create --seed-url https://your-host/seed.iso

Starter configs are in examples/seed/; the end-to-end runbook is docs/phase3-verification.md.

Use it as a library

Everything the CLI does is importable:

from isard import get_desktops, login_to_isardvdi

session = login_to_isardvdi("12345678a@edu.gencat.cat", "…")
for desktop in get_desktops(session):
    print(desktop.name, desktop.state)

See docs/library-api.md.

Development

git clone git@github.com:ddemingo/isard.git
cd isard
uv sync --dev
uv run pytest          # no network needed
uv run ruff check .
uv run isard --help

Design notes and invariants: docs/architecture.md. Every IsardVDI endpoint we call: docs/api-endpoints.md.

License

Licensed under either of MIT or Apache-2.0, at your option. Unless you state otherwise, any contribution you submit for inclusion is dual-licensed on those same terms.

Copyright © 2026 Optersoft, S.L.


Built for the Gencat educational platform — you'll need valid IsardVDI credentials to use it.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

isard-0.3.0.tar.gz (173.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

isard-0.3.0-py3-none-any.whl (113.5 kB view details)

Uploaded Python 3

File details

Details for the file isard-0.3.0.tar.gz.

File metadata

  • Download URL: isard-0.3.0.tar.gz
  • Upload date:
  • Size: 173.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for isard-0.3.0.tar.gz
Algorithm Hash digest
SHA256 3c0844541e438b3c30a9a81bbd11a21205ba4211f5fbbf20b8aad81993bc1765
MD5 72dda7a010857c92bf095f1ef29fb13e
BLAKE2b-256 19c882ff005c1a17a36bda59c17748c2d6e17e2fbb122e6b736682c7189dcf34

See more details on using hashes here.

File details

Details for the file isard-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: isard-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 113.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for isard-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 390e63bc4b221704b55548f0fb3646695ce8b9cc8b6020b80408e79056e62a67
MD5 166c946e1cc2d2bbfefee3af104f3617
BLAKE2b-256 bc914729b2941744b26fa50901c26fb983fb844ca2db8ae21a869093cd3ca973

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page