diff --git a/lib/build-clan/interface.nix b/lib/build-clan/interface.nix index 8dd3abf74..df4743980 100644 --- a/lib/build-clan/interface.nix +++ b/lib/build-clan/interface.nix @@ -3,6 +3,7 @@ let types = lib.types; in { + options = { # Required options directory = lib.mkOption { @@ -69,18 +70,6 @@ in default = { }; }; - pkgsForSystem = lib.mkOption { - type = types.functionTo (types.nullOr types.attrs); - default = _: null; - defaultText = "Lambda :: String -> { ... } | null"; - description = '' - A function that maps from architecture to pkg. `( string -> pkgs )` - - If specified this nixpkgs will be only imported once for each system. - This improves performance, but all nipxkgs.* options will be ignored. - ''; - }; - # Outputs nixosConfigurations = lib.mkOption { # Hide from documentation. @@ -112,4 +101,5 @@ in }; }; }; + } diff --git a/lib/build-clan/module.nix b/lib/build-clan/module.nix index 079a7762c..072b16c98 100644 --- a/lib/build-clan/module.nix +++ b/lib/build-clan/module.nix @@ -9,7 +9,6 @@ let inherit (config) directory machines - pkgsForSystem specialArgs ; @@ -58,7 +57,7 @@ let # Settings clan.core.clanDir = directory; # Inherited from clan wide settings - # TODO: remove these + # TODO: remove these` clan.core.name = config.inventory.meta.name; clan.core.icon = config.inventory.meta.icon; @@ -105,7 +104,12 @@ let name: _: nixosConfiguration { inherit name system; - pkgs = pkgsForSystem system; + + # We removed pkgsForSystems because we have the problem that nixpkgs.* options are then ignored + # However our current model is to have the hardware config read and then set nixpkgs.hostPlatform automatically + # which gets ignored if we set pkgsForSystems. pkgsForSystems also needed to be set as else + # pkgs was equals to null in nixosConfiguration above which broke something else + pkgs = nixpkgs.legacyPackages.${system}; } ) allMachines ) @@ -122,7 +126,7 @@ let args // { inherit name system; - pkgs = pkgsForSystem system; + pkgs = nixpkgs.legacyPackages.${system}; } ) ) allMachines diff --git a/pkgs/clan-cli/clan_cli/machines/install.py b/pkgs/clan-cli/clan_cli/machines/install.py index 05fbadc9c..52d2ff440 100644 --- a/pkgs/clan-cli/clan_cli/machines/install.py +++ b/pkgs/clan-cli/clan_cli/machines/install.py @@ -15,6 +15,7 @@ from clan_cli.completions import ( complete_machines, complete_target_host, ) +from clan_cli.errors import ClanError from clan_cli.facts.generate import generate_facts from clan_cli.machines.hardware import HardwareConfig from clan_cli.machines.machines import Machine @@ -25,10 +26,6 @@ from clan_cli.vars.generate import generate_vars log = logging.getLogger(__name__) -class ClanError(Exception): - pass - - @dataclass class InstallOptions: # flake to install @@ -85,9 +82,6 @@ def install_machine(opts: InstallOptions) -> None: if opts.no_reboot: cmd.append("--no-reboot") - if opts.build_on_remote: - cmd.append("--build-on-remote") - if opts.update_hardware_config is not HardwareConfig.NONE: cmd.extend( [ @@ -108,6 +102,10 @@ def install_machine(opts: InstallOptions) -> None: "IdentitiesOnly=yes", ] + if not machine.can_build_locally or opts.build_on_remote: + log.info("Architecture mismatch. Building on remote machine") + cmd.append("--build-on-remote") + if machine.target_host.port: cmd += ["--ssh-port", str(machine.target_host.port)] if opts.kexec: diff --git a/pkgs/clan-cli/clan_cli/machines/machines.py b/pkgs/clan-cli/clan_cli/machines/machines.py index 2818414a6..b02599eac 100644 --- a/pkgs/clan-cli/clan_cli/machines/machines.py +++ b/pkgs/clan-cli/clan_cli/machines/machines.py @@ -46,6 +46,32 @@ class Machine: def __repr__(self) -> str: return str(self) + @property + def system(self) -> str: + # We filter out function attributes because they are not serializable. + attr = f""" + (let + machine = ((builtins.getFlake "{self.flake}").nixosConfigurations.{self.name}); + in + {{ x = machine.pkgs.stdenv.hostPlatform.system; }}).x + """ + if attr in self._eval_cache: + output = self._eval_cache[attr] + else: + output = run_no_stdout( + nix_eval(["--impure", "--expr", attr]) + ).stdout.strip() + self._eval_cache[attr] = output + value = json.loads(output) + return value + + @property + def can_build_locally(self) -> bool: + # TODO: We could also use the function pkgs.stdenv.hostPlatform.canExecute + # but this is good enough for now. + output = nix_config() + return self.system == output["system"] + @property def deployment(self) -> dict: if self.cached_deployment is not None: @@ -173,7 +199,6 @@ class Machine: method: Literal["eval", "build"], attr: str, extra_config: None | dict = None, - impure: bool = False, nix_options: list[str] | None = None, ) -> str | Path: """ @@ -215,12 +240,6 @@ class Machine: "dirtyRevision" in metadata or "dirtyRev" in metadata["locks"]["nodes"]["clan-core"]["locked"] ): - # if not impure: - # raise ClanError( - # "The machine has a dirty revision, and impure mode is not allowed" - # ) - # else: - # args += ["--impure"] args += ["--impure"] args += [ @@ -254,7 +273,6 @@ class Machine: attr: str, refresh: bool = False, extra_config: None | dict = None, - impure: bool = False, nix_options: list[str] | None = None, ) -> str: """ @@ -266,7 +284,7 @@ class Machine: if attr in self._eval_cache and not refresh and extra_config is None: return self._eval_cache[attr] - output = self.nix("eval", attr, extra_config, impure, nix_options) + output = self.nix("eval", attr, extra_config, nix_options) if isinstance(output, str): self._eval_cache[attr] = output return output @@ -278,7 +296,6 @@ class Machine: attr: str, refresh: bool = False, extra_config: None | dict = None, - impure: bool = False, nix_options: list[str] | None = None, ) -> Path: """ @@ -291,7 +308,7 @@ class Machine: if attr in self._build_cache and not refresh and extra_config is None: return self._build_cache[attr] - output = self.nix("build", attr, extra_config, impure, nix_options) + output = self.nix("build", attr, extra_config, nix_options) if isinstance(output, Path): self._build_cache[attr] = output return output