Merge pull request 'hardware-update-split' (#5261) from Qubasa/clan-core:hardware-update-split into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5261
This commit is contained in:
Luis Hebendanz
2025-09-24 14:54:32 +00:00
8 changed files with 215 additions and 16 deletions

View File

@@ -69,7 +69,7 @@ class HardwareGenerateOptions:
@API.register
def run_machine_hardware_info(
def run_machine_hardware_info_init(
opts: HardwareGenerateOptions,
target_host: Remote,
) -> HardwareConfig:
@@ -157,6 +157,80 @@ def run_machine_hardware_info(
return opts.backend
@API.register
def run_machine_hardware_info_update(
opts: HardwareGenerateOptions,
target_host: Remote,
) -> HardwareConfig:
"""Generate hardware information for a machine
and place the resulting *.nix file in the machine's directory.
"""
machine = opts.machine
hw_file = opts.backend.config_path(opts.machine)
hw_file.parent.mkdir(parents=True, exist_ok=True)
if opts.backend == HardwareConfig.NIXOS_FACTER:
config_command = ["nixos-facter"]
else:
config_command = [
"nixos-generate-config",
# Filesystems are managed by disko
"--no-filesystems",
"--show-hardware-config",
]
with target_host.host_connection() as ssh, ssh.become_root() as sudo_ssh:
out = sudo_ssh.run(config_command, opts=RunOpts(check=False))
if out.returncode != 0:
if "nixos-facter" in out.stderr and "not found" in out.stderr:
machine.error(str(out.stderr))
msg = (
"Please use our custom nixos install images from https://github.com/nix-community/nixos-images/releases/tag/nixos-unstable. "
"nixos-factor only works on nixos / clan systems currently."
)
raise ClanError(msg)
machine.error(str(out))
msg = f"Failed to inspect {opts.machine}. Address: {target_host.target}"
raise ClanError(msg)
backup_file = None
if hw_file.exists():
backup_file = hw_file.with_suffix(".bak")
hw_file.replace(backup_file)
hw_file.write_text(out.stdout)
print(f"Successfully generated: {hw_file}")
# try to evaluate the machine
# If it fails, the hardware-configuration.nix file is invalid
commit_file(
hw_file,
opts.machine.flake.path,
f"machines/{opts.machine.name}/{hw_file.name}: update hardware configuration",
)
try:
get_machine_target_platform(opts.machine)
if backup_file:
backup_file.unlink(missing_ok=True)
except ClanCmdError as e:
log.exception("Failed to evaluate hardware-configuration.nix")
# Restore the backup file
print(f"Restoring backup file {backup_file}")
if backup_file:
backup_file.replace(hw_file)
# TODO: Undo the commit
msg = "Invalid hardware-configuration.nix file"
raise ClanError(
msg,
description=f"Configuration at '{hw_file}' is invalid. Please check the file and try again.",
) from e
return opts.backend
def get_machine_hardware_config(machine: Machine) -> HardwareConfig:
"""Detect and return the full hardware configuration for the given machine.

View File

@@ -122,7 +122,7 @@ def upload_sources(machine: Machine, ssh: Host, upload_inputs: bool) -> str:
def run_machine_update(
machine: Machine,
target_host: Remote | LocalHost,
build_host: Remote | LocalHost | None,
build_host: Remote | LocalHost | None = None,
upload_inputs: bool = False,
) -> None:
"""Update an existing machine using nixos-rebuild or darwin-rebuild.

View File

@@ -64,6 +64,8 @@ class Remote:
def override(
self,
*,
user: str | None = None,
address: str | None = None,
host_key_check: HostKeyCheck | None = None,
private_key: Path | None = None,
password: str | None = None,
@@ -75,8 +77,8 @@ class Remote:
) -> "Remote":
"""Returns a new Remote instance with the same data but with a different host_key_check."""
return Remote(
address=self.address,
user=self.user,
address=address or self.address,
user=user or self.user,
command_prefix=command_prefix or self.command_prefix,
port=port or self.port,
private_key=private_key if private_key is not None else self.private_key,