diff --git a/docs/cli.md b/docs/cli.md index c745883f..89ef2477 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -36,8 +36,8 @@ Options: * --stop-after-disko exit after disko formatting, you can then proceed to install manually or some other way * --extra-files - path to a directory to copy into the root of the new nixos installation. - Copied files will be owned by root. + contents of local are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten + Copied files will be owned by root. See documentation for details. * --disk-encryption-keys copy the contents of the file or pipe in local_path to remote_path in the installer environment, after kexec but before installation. Can be repeated. diff --git a/docs/howtos/INDEX.md b/docs/howtos/INDEX.md index 549ca386..8b102d37 100644 --- a/docs/howtos/INDEX.md +++ b/docs/howtos/INDEX.md @@ -10,6 +10,8 @@ [Installing on a machine with no operating system](./no-os.md) +[Copying files to the new installation](./extra-files.md) + [Using your own kexec image](./custom-kexec.md) [Repair installations without wiping data](./disko-modes.md) diff --git a/docs/howtos/extra-files.md b/docs/howtos/extra-files.md new file mode 100644 index 00000000..9b3819da --- /dev/null +++ b/docs/howtos/extra-files.md @@ -0,0 +1,106 @@ +# Copying files to the new installation + +The `--extra-files ` option allows copying files to the target host after +installation. + +The contents of the `` is recursively copied and overwrites the targets +root (/). The contents _must_ be in a structure and permissioned as it should be +on the target. + +In this way, there is no need to repeatedly pass arguments (eg: a fictional +argument: `--copy `) to `nixos-anywhere` to complete the intended +outcome. + +The path and directory structure passed to `--extra-files` should be prepared +beforehand. + +This allows a simple programmatic invocation of `nixos-anywhere` for multiple +hosts. + +## Simple Example + +You want `/etc/ssh/ssh_host_*` and `/persist` from the local system on the +target. The `` contents will look like this: + +```console +$ cd /tmp +$ root=$(mktemp -d) +$ sudo cp --verbose --archive --parents /etc/ssh/ssh_host_* ${root} +$ cp --verbose --archive --link /persist ${root} +``` + +The directory structure would look like this: + +```console +drwx------ myuser1 users 20 tmp.d6nx5QUwPN +drwxr-xr-x root root 6 ├── etc +drwx------ myuser1 users 160 │ └── ssh +.rw------- root root 399 │ ├── ssh_host_ed25519_key +.rw-r--r-- root root 91 │ ├── ssh_host_ed25519_key.pub +drwxr-xr-x myuser1 users 22 └── persist +drwxr-xr-x myuser1 users 14 ├── all +drwxr-xr-x myuser1 users 22 │ ├── my +.rw-r--r-- myuser1 users 6 │ │ ├── test3 +drwxr-xr-x myuser1 users 10 │ │ └── things +.rw-r--r-- myuser1 users 6 │ │ └── test4 +.rw-r--r-- myuser1 users 6 │ └── test2 +drwxr-xr-x myuser1 users 0 ├── blah +.rw-r--r-- myuser1 users 6 └── test +``` + +**NOTE**: Permissions will be copied, but ownership on the target will be root. + +Then pass $root like: + +> nixos-anywhere --flake ".#" --extra-files $root --target-host root@newhost + +## Programmatic Example + +```sh +for host in host1 host2 host3; do + root="target/${host}" + install -d -m755 ${root}/etc/ssh + ssh-keygen -A -C root@${host} -f ${root} + nixos-anywhere --extra-files "${root}" --flake ".#${host}" --target-host "root@${host}" +done +``` + +## Considerations + +### Ownership + +The new system may have differing UNIX user and group id's for users created +during installation. + +When the files are extracted on the remote the copied data will be owned by +root. + +### Symbolic Links + +Do not create symbolic links to reference data to copy. + +GNU `tar` is used to do the copy over ssh. It is an archival tool used to +re/store directory structures as is. Thus `tar` copies symbolic links created +with `ln -s` by default. It does not follow them to copy the underlying file. + +### Hard links + +**NOTE**: hard links can only be created on the same filesystem. + +If you have larger peristent data to copy to the target. GNU `tar` will copy +data referenced by hard links created with `ln`. A hard link does not create +another copy the data. + +To copy a directory tree to the new target you can use the `cp` command with the +`--link` option which creates hard links. + +#### Example + +```sh +cd /tmp +root=$(mktemp -d) +cp --verbose --archive --link --parents /persist/home/myuser ${root} +``` + +`--parents` will create the directory structure of the source at the +destination. diff --git a/docs/reference.md b/docs/reference.md index c1f56d6d..b6c0c620 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -48,8 +48,8 @@ Options: * --copy-host-keys copy over existing /etc/ssh/ssh_host_* host keys to the installation * --extra-files - path to a directory to copy into the root of the new nixos installation. - Copied files will be owned by root. + contents of local are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten + Copied files will be owned by root. See documentation for details. * --disk-encryption-keys copy the contents of the file or pipe in local_path to remote_path in the installer environment, after kexec but before installation. Can be repeated. diff --git a/src/get-facts.sh b/src/get-facts.sh index 0820bed6..80434422 100755 --- a/src/get-facts.sh +++ b/src/get-facts.sh @@ -13,6 +13,7 @@ isInstaller=$(if [ "$isNixos" = "y" ] && grep -Eq 'VARIANT_ID="?installer"?' /et isContainer=$(if [ "$(has systemd-detect-virt)" = "y" ]; then systemd-detect-virt --container; else echo "none"; fi) hasIpv6Only=$(if [ "$(has ip)" = "n" ] || ip r g 1 >/dev/null 2>/dev/null || ! ip -6 r g :: >/dev/null 2>/dev/null; then echo "n"; else echo "y"; fi) hasTar=$(has tar) +hasCpio=$(has cpio) hasSudo=$(has sudo) hasDoas=$(has doas) hasWget=$(has wget) diff --git a/src/nixos-anywhere.sh b/src/nixos-anywhere.sh index 6430f51d..fed359fa 100755 --- a/src/nixos-anywhere.sh +++ b/src/nixos-anywhere.sh @@ -45,6 +45,7 @@ isInstaller= isContainer= hasIpv6Only= hasTar= +hasCpio= hasSudo= hasDoas= hasWget= @@ -96,8 +97,8 @@ Options: * --copy-host-keys copy over existing /etc/ssh/ssh_host_* host keys to the installation * --extra-files - path to a directory to copy into the root of the new nixos installation. - Copied files will be owned by root. + contents of local are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten + Copied files will be owned by root. See documentation for details. * --disk-encryption-keys copy the contents of the file or pipe in local_path to remote_path in the installer environment, after kexec but before installation. Can be repeated. @@ -437,7 +438,7 @@ importFacts() { # shellcheck disable=SC2046 export $(echo "$filteredFacts" | xargs) - for var in isOs isArch isKexec isInstaller isContainer hasIpv6Only hasTar hasSudo hasDoas hasWget hasCurl hasSetsid; do + for var in isOs isArch isKexec isInstaller isContainer hasIpv6Only hasTar hasCpio hasSudo hasDoas hasWget hasCurl hasSetsid; do if [[ -z ${!var} ]]; then abort "Failed to retrieve fact $var from host" fi @@ -675,6 +676,10 @@ main() { abort "no tar command found, but required to unpack kexec tarball" fi + if [[ ${hasCpio-n} == "n" ]]; then + abort "no cpio command found, but required to build the new initrd" + fi + if [[ ${hasSetsid-n} == "n" ]]; then abort "no setsid command found, but required to run the kexec script under a new session" fi