Merge pull request 'Fix deploying to macOS as root' (#3700) from nix-darwin into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3700
This commit is contained in:
6
flake.lock
generated
6
flake.lock
generated
@@ -74,11 +74,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1747365160,
|
"lastModified": 1747521943,
|
||||||
"narHash": "sha256-4ZVr0x+ry6ybym/VhVYACj0HlJo44YxAaPGOxiS88Hg=",
|
"narHash": "sha256-GMAJcB8oB9cC+TbYTE7QDfw9fwHZyloxUWnUpHnQRko=",
|
||||||
"owner": "nix-darwin",
|
"owner": "nix-darwin",
|
||||||
"repo": "nix-darwin",
|
"repo": "nix-darwin",
|
||||||
"rev": "8817b00b0011750381d0d44bb94d61087349b6ba",
|
"rev": "b9b927dd1f24094b271e8ec5277a672dc4fc860d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -9,10 +9,9 @@ from functools import cached_property
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
from clan_lib.cmd import Log, RunOpts, run
|
|
||||||
from clan_lib.errors import ClanCmdError, ClanError
|
from clan_lib.errors import ClanCmdError, ClanError
|
||||||
from clan_lib.flake import Flake
|
from clan_lib.flake import Flake
|
||||||
from clan_lib.nix import nix_config, nix_eval, nix_test_store
|
from clan_lib.nix import nix_config, nix_test_store
|
||||||
|
|
||||||
from clan_cli.facts import public_modules as facts_public_modules
|
from clan_cli.facts import public_modules as facts_public_modules
|
||||||
from clan_cli.facts import secret_modules as facts_secret_modules
|
from clan_cli.facts import secret_modules as facts_secret_modules
|
||||||
@@ -179,27 +178,6 @@ class Machine:
|
|||||||
) as build_host:
|
) as build_host:
|
||||||
yield build_host
|
yield build_host
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def deploy_as_root(self) -> bool:
|
|
||||||
if self._class_ == "nixos":
|
|
||||||
return True
|
|
||||||
|
|
||||||
# Currently nix-darwin HEAD requires you to deploy as a non-root user
|
|
||||||
# however there is a soon to be merged PR that requires deployment
|
|
||||||
# as root to match NixOS: https://github.com/nix-darwin/nix-darwin/pull/1341
|
|
||||||
return json.loads(
|
|
||||||
run(
|
|
||||||
nix_eval(
|
|
||||||
[
|
|
||||||
f"{self.flake}#darwinConfigurations.{self.name}.options.system",
|
|
||||||
"--apply",
|
|
||||||
"system: system ? primaryUser",
|
|
||||||
]
|
|
||||||
),
|
|
||||||
RunOpts(log=Log.NONE),
|
|
||||||
).stdout.strip()
|
|
||||||
)
|
|
||||||
|
|
||||||
def nix(
|
def nix(
|
||||||
self,
|
self,
|
||||||
attr: str,
|
attr: str,
|
||||||
|
|||||||
@@ -58,11 +58,18 @@ def upload_sources(machine: Machine, host: Host) -> str:
|
|||||||
if not has_path_inputs:
|
if not has_path_inputs:
|
||||||
# Just copy the flake to the remote machine, we can substitute other inputs there.
|
# Just copy the flake to the remote machine, we can substitute other inputs there.
|
||||||
path = flake_data["path"]
|
path = flake_data["path"]
|
||||||
|
|
||||||
|
remote_url = f"ssh-ng://{host.target}"
|
||||||
|
|
||||||
|
# MacOS doesn't come with a proper login shell for ssh and therefore doesn't have nix in $PATH as it doesn't source /etc/profile
|
||||||
|
if machine._class_ == "darwin":
|
||||||
|
remote_url += "?remote-program=bash -lc 'exec nix-daemon --stdio'"
|
||||||
|
|
||||||
cmd = nix_command(
|
cmd = nix_command(
|
||||||
[
|
[
|
||||||
"copy",
|
"copy",
|
||||||
"--to",
|
"--to",
|
||||||
f"ssh://{host.target}",
|
remote_url,
|
||||||
"--no-check-sigs",
|
"--no-check-sigs",
|
||||||
path,
|
path,
|
||||||
]
|
]
|
||||||
@@ -109,11 +116,6 @@ def deploy_machine(machine: Machine) -> None:
|
|||||||
target_host = stack.enter_context(machine.target_host())
|
target_host = stack.enter_context(machine.target_host())
|
||||||
build_host = stack.enter_context(machine.build_host())
|
build_host = stack.enter_context(machine.build_host())
|
||||||
|
|
||||||
if machine._class_ == "darwin":
|
|
||||||
if not machine.deploy_as_root and target_host.user == "root":
|
|
||||||
msg = f"'targetHost' should be set to a non-root user for deploying to nix-darwin on machine '{machine.name}'"
|
|
||||||
raise ClanError(msg)
|
|
||||||
|
|
||||||
host = build_host or target_host
|
host = build_host or target_host
|
||||||
|
|
||||||
generate_facts([machine], service=None, regenerate=False)
|
generate_facts([machine], service=None, regenerate=False)
|
||||||
@@ -138,9 +140,10 @@ def deploy_machine(machine: Machine) -> None:
|
|||||||
f"{path}#{machine.name}",
|
f"{path}#{machine.name}",
|
||||||
]
|
]
|
||||||
|
|
||||||
become_root = machine.deploy_as_root
|
become_root = True
|
||||||
|
|
||||||
if machine._class_ == "nixos":
|
if machine._class_ == "nixos":
|
||||||
|
switch_cmd = ["nixos-rebuild", "switch", *nix_options]
|
||||||
nix_options += [
|
nix_options += [
|
||||||
"--fast",
|
"--fast",
|
||||||
"--build-host",
|
"--build-host",
|
||||||
@@ -153,9 +156,13 @@ def deploy_machine(machine: Machine) -> None:
|
|||||||
|
|
||||||
if target_host.user != "root":
|
if target_host.user != "root":
|
||||||
nix_options += ["--use-remote-sudo"]
|
nix_options += ["--use-remote-sudo"]
|
||||||
|
elif machine._class_ == "darwin":
|
||||||
switch_cmd = [f"{machine._class_}-rebuild", "switch", *nix_options]
|
# use absolute path to darwin-rebuild
|
||||||
test_cmd = [f"{machine._class_}-rebuild", "test", *nix_options]
|
switch_cmd = [
|
||||||
|
"/run/current-system/sw/bin/darwin-rebuild",
|
||||||
|
"switch",
|
||||||
|
*nix_options,
|
||||||
|
]
|
||||||
|
|
||||||
remote_env = host.nix_ssh_env(None, local_ssh=False)
|
remote_env = host.nix_ssh_env(None, local_ssh=False)
|
||||||
ret = host.run(
|
ret = host.run(
|
||||||
@@ -182,7 +189,7 @@ def deploy_machine(machine: Machine) -> None:
|
|||||||
"Mobile machine detected, applying workaround deployment method"
|
"Mobile machine detected, applying workaround deployment method"
|
||||||
)
|
)
|
||||||
ret = host.run(
|
ret = host.run(
|
||||||
test_cmd if is_mobile else switch_cmd,
|
["nixos--rebuild", "test", *nix_options] if is_mobile else switch_cmd,
|
||||||
RunOpts(
|
RunOpts(
|
||||||
log=Log.BOTH,
|
log=Log.BOTH,
|
||||||
msg_color=MsgColor(stderr=AnsiColor.DEFAULT),
|
msg_color=MsgColor(stderr=AnsiColor.DEFAULT),
|
||||||
|
|||||||
@@ -140,16 +140,16 @@ class Host:
|
|||||||
if opts is None:
|
if opts is None:
|
||||||
opts = RunOpts()
|
opts = RunOpts()
|
||||||
|
|
||||||
# If we are not root and we need to become root, prepend sudo
|
|
||||||
sudo = ""
|
|
||||||
if become_root and self.user != "root":
|
|
||||||
sudo = "sudo -- "
|
|
||||||
|
|
||||||
# Quote all added environment variables
|
# Quote all added environment variables
|
||||||
env_vars = []
|
env_vars = []
|
||||||
for k, v in extra_env.items():
|
for k, v in extra_env.items():
|
||||||
env_vars.append(f"{shlex.quote(k)}={shlex.quote(v)}")
|
env_vars.append(f"{shlex.quote(k)}={shlex.quote(v)}")
|
||||||
|
|
||||||
|
sudo = []
|
||||||
|
if become_root and self.user != "root":
|
||||||
|
# If we are not root and we need to become root, prepend sudo
|
||||||
|
sudo = ["sudo", "--"]
|
||||||
|
|
||||||
if opts.prefix is None:
|
if opts.prefix is None:
|
||||||
opts.prefix = self.command_prefix
|
opts.prefix = self.command_prefix
|
||||||
# always set needs_user_terminal to True because ssh asks for passwords
|
# always set needs_user_terminal to True because ssh asks for passwords
|
||||||
@@ -185,7 +185,12 @@ class Host:
|
|||||||
ssh_cmd = [
|
ssh_cmd = [
|
||||||
*self.ssh_cmd(verbose_ssh=verbose_ssh, tty=tty),
|
*self.ssh_cmd(verbose_ssh=verbose_ssh, tty=tty),
|
||||||
"--",
|
"--",
|
||||||
f"{sudo}bash -c {quote(bash_cmd)} -- {' '.join(map(quote, cmd))}",
|
*sudo,
|
||||||
|
"bash",
|
||||||
|
"-c",
|
||||||
|
quote(bash_cmd),
|
||||||
|
"--",
|
||||||
|
" ".join(map(quote, cmd)),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Run the ssh command
|
# Run the ssh command
|
||||||
|
|||||||
Reference in New Issue
Block a user