I have a setup where I manage multiple coding projects and need tight isolation.
My workflow involves having a dedicated AppVM for each project so that malicious code can’t tamper with my global dotfiles configuration. My dotfiles configuration is centralized in a standalone vault-dotfiles VM from which I pull config updates.
The problem is that, as the number of projects and client goes up, also the amount of time and complexity to keep everything up-to-date goes up like crazy.
I’d like a single “dotfiles template” VM that always has my latest configurations, plugins, and environment updates, and I want to bring these updates seamlessly into each coding session without redoing them everywhere through moving files and pulling updates, solving conflicts, etc.
/etc/skel isn’t a great solution because it only applies at VM creation. Ideally, I’d have a disposable coding environment that attaches project data as a block device (like from a project-data VM) while always pulling fresh dotfiles from a known template source. But it’s unclear whether Qubes supports mounting an internal LVM-backed project volume directly into a disposable VM the same way it does external devices.
The documentation mostly covers external block devices (not a solution for me since I want to keep everything inside Qubes and on the same device), not internal volumes. Is there a supported way to dynamically attach an internal project-specific volume to a disposable coding VM that already inherits dotfiles from a template, so I can keep my dotfiles updated in one place, maintain full isolation per project, and have everything just work when I spin up a coding session?
If you have all your dotfiles in a git repository in your vault-dotfiles qube, a program to manage dotfiles would help deploying them, using rules using the qube hostname for instance.
I have a git repo for my dotfiles in my vault, and a setup script to deploy them using stow. Then the script will update the configs and installed plugins by calling the plugin managers of the tools I use (e.g. neovim, tmux, zsh, etc.).
I have a script to deploy and update dotfiles to a specific VM (could modify it to deploy simultaneously to each “coding” VM), but this is cumbersome because it means I’m installing/updating the plugins on each VM essentially duplicating the work I have to do in case of a conflict that requires manual intervention.
If I could find a way to use a disposable VM instead then I’d not need to manually go through all of my VM in case something like this happens (it’s not super frequent, but it happens especially with some bleeding edge plugins I’m using or some more exotic dev env seeing the niche in which I’m developing stuff).
It looks like what I was trying to do is indeed feasible. I can have a coding template vm to be used as disposable, and then mount an lvm partition upon launching a new coding disposable vm.
The only question that I have now, though, is whether this is a good idea at all, seeing how there’s a udev rule specifically for skipping lvm devices.
Is the procedure I described above alongside my desired workflow usable with no loss of security?
Now add anything there that you want. In the template. I have /opt/dotfiles/pyenv/, for example, and this in my /etc/pip.conf in the template:
[global]
proxy = http://127.0.0.1:8082
Now, still in the template:
cd /home/user
ln -s /opt/dotfiles/pyenv .pyenv
cd /etc/skel
sudo ln -s /opt/dotfiles/pyenv .pyenv
From now on you manage your pyenv environments in the template. You can do the same with npm packages, etc. Or with Vim plugins.
It should be possible with browser plugins too. I haven’t tried.
NOTE: Maybe /opt/ is not the best place, semantically, for dotfiles/. Maybe it should be in /etc/dotfiles/. Maybe someone can comment on this.
EDIT: TIL that nix-shell is exactly for this. It can be installed in other Linux distros, like the Debian and Fedora templates that come with Qubes OS. You don’t need a NixOS template. The dotfiles will be saved in a subdirectory of /nix/store/ owned by user and accessible from every AppVM of the template.