What I want to be able to do is select a block device from a popup similar to the one that comes up when one does a qvm-copy in some domU (that one asks the user to select a destination VM). (I am assuming the popup for qvm-copy runs on dom0, obviously; if that assumption is wrong please let me know.)
I already understand how to get the VM to communicate with dom0; how to attach the selected block device to the VM that wants it, etc.; I just don’t know what it will take to write the popup itself. (As a last resort, I could write something in C++/Gtk on a Fedora qube with the compiler installed, then copy it to dom0…at least I know that’s not malicious code! I’m guessing the existing utility is written in python, which I will have to learn.)
Background: I already have something set up where the VM does a “pull” of the block device by calling a qrexec function to have dom0 send it a list of available block devices; on the VM I have a zenity popup ask the user to select one (if there are multiples); a qrexec call to dom0 then attaches the device, and finally, I mount /dev/xvdi (or whatever it ends up as). I don’t like the way that dom0 sends a list to the VM; I’d rather be able to make the selection via a dialog on dom0 itself. Too bad zenity doesn’t appear to exist on dom0 but if something like it does, great! I’ll just use that.
One thing that will be very helpful is a link (or path, if it’s part of the install) to the source code for the qvm-copy popup.
You have multiple options. Many options. Consider these:
Qubes Manager (possibly the oldest Qubes GUI App) was/is written in PyQt. If you already know Python, you could spend some time and learn PyQt6 for around 1 week. The are plenty of tutorials for it.
The new GUI Tools (e.g. the updater, systray widgets, global config, …) are written in PyGTK3. You could learn it by spending around 1 week. I can recommend The New Boston video tutorial series, this one from Tutorials Point or the official one.
For simple dialogues, you could use simple bash and Zenity as was suggested by Tezaria. And use qrexec-client for API calls. You have to be proficient with sed, awk and bash scripting. You will have to spend around 1 week.
C++/Qt or C++/GTK is possible. But most examples you will find are written in Python.
My recommendation is 1, 2 or 3 for the beginning.
Considerations:
To run python in dom0, type python3. Pay attention to 3.
If you do not know Python but C++, you could learn Python by spending around 1 week to 2 weeks.
Sources to the old PyQt based Qube Manager is in this repo
Sources to most new PyGTK based GUI Apps are in this repo.
Python GUI applications are installed at /usr/lib/python3.11/sites-packages and are available as text (as well as compiled binaries). You could grep -IRnw <ABOVE_PATH> -e '.*text you see on the existing GUI apps.* and find the source to the exact file. Then read its source.
Looking at qubesadmin (qvm-*) sources could help you understand the Qubes specific parts. Their source is available here. They are also installed at the path I mentioned in previous post.
No, zenity does not exist on dom0. At least, if I try to invoke it from the command line, I get bash: zenity: command not found. I also did: find . | grep zenity from / as root, just in case it was somewhere on my system and not in my path, and nothing was found. There is a “notify-send” on dom0 but that doesn’t seem to be capable of letting someone pick off a list.
If zenity existed I would already have done alimirjamali’s suggestion 3; I’ve done similar things on debian VMs already–I happen to know the other stuff needed well enough.
I know GTK3 fairly well (i’ve programmed with it in C++), but am a total Python noob. Even after going through a tutorial, I don’t have any idea what I need to import to do anything useful. I even tried running the code that Apparatus linked…and it simply complained that I was trying to import things it didn’t know how to find. So clearly I don’t have a properly set up environment. Again, I could write something in C++/GTK on another VM which has g++ installed on it (dom0 does not) and simply port the executable to dom0, if I had to in order to get something to work (at least I would know it’s not malicious code!). (That’s alimirjamali’s option 4, sort of; s/he seems to think I could do the development on dom0.) And s/he is correct, most GTK is done in Python. This is the bane of my professional existence actually since IRL I develop GTK on C++ and I often cannot find anything but “pygtk” documentation on line even if I tell google -pygtk it insists on showing me python docs.
Then you are very ahead of required time. Python is extremely easy to learn for an experienced C++ programmer. It is a little bit ugly at the beginning as it is not strongly typed (you do not need to define variables and their type prior to using them)
Here is a very simple demo program that does something Qubes related (although it is meaningless). It creates a window with the name of qubes:
#!/usr/bin/python3
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from qubesadmin import Qubes
myapp = Qubes()
mywin = Gtk.Window()
mywin.connect("destroy", Gtk.main_quit)
mybox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
mywin.add(mybox)
for qube in myapp.domains:
label = Gtk.Label()
label.set_text(qube.name)
mybox.pack_start(label, True, True, 0)
mywin.show_all()
Gtk.main()
Like C++, Gtk and Qubes are classes here. Whereas myapp, mywin, mybox, qube and label are objects. You could see that it is not necessary to define them or their type. The for loop iterates through the myapp.domains dictionary (similar to C++ vectors). And new instances of Gtk.Label is created. And added to the window.
You can run the above test in dom0. Or in any VM with proper policy. You should allow admin.vm.List for that VM.
Worked well once I got past the inevitable typos (I’m posting from a totally different system).
That ought to be enough to do it, honestly. I’ll load block device names into a dropdown (similar to what is seen with qvm-copy) and simply echo the choice and quit. And run the thing from a bash script that in turn is invoked by a qrexec call.
I should be able to learn enough from the qvm-copy code to get there.
(I may or may not create the list in the bash script and have python load it, rather than generate it from within python, especially since I already have the list made in a bash script.)
Thanks!
End result: VM asks to be connected to a thumb drive (or a CD ROM or a Loop or an SSD partition) via qrexec. A list that matches the request will be generated, then this GUI pops up to allow the user to pick one. If the user doesn’t cancel, dom0 attaches the block device to the caller, then invokes a script on the caller that will let the caller do what it needs to do, mount the device, or something else–that’s up the the VM. I can install all of this in some basic template, except for the “custom” part of the script that will be special for the particular VM.
combo_box=Gtk::ComboBoxText()
mybox.pack_start( combo_box, True, True 0)
for qube in myapp.domains:
combo_box.append_text(qube.name)
mywin.show_all()
and by golly I got a combo box. Obviously I need to add OK and Cancel buttons and the callbacks to read what’s in the combo box on pressing OK (and load block devices into the combo box, not qube names), but this got me started!
Neither Yad nor yad works (bash: yad: command not found). Do I have to do something special to get it to work?
Apparently, I could run notify-send in such a way as to put each USB device’s name on a button. Anyhow I did get a gui working, but now I’ve run into other problems.
Sorry, I haven’t logged in for a few days… If you try the command yad --text="I love Qubes", does a Yad window open?
I had fun creating small bash scripts with Yad in dom0, and everything works well.
"Sorry for this late response, I don’t know if it’s still relevant. For me, yad was already installed otherwise, you do (as usual lol) sudo qubes-dom0-update yad