VMs: persist state folders on host
Done:
- move vm inspect attrs from system.clan.vm.config to clanCore.vm.inspect. This gives us proper name and type checking. everything in `system` is basically freeform, so the previous option definitions were never enforced
- when running VMs, mount state directory from ~/.config/clan/vmstate/{...} from the host to /var/vmstate inside the vm
- create bind mount inside the VM from /var/vmstate/{folder} to / for all folders defined in clanCore.state.<name>.folders
TODOs:
- make sure directories in ~/.config/clan/vmstate never collide (include hash of clan-url, etc.)
- port impure test to python
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
{ ... }: {
|
||||
perSystem = { pkgs, lib, ... }: {
|
||||
{ self, ... }: {
|
||||
perSystem = { pkgs, lib, self', ... }: {
|
||||
packages = rec {
|
||||
# a script that executes all other checks
|
||||
impure-checks = pkgs.writeShellScriptBin "impure-checks" ''
|
||||
@@ -13,9 +13,86 @@
|
||||
]}"
|
||||
ROOT=$(git rev-parse --show-toplevel)
|
||||
cd "$ROOT/pkgs/clan-cli"
|
||||
${self'.packages.vm-persistence}/bin/vm-persistence
|
||||
nix develop "$ROOT#clan-cli" -c bash -c "TMPDIR=/tmp python -m pytest -m impure ./tests $@"
|
||||
'';
|
||||
|
||||
# TODO: port this to python and make it pure
|
||||
vm-persistence =
|
||||
let
|
||||
machineConfigFile = builtins.toFile "vm-config.json" (builtins.toJSON {
|
||||
clanCore.state.my-state = {
|
||||
folders = [ "/var/my-state" ];
|
||||
};
|
||||
# powers off the machine after the state is created
|
||||
systemd.services.poweroff = {
|
||||
description = "Poweroff the machine";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "my-state.service" ];
|
||||
script = ''
|
||||
echo "Powering off the machine"
|
||||
poweroff
|
||||
'';
|
||||
};
|
||||
# creates a file in the state folder
|
||||
systemd.services.my-state = {
|
||||
description = "Create a file in the state folder";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script = ''
|
||||
echo "Creating a file in the state folder"
|
||||
echo "dream2nix" > /var/my-state/test
|
||||
'';
|
||||
serviceConfig.Type = "oneshot";
|
||||
};
|
||||
clan.virtualisation.graphics = false;
|
||||
users.users.root.password = "root";
|
||||
});
|
||||
in
|
||||
pkgs.writeShellScriptBin "vm-persistence" ''
|
||||
#!${pkgs.bash}/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export PATH="${lib.makeBinPath [
|
||||
pkgs.coreutils
|
||||
pkgs.gitMinimal
|
||||
pkgs.jq
|
||||
pkgs.nix
|
||||
pkgs.gnused
|
||||
self'.packages.clan-cli
|
||||
]}"
|
||||
|
||||
clanName=_test_vm_persistence
|
||||
testFile=~/".config/clan/vmstate/$clanName/my-machine/var/my-state/test"
|
||||
|
||||
export TMPDIR=$(${pkgs.coreutils}/bin/mktemp -d)
|
||||
trap "${pkgs.coreutils}/bin/chmod -R +w '$TMPDIR'; ${pkgs.coreutils}/bin/rm -rf '$TMPDIR'" EXIT
|
||||
|
||||
# clean up vmstate after test
|
||||
trap "${pkgs.coreutils}/bin/rm -rf ~/.config/clan/vmstate/$clanName" EXIT
|
||||
|
||||
cd $TMPDIR
|
||||
mkdir ./clan
|
||||
cd ./clan
|
||||
nix flake init -t ${self}#templates.new-clan
|
||||
nix flake lock --override-input clan-core ${self}
|
||||
sed -i "s/__CHANGE_ME__/$clanName/g" flake.nix
|
||||
clan machines create my-machine
|
||||
|
||||
cat ${machineConfigFile} | jq > ./machines/my-machine/settings.json
|
||||
|
||||
# clear state from previous runs
|
||||
rm -rf "$testFile"
|
||||
|
||||
# machine will automatically shutdown due to the shutdown service above
|
||||
clan vms run my-machine
|
||||
|
||||
set -x
|
||||
if ! test -e "$testFile"; then
|
||||
echo "failed: file "$testFile" was not created"
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
|
||||
runMockApi = pkgs.writeShellScriptBin "run-mock-api" ''
|
||||
#!${pkgs.bash}/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
Reference in New Issue
Block a user