I’ve spent the last while building a small PyQt6 GUI for dom0 that wraps a handful of qvm-*/qubesctl workflows I kept doing manually copying files between dom0 and a qube, installing my own Salt formulas, creating qubes, checking what’s installed where. Figured I’d share it in case it’s useful to anyone else.
File Transfer - copy files/folders between dom0 and a qube in either
direction, including a remote file/folder browser for picking a path
inside a qube. Also a screenshot shortcut (region or a single window,
via xdotool) straight into the dom0 → Qube source field - the
resulting PNG is verified metadata-free before it’s ever offered for
sending.
Text / Clipboard - send or fetch plain text between dom0 and a qube
via Qubes’ own global clipboard (the same buffer Ctrl+Shift+C/V use).
Salt Formulas - install Salt states without memorizing qubesctl
incantations, including formulas you didn’t write yourself. See below.
Overview - every qube at a glance: template, netvm, memory, label
color, running state, per-template disk usage, plus
start/restart/shutdown/terminal/remove actions on the selected row.
Software Inventory - list installed packages or search available ones
in dom0 or any qube, install/uninstall by clicking results, plus a
one-click “common extras” section for what a fresh minimal template
usually lacks (passwordless sudo, audio, USB passthrough, file manager,
browser, terminal, text editor, password manager).
Create Qube - optionally clone a template first, create an AppVM from
it, pick a storage pool, and choose which of the template’s installed
apps show up in its menu.
Encrypted Pools - two related storage-pool features, nested under one
tab. LUKS Pool - a passphrase-protected LUKS+LVM-thin pool for
sensitive qubes, meant to persist: create it, open it when you need it
(passphrase prompt), close it when you’re done - closing wipes the key
from kernel memory and hides the qubes inside from menus and Qube Manager
until you open it again. Ephemeral Pool - the opposite: no passphrase,
no persistence by design. A fresh encrypted pool with a random key is
created on every boot and destroyed on every shutdown, automatically, via
a systemd service - for disposable-VM templates that should never leave
anything behind.
Backup - thin wrapper around qvm-backup, included mainly for
convenience alongside everything else - Qubes’ own Qube Manager and
backup GUI already cover this natively.
Only runs in dom0 - uses qvm-run/qvm-copy-to-vm/qubesctl, which don’t exist anywhere else. dom0 has no network of its own, and a qube can’t push files into dom0 either - it has to be pulled from dom0’s side. No extra dependencies needed: PyQt6 is already part of dom0 on current Qubes OS (Qube Manager and the tray tools are built on it too).
Full install instructions (including an optional desktop menu entry) are in the repo’s README.
Personal tool. Runs as root in dom0 - read the code first, especially Salt Formulas and Encrypted Pool. Done my own security pass, but more eyes welcome.
You can install qvm-run, qvm-copy-to-vm, etc. in other qubes by installing qubes-core-admin-client in the template. I don’t know if it is possible for qubesctl, it’s in qubes-mgmt-salt-admin-tools.
It’s actually better for this kind of scripts: you set up an admin qube to avoid putting more code in dom0. Also, copy-pasting things to dom0 is hard for a good reasons.
good point, thanks. hadn’t considered the admin-qube route seriously. this started as a small personal script and grew from there, dom0 by default. moving the qvm-* calls out to a admin qube would maybe be the cleaner approach.
that said most of it is a fairly small, transparent script and leaves no data behind in dom0 once removed. I also can’t confirm everything would work identically from an admin qube, all my testing has been against dom0, so it’s built and hardened specifically for that.
the encrypted pool tab especially (cryptsetup/losetup/LVM directly against dom0’s own storage). i’m fairly sure that one can’t move out at all, since it needs direct access to dom0’s own physical block devices, not just admin API calls to manage other qubes. that part has to stay in dom0 regardless.
thanks, appreciate that! hadn’t really thought about it that way, what i
wanted was to make daily tasks a little bit easier for qubes users. planning to start uploading some salt formulas to my github over the next few days too, ones that are compatible with the gui and can be installed with one click.
I like the Software Inventory tab – because it makes you feel an atmosphere of a mighty central dom0 that you can manage your app qubes from without having to walk away into their consoles to install things from there. Basically everything from the comfort of your armchair.
thanks! yeah that’s basically the idea, dom0 as the one place you check and act from, instead of opening a terminal in every single qube one by one just to see what’s installed or run apt/dnf.
and the common extras list exists because i kept installing the same things into every minimal template, thunar, qubes-usb-proxy, passwordless sudo, etc. so now it’s just checkboxes for a few common things
Could you add an ephemeral pool (on zram or ephemeral encrypted) in addition to the encrypted one? That would be very convenient and provide a complete set of secure pools!
hi, thanks! ephemeral pools are a different feature though, fresh key every boot, fully destroyed on shutdown, would need its own design, not just a toggle on the existing tab. genuinely interested, no promises on timing, but I’ll check the guide properly.
You could use a 2GB zram container, for example, in that case, there would be ephemeral key. Anyway, please check out this excellent guide.
I also hope your tool gets added to Qubes OS officially - you’ve done a huge amount of work, and it’s an incredibly useful tool for both beginners and experienced users. Qubes OS has been needing a tool like this for a long time, and it has been requested for so long. I hope the devs notice it.
one-click install (don’t blindly trust the code, always check it out first) through QubesOS Helper’s Salt Formulas tab.
the dry run on any of these won’t come back 100% clean. qvm.prefs/qvm.features can’t simulate against a qube that test mode didn’t actually create, so a few steps always show as failed. that’s expected, not a sign anything’s broken.
This is fantastic work, and I hope the devs notice it. Even if it doesn’t become an official tool, it would be great to continue developing it as a community project. I will recommend this to all my friends using Qubes - it will significantly make their lives easier. I’m delighted to see my encrypted pools included here. Thanks!
thanks, really appreciate that! and yeah, your guide was exactly what got me thinking about the encrypted pool feature. right now I’m actually working on ephemeral DVM pools too, based on your guide - turns out it’s much more work than I expected, so no promises on timing
If this doesn’t make it to a contrib repo, then I don’t know what would.
I really can’t remember a more (advanced-)user friendly tool, at least gui tool, then this. And if something justifiably deserve its name then this tool is - it is indeed a Helper with a capital H.
Please do not extend it too much, at least at the beginning. It may overwhelm you and you may abandon it. Maybe it’s a good idea to put each suggestion into a poll, then to upgrade it with the top 3 out of the first ten, or so.
i’m working hard on the ephemeral pool dvm feature, testing (code-level and dom0) is looking good so far, still polishing things and hardening it a bit more before it’s properly release-ready
and like corporateblush already said:
everything just takes its time. i’m doing this completely alone, and it’s already taken countless days to get the tool to where it is now.
if anyone wants to support the work, that’d be a huge help.
and if anyone’s already dug into the salt formulas and feels like making their own formulas compatible with qubes helper (via qubes-helper.json), that’d help too.
the new feature should be ready by end of week, i’ll keep you posted.
found and fixed a bug in the Encrypted Pool tab (open/close, status display) in the current github version: after closing a pool, status kept showing “Open” even though it was actually locked.
the feature isn’t really usable like this right now, please hold off until the update.
will be in the new version, up by the weekend, along with the previously promised ephemeral pool dvm feature.