fix(nixos): import unsigned deploy closures

This commit is contained in:
2026-09-15 14:34:39 -04:00
parent e58eed3953
commit 1c4d5a0518
3 changed files with 38 additions and 5 deletions

View File

@@ -50,7 +50,10 @@
directories already exist inside the read-only source. directories already exist inside the read-only source.
For aggregate Copyparty volumes such as `/srv` with nested `/srv/inbox`, keep the guest bind mount For aggregate Copyparty volumes such as `/srv` with nested `/srv/inbox`, keep the guest bind mount
writable and enforce read-only behavior through Copyparty access plus service `ReadWritePaths`. writable and enforce read-only behavior through Copyparty access plus service `ReadWritePaths`.
- `deploy-to` builds from the source checkout and activates a copied closure on the target. - `deploy-to` builds from the source checkout and activates an imported closure on the target.
Do not rely on a target-local monorepo checkout for remote deployment. Do not rely on a target-local monorepo checkout for remote deployment.
- On Pikachu, `nix copy --to ssh://pikachu` accepted a small `nix store add-file` probe,
but rejected locally built system paths that lacked trusted signatures.
Use a sudo `nix-store --import` path for unsigned deploy closures.
- Do not hand-author `hardware-configuration.nix` for a host that has not been generated on that machine. - Do not hand-author `hardware-configuration.nix` for a host that has not been generated on that machine.
Generate it on the target system or live ISO, then stage it before evaluating the flake. Generate it on the target system or live ISO, then stage it before evaluating the flake.

View File

@@ -99,7 +99,7 @@ in
}; };
deploy-to = { deploy-to = {
description = "Build the current checkout locally, copy it to a host, and activate it"; description = "Build the current checkout locally, import it on a host, and activate it";
body = builtins.readFile ./functions/deploy-to.fish; body = builtins.readFile ./functions/deploy-to.fish;
}; };

View File

@@ -34,10 +34,40 @@ if test (count $system_path) -ne 1
return 1 return 1
end end
echo "deploy-to: copying $system_path to $host" >&2 set nar_file (mktemp --suffix=.nar)
nix copy --to ssh://$host $system_path or return $status
set remote_nar "/tmp/deploy-to-$host-"(date +%s)"-$fish_pid.nar"
set closure_paths (nix-store -qR $system_path)
or begin or begin
echo "deploy-to: copy failed for $host" >&2 set query_status $status
rm -f $nar_file
echo "deploy-to: closure query failed for $host" >&2
return $query_status
end
echo "deploy-to: exporting closure for $system_path" >&2
nix-store --export $closure_paths >$nar_file
or begin
set export_status $status
rm -f $nar_file
echo "deploy-to: closure export failed for $host" >&2
return $export_status
end
echo "deploy-to: copying closure archive to $host:$remote_nar" >&2
scp $nar_file $host:$remote_nar
set scp_status $status
rm -f $nar_file
if test $scp_status -ne 0
echo "deploy-to: closure archive copy failed for $host" >&2
return $scp_status
end
echo "deploy-to: importing closure on $host" >&2
ssh -t $host "sudo sh -c 'nix-store --import < $remote_nar' && rm -f $remote_nar"
or begin
echo "deploy-to: closure import failed for $host" >&2
return $status return $status
end end