Skip to content

Commit

Permalink
feat: add install-anywhere
Browse files Browse the repository at this point in the history
A writeShellApplication that wraps nixos-anywhere. Allow root login via keys to facilitate remote deployment/recovery.
  • Loading branch information
flexiondotorg committed Oct 15, 2024
1 parent 6ab3413 commit f1eb984
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 5 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ The [nixos/_mixins] and [home-manager/_mixins] are a collection of composited co
### Installing to a remote host 🌍

As [Disko] is used to declare the disk layout for all my NixOS hosts, each NixOS configurations can be deployed to a remote host using [nixos-anywhere].

I've created a simple wrapper around `nixos-anywhere` that makes it a bit simpler to deploy a NixOS configuration to a remote host.
For example, `malak` is a Hetzner dedicated server.
To deploy it, enable the Hetzner Rescue system and then execute the following command from any of my systems with Nix installed:
To deploy it, enable the Hetzner Rescue system and then execute the following command from one of my workstations:

```bash
nix run github:nix-community/nixos-anywhere -- --flake '.#malak' root@<ip-address>
install-anywhere malak <ip-address>
```

When the deployment is complete, the remote host will be automatically rebooted.
Expand Down
19 changes: 19 additions & 0 deletions nixos/_mixins/scripts/install-anywhere/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
inputs,
pkgs,
platform,
...
}:
let
install-anywhere = pkgs.writeShellApplication {
name = "install-anywhere";
runtimeInputs = with pkgs; [
coreutils-full
git
];
text = builtins.readFile ./install-anywhere.sh;
};
in
{
environment.systemPackages = with pkgs; [ install-anywhere ];
}
83 changes: 83 additions & 0 deletions nixos/_mixins/scripts/install-anywhere/install-anywhere.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/env bash

set +e # Disable errexit
set +u # Disable nounset
set +o pipefail # Disable pipefail

function usage() {
echo "Usage: $(basename "$0") -h HOST -r REMOTE_ADDRESS [-k] [-t]"
echo " -h HOST: NixOS configuration to install"
echo " -r REMOTE_ADDRESS: Remote address to install NixOS on"
echo " -k Keep disks"
echo " -t Test in VM"
exit 1
}

EXTRA=""
HOST=""
KEEP_DISKS=0
REMOTE_ADDRESS=""
VM_TEST=1

while getopts "k:h:r:t" opt; do
case $opt in
h ) HOST=$OPTARG;;
k ) KEEP_DISKS=1;;
r ) REMOTE_ADDRESS=$OPTARG;;
t ) VM_TEST=1;;
\? ) usage;;
esac
done

if [ -z "$HOST" ] || [ -z "$REMOTE_ADDRESS" ]; then
usage
fi

# Create a temporary directory
FILES=$(mktemp -d)

# Function to cleanup temporary directory on exit
function cleanup() {
rm -rf "$FILES"
}
trap cleanup EXIT

echo "Installing NixOS $HOST configuration on root@$REMOTE_ADDRESS..."

if [ "$VM_TEST" -eq 1 ]; then
echo "- INFO: Testing in VM"
EXTRA+=" --vm-test"
else
echo "- WARN! Production install"
fi

if [ "$KEEP_DISKS" -eq 1 ]; then
echo "- INFO: Keeping disks"
EXTRA+=" --disko-mode mount"
else
echo "- WARN! Wiping disks"
fi

# https://github.com/nix-community/nixos-anywhere/blob/main/docs/howtos/secrets.md
if [ -e "$HOME/.config/sops/age/keys.txt" ] && [ "$VM_TEST" -eq 0 ]; then
install -d -m755 "$FILES/$HOME/.config/sops/age"
cp "$HOME/.config/sops/age/keys.txt" "$FILES/$HOME/.config/sops/age/keys.txt"
EXTRA+=" --extra-files $FILES"
echo "- INFO: Sending SOPS keys"
else
echo "- WARN! No SOPS keys found"
fi

REPLY="n"
read -p "Proceed with remote install? [y/N]" -n 1 -r
echo
if [[ $REPLY =~ ^[Nn]$ ]]; then
echo "Installation aborted."
exit 1
fi

pushd "$HOME/Zero/nix-config" || exit 1
# shellcheck disable=2086
nix run github:nix-community/nixos-anywhere -- \
$EXTRA --flake ".#$HOST" "root@$REMOTE_ADDRESS"
popd || true
2 changes: 1 addition & 1 deletion nixos/_mixins/services/ssh/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
openFirewall = !isLaptop;
settings = {
PasswordAuthentication = false;
PermitRootLogin = lib.mkDefault "no";
PermitRootLogin = lib.mkDefault "prohibit-password";
};
};
sshguard = {
Expand Down
2 changes: 1 addition & 1 deletion nixos/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
] ++ lib.optional isWorkstation ./_mixins/desktop;

boot = {
consoleLogLevel = 0;
consoleLogLevel = lib.mkDefault 0;
initrd.verbose = false;
kernelModules = [ "vhost_vsock" ];
kernelParams = [ "udev.log_priority=3" ];
Expand Down

0 comments on commit f1eb984

Please sign in to comment.