diff --git a/pkgs/clan-cli/clan_cli/machines/install.py b/pkgs/clan-cli/clan_cli/machines/install.py index 0f839f7da..9a625f118 100644 --- a/pkgs/clan-cli/clan_cli/machines/install.py +++ b/pkgs/clan-cli/clan_cli/machines/install.py @@ -100,7 +100,9 @@ def install_machine(opts: InstallOptions) -> None: ] if not machine.can_build_locally or opts.build_on_remote: - machine.info("Architecture mismatch. Building on remote machine") + machine.info( + f"Target machine has architecture {machine.system} which cannot be built locally or with the configured remote builders. Building on target machine" + ) cmd.append("--build-on-remote") if machine.target_host.port: diff --git a/pkgs/clan-cli/clan_cli/machines/machines.py b/pkgs/clan-cli/clan_cli/machines/machines.py index a4577b835..2b5e46fee 100644 --- a/pkgs/clan-cli/clan_cli/machines/machines.py +++ b/pkgs/clan-cli/clan_cli/machines/machines.py @@ -5,6 +5,7 @@ from dataclasses import dataclass, field from functools import cached_property from pathlib import Path from tempfile import NamedTemporaryFile +from time import time from typing import TYPE_CHECKING, Any, Literal from clan_cli.clan_uri import FlakeId @@ -78,10 +79,32 @@ class Machine: @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"] + config = nix_config() + if self.system == config["system"] or self.system in config["extra-platforms"]: + return True + + unsubstitutable_drv = json.loads( + run_no_stdout( + nix_eval( + [ + "--impure", + "--expr", + f'((builtins.getFlake "{self.flake}").inputs.nixpkgs.legacyPackages.{self.system}.runCommandNoCC "clan-can-build-{int(time())}" {{ }} "touch $out").drvPath', + ] + ), + opts=RunOpts(prefix=self.name), + ).stdout.strip() + ) + + try: + run_no_stdout( + nix_build([f"{unsubstitutable_drv}^*"]), opts=RunOpts(prefix=self.name) + ) + except Exception as e: + self.debug("failed to build test derivation", exc_info=e) + return False + else: + return True @property def deployment(self) -> dict: diff --git a/pyproject.toml b/pyproject.toml index 080d859c6..23d87d00e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,6 @@ lint.select = [ ] lint.ignore = [ "A003", - "ANN101", "ANN401", "TRY400", "E402",