From bc36ec4c1a7d7069ac1da6483935ce096ee4065e Mon Sep 17 00:00:00 2001 From: lassulus Date: Wed, 4 Oct 2023 18:01:50 +0200 Subject: [PATCH] vms: support secrets and fix cross compilation --- nixosModules/clanCore/vm.nix | 10 ++++++++ pkgs/clan-cli/clan_cli/task_manager.py | 5 ++-- pkgs/clan-cli/clan_cli/vms/create.py | 34 +++++++++++++++++++++++--- pkgs/clan-cli/clan_cli/vms/inspect.py | 6 +++-- 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/nixosModules/clanCore/vm.nix b/nixosModules/clanCore/vm.nix index d9d0a9516..acd57c15f 100644 --- a/nixosModules/clanCore/vm.nix +++ b/nixosModules/clanCore/vm.nix @@ -3,6 +3,14 @@ let vmConfig = extendModules { modules = [ (modulesPath + "/virtualisation/qemu-vm.nix") + { + virtualisation.fileSystems.${config.clanCore.secretsUploadDirectory} = lib.mkForce { + device = "secrets"; + fsType = "9p"; + neededForBoot = true; + options = [ "trans=virtio" "version=9p2000.L" "cache=loose" ]; + }; + } ]; }; in @@ -52,6 +60,8 @@ in toplevel = vmConfig.config.system.build.toplevel; regInfo = (pkgs.closureInfo { rootPaths = vmConfig.config.virtualisation.additionalPaths; }); inherit (config.clan.virtualisation) memorySize cores graphics; + generateSecrets = config.system.clan.generateSecrets; + uploadSecrets = config.system.clan.uploadSecrets; }); }; diff --git a/pkgs/clan-cli/clan_cli/task_manager.py b/pkgs/clan-cli/clan_cli/task_manager.py index d1fa34045..a710b33ca 100644 --- a/pkgs/clan-cli/clan_cli/task_manager.py +++ b/pkgs/clan-cli/clan_cli/task_manager.py @@ -8,7 +8,7 @@ import sys import threading import traceback from enum import Enum -from typing import Any, Iterator, Type, TypeVar +from typing import Any, Iterator, Optional, Type, TypeVar from uuid import UUID, uuid4 from .errors import ClanError @@ -30,7 +30,7 @@ class Command: self._output.put(None) self.done = True - def run(self, cmd: list[str]) -> None: + def run(self, cmd: list[str], env: Optional[dict[str, str]] = None) -> None: self.running = True self.log.debug(f"Running command: {shlex.join(cmd)}") self.p = subprocess.Popen( @@ -38,6 +38,7 @@ class Command: stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8", + env=env, ) assert self.p.stdout is not None and self.p.stderr is not None os.set_blocking(self.p.stdout.fileno(), False) diff --git a/pkgs/clan-cli/clan_cli/vms/create.py b/pkgs/clan-cli/clan_cli/vms/create.py index e754703e7..5888ec20b 100644 --- a/pkgs/clan-cli/clan_cli/vms/create.py +++ b/pkgs/clan-cli/clan_cli/vms/create.py @@ -1,32 +1,36 @@ import argparse import asyncio import json +import os import shlex +import sys import tempfile from pathlib import Path from typing import Iterator from uuid import UUID from ..dirs import get_clan_flake_toplevel -from ..nix import nix_build, nix_shell +from ..nix import nix_build, nix_config, nix_shell from ..task_manager import BaseTask, Command, create_task from .inspect import VmConfig, inspect_vm class BuildVmTask(BaseTask): def __init__(self, uuid: UUID, vm: VmConfig) -> None: - super().__init__(uuid, num_cmds=4) + super().__init__(uuid, num_cmds=6) self.vm = vm def get_vm_create_info(self, cmds: Iterator[Command]) -> dict: + config = nix_config() + system = config["system"] + clan_dir = self.vm.flake_url machine = self.vm.flake_attr cmd = next(cmds) cmd.run( nix_build( [ - # f'{clan_dir}#clanInternals.machines."{system}"."{machine}".config.clan.virtualisation.createJSON' # TODO use this - f'{clan_dir}#nixosConfigurations."{machine}".config.system.clan.vm.create' + f'{clan_dir}#clanInternals.machines."{system}"."{machine}".config.system.clan.vm.create' ] ) ) @@ -48,8 +52,29 @@ class BuildVmTask(BaseTask): tmpdir = Path(tmpdir_) xchg_dir = tmpdir / "xchg" xchg_dir.mkdir() + secrets_dir = tmpdir / "secrets" + secrets_dir.mkdir() disk_img = f"{tmpdir_}/disk.img" + env = os.environ.copy() + env["CLAN_DIR"] = str(self.vm.flake_url) + env["PYTHONPATH"] = str( + ":".join(sys.path) + ) # TODO do this in the clanCore module + env["SECRETS_DIR"] = str(secrets_dir) + + cmd = next(cmds) + cmd.run( + [vm_config["generateSecrets"]], + env=env, + ) + + cmd = next(cmds) + cmd.run( + [vm_config["uploadSecrets"]], + env=env, + ) + cmd = next(cmds) cmd.run( nix_shell( @@ -97,6 +122,7 @@ class BuildVmTask(BaseTask): "-virtfs", "local,path=/nix/store,security_model=none,mount_tag=nix-store", "-virtfs", f"local,path={xchg_dir},security_model=none,mount_tag=shared", "-virtfs", f"local,path={xchg_dir},security_model=none,mount_tag=xchg", + "-virtfs", f"local,path={secrets_dir},security_model=none,mount_tag=secrets", "-drive", f'cache=writeback,file={disk_img},format=raw,id=drive1,if=none,index=1,werror=report', "-device", "virtio-blk-pci,bootindex=1,drive=drive1,serial=root", "-device", "virtio-keyboard", diff --git a/pkgs/clan-cli/clan_cli/vms/inspect.py b/pkgs/clan-cli/clan_cli/vms/inspect.py index 9b8559a75..83230add1 100644 --- a/pkgs/clan-cli/clan_cli/vms/inspect.py +++ b/pkgs/clan-cli/clan_cli/vms/inspect.py @@ -6,7 +6,7 @@ from pydantic import BaseModel from ..async_cmd import run from ..dirs import get_clan_flake_toplevel -from ..nix import nix_eval +from ..nix import nix_config, nix_eval class VmConfig(BaseModel): @@ -19,9 +19,11 @@ class VmConfig(BaseModel): async def inspect_vm(flake_url: str, flake_attr: str) -> VmConfig: + config = nix_config() + system = config["system"] cmd = nix_eval( [ - f"{flake_url}#nixosConfigurations.{json.dumps(flake_attr)}.config.system.clan.vm.config" + f'{flake_url}#clanInternals.machines."{system}"."{flake_attr}".config.system.clan.vm.config' ] ) stdout = await run(cmd)