How to search for a file across multiple qubes?

I may have left a file on one of my qubes
I do not know which qube it might be on
I have lots of qubes, and I can’t be sure that I won’t miss a qube (I may have a problem)
I would like to know if the file is lost, or if it’s just buried somewhere, before I go through the tedious process of re-creating the thing

Please can y’all let me know how to search across all qubes for a file?

It would need to be from dom0, but I can’t find anything that looks like a “search across all qubes” thing anywhere…
Thunar File Manager only lets me search my current folder for a file

If you want to search across all your qubes for the file (assuming it resides somewhere in /home/user in that Qube, you can paste this into a terminal in dom0, replacing FILENAMEHERE with the name of the file you’re looking for:

for qube in $(qvm-ls --all | grep -vE "(dom0|NAME)" | cut -d ' ' -f1 | tr '\n' ' '); do echo "$qube"; qvm-run -u root --pass-io "$qube" -- bash -c "find /home/user -iname '*FILENAME*' 2>/dev/null"; qvm-shutdown "$qube"; done

If successful, you will see the name of the qube get printed, followed by the location of the file, in red. Otherwise, just the name of the searched qube will get printed.

If you have a list of qubes to search through, it can be simplified to this, replacing QUBENAME# as you see fit:

for qube in QUBENAME1 QUBENAME2 QUBENAME3 | cut -d ' ' -f1 | tr '\n' ' '); do echo "$qube"; qvm-run -u root --pass-io "$qube" -- bash -c "find /home/user -iname '.zshrc' 2>/dev/null"; qvm-shutdown "$qube"; done

Warning: this little one-liner script will start each qube sequentially and then shut it down. If you’d rather it did not shut the qubes down, remove the qvm-shutdown "$qube"; part.


Warning 2: You shouldn’t paste stuff that a stranger tells you to into dom0 if you’re not sure how it works :). If you want, you can wait for someone to confirm that I’m not trying to break/hack your system before doing this.

3 Likes

I’m quite sure using salt would be better here as it can run n qubes simultaneously and handle start/stop as well.

3 Likes

Certainly! However:

  • I know do not know Salt syntax :slight_smile:

If someone provided a salt file that can be executed to search for a file across VMs, that might come in handy in the future for other people.

4 Likes
root@dom0:~# time qubesctl --max-concurrency=2 --targets sys-net,sys-firewall,debian-13-minimal,debian-13-xfce --show-output --skip-dom0 cmd.run "find /etc -name '*shadow*'"
debian-13-minimal:
      /etc/gshadow
      /etc/gshadow-
      /etc/shadow
      /etc/shadow-
debian-13-xfce:
      /etc/shadow-
      /etc/shadow
      /etc/gshadow-
      /etc/gshadow
sys-firewall:
      /etc/shadow-
      /etc/shadow
      /etc/gshadow-
      /etc/gshadow
sys-net:
      /etc/shadow-
      /etc/shadow
      /etc/gshadow-
      /etc/gshadow

real	1m16,709s
user	0m11,865s
sys	0m4,316s

You can use --app to matches only appvm for instances if you don’t want to list all.

9 Likes

Salt has a module file.find. Use it like this:
find.sls:

find_a_file:
  module.run:
    - name: file.find
    - path: /home/user
    - kwargs:
        iname: NAME_TO_SEARCH

qubesctl --skip-dom0 --show-output --targets=TARGETS state.apply test.find

iname provides case insensitive searching.

You can also search for contents, owners, size, date modified, and
combinations of these.

Look at salt.modules.file

I never presume to speak for the Qubes team.
When I comment in the Forum I speak for myself.

7 Likes

sudo time qubesctl --max-concurrency=2 --all --show-output cmd.run “find -name `‘*file*’”

works as expected across all non-minimal qubes. Thank you
(without sudo, I get: fedora-42-minimal: ERROR (exception No such domain: 'disp-mgmt-fedora-42-minimal'))
Sadly, I did not find my files (:frowning:), but it worked for other file names, so you get the green tick (:slight_smile:)

FYI, I also get

local:
debian-13:
/usr/lib/python3.13/site-packages/salt/utils/jid.py:19: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
return datetime.datetime.utcnow()
/usr/lib/python3.13/site-packages/salt/client/ssh/__init__.py:1595: DeprecationWarning: ‘maxsplit’ is passed as positional argument
stdout = re.split(RSTR_RE, stdout, 1)[1].strip()

for every qube searched, so something might need updating?

1 Like