From cf95fd33b07bd9cb1d9c98378d29d1e371c93b9b Mon Sep 17 00:00:00 2001 From: Else Someone Date: Sat, 7 Mar 2026 21:16:53 +0200 Subject: [PATCH] uvms: add --mem Yeah, yeah, I know, it's stupid, adding add_argument() statements manually, et c. I'll throw the whole Python thing away whenever I might have the time --- pkgs/uvms/uvms.py | 20 ++++ profiles/baseImage.nix | 221 +++++++++++++++++++++++------------------ 2 files changed, 143 insertions(+), 98 deletions(-) diff --git a/pkgs/uvms/uvms.py b/pkgs/uvms/uvms.py index c473f11..534a7b9 100644 --- a/pkgs/uvms/uvms.py +++ b/pkgs/uvms/uvms.py @@ -10,6 +10,7 @@ import os import subprocess import socket import json +import re from argparse import ArgumentParser from contextlib import contextmanager, closing, ExitStack @@ -20,6 +21,7 @@ parser.add_argument("--prefix", default="$HOME/uvms/$VM") parser.add_argument("--vm-config", default="@BASE_CONFIG@") # noqa: E501 parser.add_argument("--persist-home", action="store_true") parser.add_argument("--run", action="append") +parser.add_argument("--mem", default=None) parser.add_argument("app", nargs="*", default=()) TOOLS_DIR = "@TOOLS@" # noqa: E501 @@ -469,6 +471,21 @@ def connect_ch_vsock( yield s +BYTES_PATTERN = re.compile(r"^([0-9]+)([MmGgKk]?)$") +BYTES_UNITS = { + "k": 1024, + "m": 1048576, + "g": 1024 * 1048576, +} + + +def parse_bytes(s): + m = BYTES_PATTERN.match(s) + assert m, s + size, unit = m.groups() + return int(size) * BYTES_UNITS.get(unit.lower(), 1) + + @contextmanager def listen_ch_vsock( vsock_sock_path, @@ -564,6 +581,9 @@ def main(args, args_next, cleanup, ps): ) virtiofs_socks.append(("home", sock_path)) config["payload"]["cmdline"] += " uvms.persist-home=1" + if args.mem is not None: + config["memory"]["size"] = parse_bytes(args.mem) + config["memory"]["hotplug_size"] = parse_bytes(args.mem) gpud, gpud_path = cleanup.enter_context(ps.start_gpu()) diff --git a/profiles/baseImage.nix b/profiles/baseImage.nix index 2f9029a..289f903 100644 --- a/profiles/baseImage.nix +++ b/profiles/baseImage.nix @@ -301,121 +301,146 @@ in }; uvms.ch.settings = mkOption { default = { }; - type = types.submodule { - freeformType = jsonType; - options = { - payload = { - cmdline = mkOption { - type = types.str; - default = concatStringsSep " " ( - config.boot.kernelParams - ++ [ - # "init=${lib.removePrefix "/nix/store" "${config.system.build.toplevel}"}/init" - "init=${config.system.build.toplevel}/init" - ] - ); - defaultText = ''concatStringsSep " " ${config.boot.kernelParams}''; + type = types.submodule ( + let + osConfig = config; + in + { config, ... }: + { + freeformType = jsonType; + options = { + payload = { + cmdline = mkOption { + type = types.str; + default = concatStringsSep " " ( + osConfig.boot.kernelParams + ++ [ + # "init=${lib.removePrefix "/nix/store" "${osConfig.system.build.toplevel}"}/init" + "init=${osConfig.system.build.toplevel}/init" + ] + ); + defaultText = ''concatStringsSep " " ${osConfig.boot.kernelParams}''; + }; + kernel = mkOption { + type = types.str; + default = "${kernel}/${kernelTarget}"; + }; + initramfs = mkOption { + type = types.nullOr types.str; + default = "${initialRamdisk}/${initrdFile}"; + }; }; - kernel = mkOption { - type = types.str; - default = "${kernel}/${kernelTarget}"; + vsock = { + cid = mkOption { + type = types.int; + default = 4; + }; + socket = mkOption { + type = types.str; + default = "vsock.sock"; + }; }; - initramfs = mkOption { + "api-socket" = mkOption { + type = types.str; + default = "vmm.sock"; + }; + "serial".mode = mkOption { + type = types.str; + default = "File"; + }; + "serial".file = mkOption { type = types.nullOr types.str; - default = "${initialRamdisk}/${initrdFile}"; + default = "serial"; }; - }; - vsock = { - cid = mkOption { - type = types.int; - default = 4; - }; - socket = mkOption { + "console".mode = mkOption { type = types.str; - default = "vsock.sock"; + default = "Pty"; }; - }; - "api-socket" = mkOption { - type = types.str; - default = "vmm.sock"; - }; - "serial".mode = mkOption { - type = types.str; - default = "File"; - }; - "serial".file = mkOption { - type = types.nullOr types.str; - default = "serial"; - }; - "console".mode = mkOption { - type = types.str; - default = "Pty"; - }; - "console".file = mkOption { - type = types.nullOr types.str; - default = null; - }; - # "watchdog" = true; - # "seccomp" = true; - disks = mkOption { - default = [ ]; - type = types.listOf ( - types.submodule { + "console".file = mkOption { + type = types.nullOr types.str; + default = null; + }; + # "watchdog" = true; + # "seccomp" = true; + disks = mkOption { + default = [ ]; + type = types.listOf ( + types.submodule { + freeformType = jsonType; + options = { + path = mkOption { + type = types.oneOf [ + types.path + types.str + ]; + }; + readonly = mkOption { + type = types.bool; + default = true; + }; + id = mkOption { type = types.str; }; + }; + } + ); + }; + memory = mkOption { + default = { }; + type = types.submodule { freeformType = jsonType; options = { - path = mkOption { - type = types.oneOf [ - types.path - types.str - ]; + size = mkOption { + type = types.int; + default = 2 * 1024 * 1048576; }; - readonly = mkOption { + shared = mkOption { type = types.bool; default = true; }; - id = mkOption { type = types.str; }; + mergeable = mkOption { + type = types.bool; + default = true; + }; + hotplug_method = mkOption { + default = "VirtioMem"; + type = types.enum [ + "Acpi" + "VirtioMem" + ]; + }; + hotplugged_size = mkOption { + type = types.int; + default = 512 * 1048576; + }; + hotplug_size = mkOption { + type = types.int; + default = config.memory.size; + }; + # hugepages = mkOption { + # type = types.bool; + # default = true; + # }; }; - } - ); - }; - memory = mkOption { - default = { }; - type = types.submodule { - freeformType = jsonType; - options = { - size = mkOption { - type = types.int; - default = 3 * 1024 * 1048576; - }; - shared = mkOption { - type = types.bool; - default = true; - }; - mergeable = mkOption { - type = types.bool; - default = true; + }; + }; + cpus = mkOption { + default = { }; + type = types.submodule { + freeformType = jsonType; + options = { + boot_vcpus = mkOption { + type = types.int; + default = 4; + }; + max_vcpus = mkOption { + type = types.int; + default = 4; + }; }; }; }; }; - cpus = mkOption { - default = { }; - type = types.submodule { - freeformType = jsonType; - options = { - boot_vcpus = mkOption { - type = types.int; - default = 4; - }; - max_vcpus = mkOption { - type = types.int; - default = 4; - }; - }; - }; - }; - }; - }; + } + ); }; }; }