api/machines: allow config verification on imaginary machines
All checks were successful
checks-impure / test (pull_request) Successful in 1m37s
checks / test (pull_request) Successful in 2m39s

Machines do not need to exist in order to verify their configuration.

This allows verifying a config before creating an actual machine with it.
This commit is contained in:
DavHau 2023-11-13 21:24:05 +07:00
parent 7eb664fd08
commit 6a52c5f15b
3 changed files with 43 additions and 7 deletions

View File

@ -2,7 +2,6 @@ import json
import os
import re
import subprocess
from pathlib import Path
from tempfile import NamedTemporaryFile
from typing import Optional
@ -10,6 +9,7 @@ from fastapi import HTTPException
from clan_cli.dirs import (
machine_settings_file,
nixpkgs_source,
specific_flake_dir,
specific_machine_dir,
)
@ -24,7 +24,6 @@ def verify_machine_config(
flake_name: FlakeName,
machine_name: str,
config: Optional[dict] = None,
flake: Optional[Path] = None,
) -> Optional[str]:
"""
Verify that the machine evaluates successfully
@ -40,11 +39,34 @@ def verify_machine_config(
env["CLAN_MACHINE_SETTINGS_FILE"] = clan_machine_settings_file.name
cmd = nix_eval(
flags=[
"--impure",
"--show-trace",
"--show-trace",
"--impure", # needed to access CLAN_MACHINE_SETTINGS_FILE
f".#nixosConfigurations.{machine_name}.config.system.build.vm.outPath",
"--expr",
f"""
let
# hardcoding system for now, not sure where to get it from
system = "x86_64-linux";
flake = builtins.getFlake (toString {flake});
clan-core = flake.inputs.clan-core;
nixpkgsSrc = flake.inputs.nixpkgs or {nixpkgs_source()};
lib = import (nixpkgsSrc + /lib);
pkgs = import nixpkgsSrc {{ inherit system; }};
config = lib.importJSON (builtins.getEnv "CLAN_MACHINE_SETTINGS_FILE");
fakeMachine = pkgs.nixos {{
imports =
[
clan-core.nixosModules.clanCore
# potentially the config might affect submodule options,
# therefore we need to import it
config
{{clanCore.clanDir = {flake};}}
]
# add all clan modules specified via clanImports
++ (map (name: clan-core.clanModules.${{name}}) config.clanImports or []);
}};
in
fakeMachine.config.system.build.vm.outPath
""",
],
)
# repro_env_break(work_dir=flake, env=env, cmd=cmd)

View File

@ -43,7 +43,8 @@ def machine_schema(
f"""
let
b = builtins;
system = b.currentSystem;
# hardcoding system for now, not sure where to get it from
system = "x86_64-linux";
flake = b.getFlake (toString {flake});
clan-core = flake.inputs.clan-core;
config = b.fromJSON (b.readFile (b.getEnv "CLAN_MACHINE_SETTINGS_FILE"));
@ -85,7 +86,8 @@ def machine_schema(
"--expr",
f"""
let
system = builtins.currentSystem;
# hardcoding system for now, not sure where to get it from
system = "x86_64-linux";
flake = builtins.getFlake (toString {flake});
clan-core = flake.inputs.clan-core;
nixpkgsSrc = flake.inputs.nixpkgs or {nixpkgs_source()};

View File

@ -62,6 +62,18 @@ def test_create_machine_invalid_hostname(
)
@pytest.mark.with_core
def test_verify_config_without_machine(
api: TestClient, test_flake_with_core: FlakeForTest
) -> None:
response = api.put(
f"/api/{test_flake_with_core.name}/machines/test/verify",
json=dict(),
)
assert response.status_code == 200
assert response.json() == {"success": True, "error": None}
@pytest.mark.with_core
def test_configure_machine(api: TestClient, test_flake_with_core: FlakeForTest) -> None:
# ensure error 404 if machine does not exist when accessing the config