Pre-selecting different qvm-copy targets each time

Context from original thread (linked below)You're certainly right about the usefulness of qvm-copy on dom0 (and that I think about it, that's indeed not an issue with your completer). Ironically, on a domU it does it needs to be retained there (and without looking I am sure there's a lot more meat in that version!). What won't work on a domU is qvm-copy-to-vm.

The end effect is that on dom0 you MUST specify a VM on the command line, but on a domU you cannot (the popup…well, pops up, and you have to select on it–you can’t even arrange for one to show up as the “default” which forces you to think but also leads to mouse-clumsy errors).

You can, but you have to add a custom RPC policy.

1 Like

I fear we’re wandering off topic…but I gotta clarify.

Wouldn’t that always be the same default?

I was thinking more along the line of calling qvm-copy-to-vm on a domU and the VM given as the first parameter would be the one that shows up in the dialog when it comes up. You could then change it, or not.

It would beat scrolling through (in my case) dozens of VM names (including templates and dvm-templates, neither of which is usually desired–typically you want an AppVM, a named disposable or a particular disp1234).

Ah, yeah, I think we’re thinking of different things.

If you click on the share button of a specific post, you can click on New Topic.

You can do that with the RPC policy rules. e.g.

qubes.Filecopy  *   @anyvm   personal   ask default_target=personal

You also can control this behaviour with RPC policy rules.

I speak only for myself (obviously): I think it’s a good idea to split.

You misunderstood me perfectly.

If I do what you suggest, then when I type qvm-copy it will always preselect “personal”. What I want is something on the command line to tell it what to preselect because it probably isn’t “personal”.

(Obviously it’d be more convenient to dispense with the popup entirely, but I understand it’s there for security reasons. I just don’t want to have to scroll through dozens of VMs, and the policy is not a solution because I rarely copy twice to the same VM in a row.)

I did understood you correctly and perfectly. 100%.
Did you actually tried this RPC rule ?? no you didn’t.

You didn’t tried and you just guess … and you are wrong.

You was asking about qvm-copy-to-vm !!!
If you do what I suggest, if you use qvm-copy, nothing will change.
Because qvm-copy use the rule with @default.
Aka: qubes.Filecopy * @anyvm @default ask.

To make a default qube to appear with qvm-copy it would be:

qubes.Filecopy *  @anyvm @default ask default_target=some_qube

Will it be always the same default qube ?
Yes. Isn’t the definition of default …

When you use qvm-copy-to-vm some_qube some_file, it will use the rule:

qubes.Filecopy *  @anyvm some_qube ask

And therefore, if you add a default_target, it will match the qube you put in the default_target.

If you make the rule I showed you. You will have that behaviour.
Do you need to add one rule for each of your qube ? Yes you do.


qubes.Filecopy  *   @anyvm   personal   ask default_target=personal
qubes.Filecopy  *   @anyvm   vault      ask default_target=vault
qubes.Filecopy  *   @anyvm   work       ask default_target=work
etc ...

If you use qvm-copy-to-vm personal some_file:
The default preselected qube will be personal.

If you use qvm-copy-to-vm work some_file:
The default preselected qube will be work.

etc …

You can achieve that … guess what ? … with the policy rules.

qubes.Filecopy  *   @anyvm   personal   allow

If you use qvm-copy-to-vm personal some_file you will not have a prompt and the file will be copied.
The security risk depends of your workflow …

If you don’t want some qubes to be in that list, make a deny rule.

qubes.Filecopy  *   @anyvm   @type:TemplateVM   deny

You will not have any template in the qubes list of the popup.
Adjust to your needs and to your workflow …

If you are in Qubes OS 4.2.0-rc3 (or any rc), in dom0 terminal, run sudo qubes-policy-editor-gui and read the policy syntax help.
Everything I just told you is explained in the documentation:
Please, read them. Several time if you need.

TBH, I don’t know if you are trolling or not …

Well I did do exactly what you said, just now.

qubes.Filecopy * @anyvm personal ask default_target=personal

The only difference being I don’t have a qube named “personal” so I substituted the name of a qube that does exist on my system.

Guess what? It didn’t force the qube I used in the policy to be the default (so I suppose you’re right about that). In fact, it had NO EFFECT WHATSOEVER. I still have to select my desired destination off the popup; it’s not pre-selected.

All I want is a way to specify on the qvm-copy command line which qube is pre-selected. (I brought up qvm-copy-to-vm as an example because it lets you specify the target on the command line But I do not want qvm-copy-to-vm on a domU.)

Incidentally, thanks for showing me how to dispense with the popup, but I don’t want to do that.

In the spirit of experimentation, I also tried using qvm-copy-to-vm on the source domU…same behavior, I still had to scroll-and-select the destination; nothing was preselected. (And this was after it pinged me for not using qvm-copy to save typing.)

I’ll state this again. I want some sort of copy utility that

 1) works in a domU 
 2) lets you specify the destination on the command line
 3) still pops up a gui requesting confirmation, for security reasons.

That means specifying a target or a default target in a policy is beside the point; I want to set the default target by typing its name on the command line

Given the rather insulting tone of your response, I chose not to read further.

Let me try to bring down the heat a little, if that doesn’t help I’ll withdraw quietly.

My understanding from where this topic came up in the context of the previous topic (linked in the first port) is that @SteveC:

  • finds convenient to be able to specify a target directly on the command line when copying between qubes
  • observes that’s possible (and the way to go) in dom0 using qvm-copy-to-vm
  • notes that the exact qvm-copy-to-vm behaviour wouldn’t be desirable in a domU because it doesn’t trigger a dom0 pop-up confirmation
  • has a long list of VMs in the typical confirmation pop-up
  • understands that a default target can be defined for a given domU/qube/VM using policies
  • find that there is no default target that would often be the intended target for the copy operation (because I guess, of copying regularly to different targets)
  • wishes that:
    • qvm-copy would accept a VM name as argument
    • the confirmation pop-up would use that VM name as the pre-selected option for that specific operation only

That is close, but not the same as:

  • configuring qvm-copy to skip the confirmation pop-up (via a policy)
  • using qvm-copy-to-vm in a domU (which doesn’t by default pre-select the target for the confirmation dialog - I’ll come back to this)

Now, with all that being said, there is a lot of information in @szz9pza’s replies and while that information may not always be exactly on target (pun intended) I think that among those suggestions there is a workaround that you could use @SteveC. I might be wrong, and it is certainly not perfect but I’ll lay it out in a separate post, please bear with me!


Here it is. (I added emphasis.)

What does the workaround look like

If I add the following to my policies:

# /etc/qubes/policy.d/30-user

qubes.Filecopy * @anyvm disp985 ask default_target=disp985

And I run the following in any qube (let’s say work for example):

qvm-copy-to-vm disp985 my_example_file

Then the confirmation pop-up does indeed have disp985 pre-selected!

Let’s unpack that example

  • Yes it’s qvm-copy-to-vm and qvm-copy does not pre-select disp985. (I’ll explain why a bit below.)
  • And… yes you’d have to create one policy statement per potential target. :slightly_frowning_face:
    The good new is: it’s one line per target, but not one line per origin-target combination, which would be considerably worse!

Why does this work the way it does?

I’ll say what I did, so you can follow along.
First I asked myself what qvm-copy-to-vm really did in a domU. So I opened a qube (let’s say work) and asked where qvm-copy-to-vm was defined:

which qvm-copy-to-vm
# answer: /usr/bin/qvm-copy-to-vm

Then I tried my luck at looking into it, to see if it was a binary or text file. It turns out I was lucky and it’s a Bash script, which means I can read what it does.

less /usr/bin/qvm-copy-to-vm
# Press q to "quit"

(In practice, I find code easier to read with colors, so I used vim, not less, but the code you see is the same.)

Now, there is at the beginning of the file, a case statement that sets a few options depending on what was the name of the first item on the command line:

# /usr/bin/qvm-copy-to-vm

case ${0##*/} in
    (qvm-move) OPERATION_TYPE=move TARGET_TYPE=default MIN_ARGS=1;;
    (qvm-copy) OPERATION_TYPE=copy TARGET_TYPE=default MIN_ARGS=1;;
    (qvm-copy-to-vm) OPERATION_TYPE=copy TARGET_TYPE=vm MIN_ARGS=2;;
    (qvm-move-to-vm) OPERATION_TYPE=move TARGET_TYPE=vm MIN_ARGS=2;;
    (*) printf 'Invoked with unrecognized name %s, cannot determine operation to perform\n' "$0"; exit 1;;

One of the cases is qvm-move-to-vm, but qvm-move, qvm-copy, qvm-move-to-vm are also there?!?
It turns out that all those tools actually use the same code. Which becomes obvious once you realize that the file /usr/bin/qvm-copy-to-vm is actually not a Bash script, but a link to /usr/bin/qvm-copy :slightly_smiling_face:

ls -alh /usr/bin/qvm-copy-to-vm
# answer: lrwxrwxrwx 1 root root 8 Aug 23 21:41 /usr/bin/qvm-copy-to-vm -> qvm-copy

So they’re the same file. Does it man they behave the same?

Not quite, and you can see that in the case statement I quoted above.

  • If you call the script as qvm-copy my_example_file, the TARGET_TYPE will be set to the value default.
  • If you call the script as qvm-copy-to-vm disp985 my_example_file, the TARGET_TYPE will be set to the value vm. I didn’t know what that meant at this point, but that’s different! Hold that thought.

Relevant code:

# /usr/bin/qvm-copy-to-vm

    (qvm-copy) OPERATION_TYPE=copy TARGET_TYPE=default MIN_ARGS=1;;
    (qvm-copy-to-vm) OPERATION_TYPE=copy TARGET_TYPE=vm MIN_ARGS=2;;

Now, let’s keep going. It turns out that further down the script, the usage of the TARGET_TYPE variable becomes clear. It allows to select the value that will be used as the target when actually performing the copy operation.

# /usr/bin/qvm-copy-to-vm

if [ "$TARGET_TYPE" = "vm" ]; then

Two values are used and qvm-copy (which TARGET_TYPE is not vm) will always use @default as its target value.
Similarly, qvm-copy-to-vm (which TARGET_TYPE is exactly vm) will use $1 as its target value.

In this context $1 means: the first argument of the command.

qvm-copy-to-vm disp985 my_example_file
                  ^--- that is $1 !

Please take not at this point that @default is a value that has a special meaning in policy files. (So we’re finally connecting what we type in the command line to the policy files. :white_check_mark:)

Now that means that we can pass the target name as long as we use qvm-copy-to-vm all the way to the policy check. (:bulb: And it also means, and that I didn’t know, that running qvm-copy-to-vm in a domU is not exactly the same as running qvm-copy, even if it looks like that when using the default policies. Today I learned.)

Where does the target name get from the policy check to the confirmation dialog though?

Bear with me let’s go backwards this time.

  • Unless we define a default target in the relevant RPC policies, then no option will be pre-selected in the confirmation dialog.
  • We know that we can define a default option in the confirmation dialog by setting the value of the default_target in a qvm.Filecopy policy statement. That option will be used if the @default is used when issuing the copy command. (Which is what qvm-copy does, see above.)

As far as I know, we can’t define a policy statement that says: “use whatever value that was used when issuing the command”. (:point_left: Is that true? I believe it is, and I suppose it has to do with preventing the value to be used to inject unintended commands / do bad things.)

However, there is a place where that value affects policies. It actually allows to match policy statements, specifically when their destination field matches exactly the value that was used.

# /etc/qubes/policy.d/30-user

# File format:
# service-name|*    +argument|*    source   destination   action   [options]

qvm.Filecopy        *              @anyvm   disp985       ask      default_target=disp985
#                                           _______
#               ,------------------------------^
#    If the value that was used on the command line
#    matches exactly 'disp985', the policy will apply
#    (including its options, like default_target!)

With that we’ve got the workaround:

For each desirable pre-selected target, create a policy statement that applies to @anyvm source, specifies the target name in the destination field and sets the default_target option to that same target name. And use qvm-copy-to-vm in your qubes, even though that feels odd. (It’s not wrong!)

Not perfect, but it’s one step forward? (And it doesn’t require modifying any of the qvm-* tools, so that speeds things up. :stuck_out_tongue:)

What do you think @SteveC, was I right in saying that @szz9pza actually got a pretty good suggestion there?


I’ll say it again: the utility you are looking for is:
qvm-copy-to-vm + RPC policy rules.
(see @gonzalo-bulnes explanation of how it works under the hood)

For some reason, you do no want to use it even if it does exactly what you want.

Telling you you were wrong when in fact you were, explaining you why and how to solve your issue, and then wondering if you’re trolling.
Well, if you consider all this as a “rather insulting tone”, I guess we don’t have the same definition of “rather insulting tone”.

Sorry to have tried to help you.
I will make sure to don’t make that mistake again…

complaints about style

The accusation of trolling at the end was, all by itself, insulting enough. Why did you assume a non-positive intent on my part?

And the fact remains that your original suggestion would not have worked–I tested it after your second response. And I knew it wouldn’t. It genuinely looked (in your first response) like you simply didn’t understand what I wanted.

So you blasted me for not trying. It’s in your favor that you went through a longer explanation but the whole “Oh but no you don’t want to try this” schtick you immediately assumed was very offputting. It’s as if as soon as someone pushes back YOU take it as a personal affront. And it only became more irritating when, as soon as I did try it, I found it useless anyway.

So when I did try your original suggestion (after being ridiculed and called a troll for not having tried it) and it had no effect whatsoever (so it worked better than I thought it would), am I not justified in being irritated?

Now to return to the actual issue…the solution that gonzalo has explained (and managed to do so without flinging “troll” accusations) requires an individual line in the policy file for each target…and it’s on me to decide whether that’s worth doing or not (I have as yet not verified that it “works” for one potential target). The issue here now becomes one of maintenance–having to remember to add the line to the policy file every time I create a new potential target, and ideally remove it when a target no longer exists. It’s a lot easier to automate adding than removal…but that’s actually a very different topic.

As for your vow to not try to help me ever again, given the horrific attitude you’ve displayed, I look forward with relish to your implementation of that policy.

unproductive comment

I guess I have my answer.

moderation hat on

This is a good thread with lots of good information, let’s keep it that way. I collapsed the off-topic stuff, so other don’t have to read it unless they want to.