modules.services.nixvirt: finish

This commit is contained in:
2025-05-02 20:07:56 +08:00
parent d0c4512a8e
commit d46ad39a3b
5 changed files with 93 additions and 19 deletions

View File

@@ -35,7 +35,7 @@ inputs:
sshd = {};
nixvirt =
{
test = { memoryGB = 8; cpus = 4; address = 2; };
test = { memoryGB = 8; cpus = 4; address = 2; owner = "chn"; };
};
};
user.users = [ "chn" "aleksana" ];

View File

@@ -19,7 +19,7 @@ inputs:
cpus = mkOption { type = types.ints.unsigned; };
vncPort = mkOption { type = types.ints.unsigned; default = 15900 + submoduleInputs.config.address; };
mac = mkOption
{ type = types.nonEmptyStr; default = "02:${createString "-" [ [ 0 2 ] [ 2 2 ] [ 4 2 ] [ 6 2 ] [ 8 2 ] ]}"; };
{ type = types.nonEmptyStr; default = "02:${createString ":" [ [ 0 2 ] [ 2 2 ] [ 4 2 ] [ 6 2 ] [ 8 2 ] ]}"; };
address = mkOption { type = types.ints.unsigned; };
owner = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; };
};})));
@@ -106,5 +106,29 @@ inputs:
placeholder = builtins.listToAttrs (builtins.map
(vm: { name = "nixvirt/${vm}"; value = builtins.hashString "sha256" vm; }) (builtins.attrNames nixvirt));
};
security.wrappers.vm =
{
source =
let vm = inputs.pkgs.localPackages.vm.override
{
vmConfig = inputs.pkgs.writeText "vm.yaml" (builtins.toJSON
({
virsh = "${inputs.pkgs.libvirt}/bin/virsh";
vm =
let vms = builtins.groupBy (vm: vm.value.owner) (inputs.localLib.attrsToList nixvirt);
in builtins.listToAttrs (builtins.map (owner:
{
name = builtins.toString inputs.config.nixos.user.uid.${owner.name};
value = builtins.map (vm: vm.name) owner.value;
})
(inputs.localLib.attrsToList vms));
}));
};
in "${vm}/bin/vm";
program = "vm";
owner = "root";
group = "root";
setuid = true;
};
};
}

View File

@@ -23,6 +23,7 @@ namespace biu
template <detail_::ExecMode Mode> detail_::ExecResult<Mode> exec(detail_::ExecInput<Mode> input)
{
// TODO: switch to v2
namespace bp = boost::process;
// decide input/output format, prepare environment, seach actual program

View File

@@ -1 +1,63 @@
int main() {}
# include <biu.hpp>
# ifndef VM_CONFIG
# define VM_CONFIG "./vm.yaml"
# endif
int main(int argc, char** argv)
{
using namespace biu::literals;
biu::Logger::try_exec([&]
{
struct
{
std::string virsh;
std::map<uid_t, std::set<std::string>> vm;
} config = YAML::LoadFile(VM_CONFIG).as<decltype(config)>();
auto uid = getuid();
if (setuid(0) == -1) throw std::runtime_error("Failed to setuid to root");
if (setgid(0) == -1) throw std::runtime_error("Failed to setgid to root");
std::vector<std::string> args(argv + 1, argv + argc);
std::map<std::string, std::string> vm_to_virsh =
{
{"status", "dominfo"},
{"start", "start"},
{"stop", "shutdown"},
{"force-stop", "destroy"},
{"reboot", "reboot"},
{"force-reboot", "reset"}
};
if (args.empty()) std::cout << R"(
vm list
get list of VMs owned by current user
vm status <vm>
get status of specified VM (virsh dominfo)
vm start <vm>
start specified VM if it is not running (virsh start)
vm stop <vm>
try to gracefully stop specified VM (may not success, virsh shutdown)
vm force-stop <vm>
force stop specified VM (virsh destroy)
vm reboot <vm>
reboot specified VM (virsh reboot)
vm force-reboot <vm>
force reboot specified VM (virsh reset)
)";
else if (args[0] == "list")
{
if (!config.vm.contains(uid)) throw std::runtime_error("No VM found for current user");
std::cout << "{}\n"_f(config.vm[uid]);
}
else if (vm_to_virsh.contains(args[0]))
{
if (args.size() != 2)
throw std::runtime_error("Invalid argument count, expected 2, received {}"_f(args.size()));
if (!config.vm.contains(uid)) throw std::runtime_error("No VM found for current user");
if (!config.vm[uid].contains(args[1]))
throw std::runtime_error("VM {} is not owned by current user"_f(args[1]));
biu::exec<{.DirectStdout = true, .DirectStderr = true, .SearchPath = false}>
({config.virsh, { vm_to_virsh[args[0]], args[1] }});
}
else throw std::runtime_error("unknown command: {}"_f(args[0]));
});
}

View File

@@ -1,16 +1,3 @@
Program:
VaspCpu:
Queue:
- Name: localhost
Recommended:
Mpi: 4
Openmp: 4
Memory: 64
VaspGpu:
Queue:
- Name: localhost
Gpu: [ "4060" ]
Mumax3:
Queue:
- Name: localhost
Gpu: [ "4060" ]
virsh: /run/current-system/sw/bin/virsh
vm:
1000: ["test"]