Roadmap
Below are Keal features that are in progress, planned and completed.
In Progress
Keal Registry integration
Engines link to the Keal Registry for shared accounts, stacks, DNS and their own settings. The Registry has everything Keal needs live: passwords, DNS ownership, installed apps, engine settings, public stacks, publishing, per-account quotas, billing, remote IPs and engine backups. What is done on Keal's side is under Completed below.
Still to do on Keal's side:
| Work | Status | Plan |
|---|---|---|
| Engine backups | Built (f5ca049); a backup made and stored at the Registry, no restore run yet |
Daily, encrypted on the engine, kept at the Registry with the key locked by the owner's passphrase, or kept by the Registry if the owner chooses no passphrase; restore here or onto a replacement engine. Restore waits for the new package and installer, to try it on a throw-away engine |
| Tags when publishing a stack | To do | Setting a stack's tags when publishing it from a VM; until then a new version keeps the tags the stack has at the Registry |
Loose ends
- A VLAN's dnsmasq sometimes died after a deactivation, without a word - so
not on SIGTERM, which it logs, nor a crash, which the kernel would. A reload,
a reload after an external address went, and a lease release followed by a
reload all leave it running (tested 2026-11-02), so what killed it is not
known. Since then a deactivation restarts it instead of reloading it, it is
signalled only by its pid file rather than
pkill -f, and it lives in the API's own cgroup (keal-api.service). If one dies again,strace -pon the next one shows who sends the signal. - cgroups v2: the engine's resource limits for VMs (
configurecgroups, cgconfig and cgrulesengd, as Stabile set them up) are written for cgroups v1. Get them working on cgroups v2, which current Ubuntu runs by default. support/pressurecontrolhas nothing left that Keal needs: its last two jobs are Keal's own. It stays while the old Stabile UI is kept as a reference, and goes with the installer work (Package bootstrap + installer, below), which still installs it.- Cosmetic renames, kept from Stabile: the register database
steamregister(tokealregister) and the system accountirigo(tokeal). The database needs its tables moved across on an existing engine (RENAME TABLE, fromkeal-engine-setup), Stabile's copies ofsteamExecandpressurecontrolreplaced, and backup restores reading both dump names. The account owns the system jobs, the master images (images/irigo) and the database user on converted engines, and nodes already sign in askeal.
Planned
- Dashboard
- CLI
- DNS functionality
- Implement remote IP / tunnels
- Keal pxe boot images
- New Keal stackbuilder
- Consistent backups of running VMs – build the base images with the QEMU guest agent, so a backup can freeze the guest's file systems for an instant instead of pausing the VM for the whole backup (today a running VM off LVM storage is paused while its images are backed up)
- Keal Ubuntu 22.04 and 24.04 stacks
- Package bootstrap + installer for Keal
To remember when it is built - what this engine was set up with by hand,
or still gets from Stabile's postinst (
support/bootstrapper/stabile-postinst):- The API as a service: install
support/keal-api.servicewith the engine's own user and paths, and enable it (KillMode=process, so what the API starts outlives a restart of it). - sudo:
/etc/sudoers.d/kealgrants the API's usersbin/tapwrenchand nothing more (support/keal-sudoers). This engine's was widened toALLfor debugging; put it back. - Logs:
/var/log/keal, owned by the API's user (keal-engine-setupmakes it; the installer should too). - No more Stabile services: stop installing and enabling
pressurecontrol, and retiresupport/pressurecontrol; the postinst's Tomcat, Guacamole and Stabile-UI steps go with it. - Configuration in
/etc/kealonly:config.cfgfromsupport/config.template.cfg, and nodes'nodeconfig.cfg- in the node images too - under/etc/keal, which is allmovepistonreads now. - movepiston into every node image, and onto a node that is also the engine.
- The register:
keal-engine-setupmakes it on a fresh engine with the postinst'screatedb; the installer can take that step over. - cgroups v2 limits, once they work (see Loose ends).
- The API as a service: install
- Keal Kubernetes stack – Inspired by IKS Lifecycle Management
- Auto-configuration of storage – Like Stabile, Keal should be able to detect and configure storage for storage pools and backup - LVM and ZFS
- Clusters tab – Support Kubernetes clusters as first-class Keal entities
- Apps tab – Stacks + Kubernetes apps
- Deploy on hardware – run Keal on actual physical hardware
- VM import functionality – import VMs from Azure, AWS, Google Cloud, VMware and Nutanix
Completed
Networks (November 2026)
| What | Commit |
|---|---|
| A network's VMs and stacks are counted as its owner's, so a listing by anyone else - Keal's own monitor loop every 30 seconds - no longer clears them; Activate works on the first click | 91c2606 |
| DHCP reservations matched by whole fields, removed from the right NIC, and always tagged; internal and external IP columns | e3baf7d |
| Traffic: a sparkline column and the last hour, day and month in the details, from the VMs' counters in Prometheus; status badges explained; tables sorted by how alive a status is | f9bb99f |
A VM may write a line to the engine's log (writelogentry), recorded in the audit log under its owner; Keal's logs are in /var/log/keal, and nothing reads /etc/stabile |
cbbdadb |
Loose ends tidied (November 2026)
| What | Commit |
|---|---|
| A backup of an image on a node's own storage shows how far it has got on the Images tab: the node watches rdiff-backup, as the engine does, and says so in every report | 15aa1f7 |
The old registry's code gone from the Perl - postToOrigo, uploadToOrigo, postAsyncToOrigo, xmppSend, Uploadtoregistry, do_appstore; APPSTORE_URL defaults to the Keal Registry |
15aa1f7 |
pressurecontrol's last two jobs are Keal's: stale DHCP leases released every heartbeat (engine releaseleases), and the database waited for, and made on a fresh engine, by keal-engine-setup |
15aa1f7 |
How the VMs and nodes stand is worked out once, by the engine (GET /api/v1/home/health), for Home's Health card and keal status alike |
15aa1f7 |
Audit log (October 2026)
Every change made through the API is recorded - who, as which account, from
where, what was done to what, and how it went - along with what the engine does
by itself. It has a tab of its own, and keal audit in the CLI. See Audit.
Keal Registry integration (October 2026)
| What | Commit |
|---|---|
| A client for the Registry's published API, with the engine's own key; the Perl reaches the Registry through Keal | 915b61f |
| Linking, unlinking and renaming the engine; status reports with a capacity summary | 78e943d |
| Account sync, both ways, every heartbeat | 35519ae, 7ef8c4b |
| Stacks from the Registry: catalogue, settings and image downloads | 84f51fd |
| DNS records through the Registry | 88124cd |
| Engine settings from the Registry: quotas, address ranges, I/O limits | 90f0f94 |
| The old registry retired: no fallbacks, its routes, UI, CLI commands and Perl calls gone | a6493a0 |
Salted password hashes (pbkdf2_sha256), shared with the Registry, and old hashes upgraded on sign-in |
353ccd4, f61f5ce |
| Installed apps in the status report; heartbeat steps that fail no longer stop the rest; the sign-in password kept off the process list | 88135fb |
| Public stacks on an engine that is not linked | b689eea |
| Stack publishing from inside a VM, through the engine | 43888dc |
| Per-account quotas from the Registry, through account sync; shown as set there | 3d850ce |
| Remote IPs through the Registry: addresses given out, activated and returned there, tunnels as the unprivileged account it names | b7bc01f |
| Usage for billing: each account's monthly usage, reported to the Registry - daily at first, hourly since | eb11f4e |
| Salted hashes only: sign-in no longer accepts the old unsalted ones, nor the stored hash in place of the password with a two-factor code; account sync carries salted hashes only. No reset was needed here: every account had signed in since step 3 | 00a58ea |
Stack tags from the Registry: after each stack's name in the Install stack picker, which has a search by name or tag, and on its card; a stack already on the engine takes its app's tags. keal stacks catalog has a TAGS column and --tag |
7718569 |
View in the registry goes to the stack's own page for that version - the Registry's page_url, else <registry>/#stacks/<app id>/<version> - for stacks on the engine and at the Registry alike |
7718569, 6d7d902 |
Every installed stack in the status report: each system and each VM outside one, hand-built ones without app_id - shown by the Registry as custom stacks |
6d7d902 |
| More about each installed stack in the status report: its VMs, vCPUs, memory and storage, addresses, monitors, last backup per VM, waiting updates and whether a restart is needed | 0ea8850 |