Run commands and copy files in --dispvm from dom0

I write scripts that make it easier to interact with dispvm. How can I run a command or copy a file to a new dispXXX? And it’s all from dom0
For example:

qvm-copy-to-vm dispXXX id_rsa
qvm-run dispXXX "mv ~/QubesIncoming/dom0/id_rsa ~/.ssh/"
qvm-run dispXXX "xfce4-terminal -e 'bash -c \"ssh user@1.2.3.4\"; bash'"

so I would do if dispXXX is already running. But how do you do that in a dispXXX that doesn’t yet exist?

qvm-run --dispvm=whonix-ws-16 --service qubes.StartApp+"Please copy my keys and connect to the server"

Any ideas?

According to “How to use disposables” (How to use disposables | Qubes OS) you can execute commands in a disposable like this:

$ qvm-run --dispvm=<DISPOSABLE_TEMPLATE> --service qubes.StartApp+xterm

As to the problem of how to direct the following commands to the same dispQube, perhaps using a named disposable (Glossary | Qubes OS) would help, since you could address that one individually?

(Being pretty much a Qubes-newbie I may be wrong, perhaps somebody more experienced can point out better ways of doing this.)

I’m currently using a named disposable, but that’s pretty damn awkward since I have to create hundreds of them, with scripts bound to the names of these named disposables, and I want the names to be variables.

This sounds as an oxymoron. I think it would be helpful to explain why you would want to use a specific, but not any dvm?

Maybe you should look at /usr/lib/qubes/qvm-actions.sh and try to customize it for your purposes. It would be nice to let us know about the final script anyway, since I have a similar need…

what do you mean by “want to use a specific, but not any dvm?” Actually, I want to use any that is generated when you run dispvm, but its name will be random among other such. Editing /usr/lib/qubes/qvm-actions.sh not quite the right solution, because I stick to default settings so as not to depend on crutches. The final script I see is this, at the moment of running dispvm run a loop that parses qvm-ls | grep Transient | awk '{print $1}' and assign a value to the dispvm name variable. rough but works

I have probably misread this as

how do you do that in a dispXXX that hasn’t been already started

Qubes tooling is a bit rigid in how it creates and starts the usual disp1234 DisposableVMs, but you can get full control by creating custom DispVM class VMs:

name=my-dispvm-$RANDOM
template=$(qubes-prefs default_dispvm)
qvm-create --class=DispVM --prop=auto_cleanup=True --label=red --template="$template" "$name"
qvm-copy-to-vm "$name" ...
qvm-run "$name" ...
...
qvm-kill "$name"
1 Like

I apologize wildly, I’m funny and ashamed at the same time. I understand how the system works and am completely unfamiliar with the English language.
Forgive me again and explain in a more accessible way what you mean.
I use a translator)) love<3

That’s the way I was thinking about it. But this creates permanent entries in the table (qvm-ls)
I believe that we should follow the principle of a one-time system, and an entry in the table destroys this idea.

No, that’s the magic of the --prop=auto_cleanup=True parameter: It ensures that whole DisposableVM is removed as soon as it shuts down.

It’s cool. This solved the problem elementarily. I created the vm this way but forgot to check the :slight_smile: However, nothing prevented me from using qvm-remove in the script, but it turned out that there is a special parameter. In either case, the script must include commands to create the vm. Thank you for helping to understand

Hello. Thank you, I still use this but there was another problem.
After close the application in regular dispVM, the dispVM halted automatically. Created by dispVM in our way, does not turn off automatically after closing the application
How can this be done in our case?

Hi

Did you find a solution to this in the end?

I have been looking at something similar - I wanted to be able to launch apps through the GUI for running disposable VM’s but they don’t show in the application menu. They do show in the domains menu but only with the standard “Open File Manager” and “Run Terminal” options whereas I wanted the full range of apps as shown in the Applications tab of the template cube’s settings.

I am using named disposables as suggested in this thread and launching my apps with a shortcut to a script like this…

MyVM=MyVM$RANDOM
qvm-create $MyVM --class DispVM --template fedora-34-dvm --label orange --prop=auto_cleanup=True
qvm-run --service $MyVM qubes.StartApp+firefox

Then I am using the following to detect if there are any running apps on any VMs launched as above…

for MyVM in $(qvm-ls | grep MyVM | grep Running | awk ‘{print$1}’)
do
if [[ $(qvm-run --pass-io $MyVM – ps -e -F | grep -e StartApp -e gapplication -c) = 0 ]]; then
qvm-shutdown $MyVM
fi
done

This relies on running apps showing up in the output from “ps -e -F” as containing “StartApp” or “gapplication”. If there are no processes with these then qvm-shutdown is run and the auto_cleanup property deals with the VM deletion.

Currently I am running this last script manually using a shortcut - which pretty much defeats the object I know! - but I am aiming to set it up to run in the background.

If you write such scripts, what the hell is your ability to run applications from the domain menu?
My script will create and run the necessary programs, if I need something else, then I just manually enter the name of the application:
qvm-run mydispvmforchatting 'application'
Naturally, I don’t enter the entire command, I just select the desired vm from the list and enter only the application name. This is to press multiple keys
However, you can write a list of applications to a script and select the desired application from the list. Use the console, it will simplify your task.

it is much more convenient to call the cube what it is for and use some script that will focus the “necessary” windows (the windows of these dispvm), as well as run the appropriate applications in it

I don’t understand how it works. If I use qvm-run to start something, will this script understand that some background process is running?

I like the idea. If you only use graphics applications, then it’s easier to search for window names through wmctl. I’m looking for windows like this: wmctrl -a mydispvm -x
But if we run the window search (wmctrl -l) , we get a list of dom0 windows and VM’s names as N/A

Accordingly if you get a list of active windows, according to their names as the name of the vm, you can exclude them from the list of all other VM’s that are to be turned off

Use the cron if it is enough that it happens once a minute. Or a normal cycle, such as every 5 seconds

while true; do
sleep 5
for MyVM in $(qvm-ls | grep MyVM | grep Running | awk ‘{print$1}’)
do
if [[ $(qvm-run --pass-io $MyVM – ps -e -F | grep -e StartApp -e gapplication -c) = 0 ]]; then
qvm-shutdown $MyVM
fi
done
done

Unexpected things may occur when you turn it off. Use the command (qvm-shutdown) with the -f (–force) or qvm-kill

1 Like

Thanks for the reply.

This command…

…runs ps on the required VM and searches for any processes that contain “StartApp” or “gapplication”. I found that whenever I used qvm-run with qubes.StartApp to launch an app it would show up in the process list with a name containing “StartApp”. One time this failed and I discovered that the process contained “gapplication” instead - I believe this was when I launched an app using the blue cube icon (Qubes Domains).
So this has been working reliably for me though I am not sure it works with Debian (I currently mainly use Fedora).

However, in your reply you have mentioned wmctrl
I was not aware of this command but have just been trying this out and can see that using
wmctrl -lx lists all windows along with the associated VM name.
So I am going to see if I can use this from now on instead of running the ps command on each VM - thanks for the suggestion.

I’ll tell you for sure. Remind me a little later