How do you guys manage ubiquitous configs?

I’d like some fundamentals to be consistent across all vms. By means of salt I’ve gotten some tools to be installed in all of them: xterm, vim, tmux

Now I’d like some configs to be the same everywhere: Xresources, vimrc, tmux.conf, bashrc, my terminal font, some convenience scripts, etc

I could use salt or some skel feature to copy files around, but what I’d rather like is for them to update live. So something like a blockdev that’s read/write in dom0 and readonly in all domUs.

I could try a simple loopdev, but I don’t know enough about the internals to be sure that it won’t mangle anything, even if the blockdev is only writable “one place”

So, do I have to reach for a cluster fs or something? Seems a bit overkill for something this simple. qemu has something called 9pfs, which seems to fit the bill from what I just read about it. Or any lvm trickery I can pull?

Anything for this in qubes? Can’t be that esoteric a use case. How do you guys handle this?

What did you end up doing?

Personally, I’ll create a file in /etc (or somewhere else appropriate) and source that file from my user config file in each AppVM. This does require per-VM setup so it’s not completely automatic, but honestly I’m more comfortable with things being less automatic (especially for disposable VMs where config files could be useful for fingerprinting), and this minimizes the amount of effort required to set up.

1 Like

My setup

I created /opt/00_userowned/ in the template, owned by the user user. I have Brave extensions, LazyVim and pyenv there.

I have a special AppVm I call userowned, that automatically start on system booting. From there I run tmuxp load config, which runs this file:

session_name: updates
windows:
  - window_name: Brave extensions
    panes:
      - shell_command:
        - brave-browser
  - window_name: LazyVim plugins
    panes:
      - shell_command:
        - nvim --headless "+Lazy! sync" +qa | lnav

Brave automatically loads the page brave://extensions at startup.

After updates I manually qvm-copy to the template and from there I cp to /opt/00_userowned/ in the template, always as user, not as root.

Shortcomings

I don’t love this solution, specifically that I don’t think /opt/00_userowned/ is the best place for this, but I can’t think of a better location. Maybe /userowned/. I’m trying to follow POSIX as much as possible.

I looked into using Nix for this, but it doesn’t seem the right tool, or maybe I’m missing something because I’m not very familiar with it.

I have an elaborate system. I use emacs org mode to write ALL my
dotfile configs. This stays in a single, network isolated qube of mine.
From that org mode file, I tangle out all my dotfiles to ~/.dotfiles
directory. Which, then gets gnu stow’ed to their placed under ~/.config
and other places.

From dom0, I have a simple shell script, that spawns my qubes one by one
and dishes out those configuration files under ~/.dotfiles.

It sounds convoluted, but I got my system pretty much automated for me.
I write and manage all my dotfiles from a single file in a single qube.
Then I copy them to other qubes from dom0 via qvm-copy-to-vm commands.