From b1f426697f62006b99fac0cc25a106626c78f874 Mon Sep 17 00:00:00 2001 From: Nikolaos Karaolidis Date: Thu, 21 Aug 2025 11:03:05 +0000 Subject: [PATCH] feat: add --extra-files and --chown parameters Signed-off-by: Nikolaos Karaolidis --- docs/src/building.md | 50 ++++++++++++++++++++++++++++++-- modules/build-tarball.nix | 61 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 105 insertions(+), 6 deletions(-) diff --git a/docs/src/building.md b/docs/src/building.md index 603c130e..ea07a42b 100644 --- a/docs/src/building.md +++ b/docs/src/building.md @@ -2,8 +2,7 @@ This requires access to a system that already has Nix installed. Please refer to the [Nix installation guide](https://nixos.org/guides/install-nix.html) if that\'s not the case. -If you have a flakes-enabled Nix, you can use the following command to -build your own tarball instead of relying on a prebuilt one: +If you have a flakes-enabled Nix, you can use the following command to build your own tarball instead of relying on a prebuilt one: ```sh sudo nix run github:nix-community/NixOS-WSL#nixosConfigurations.default.config.system.build.tarballBuilder @@ -19,7 +18,52 @@ Without a flakes-enabled Nix, you can build a tarball using: ```sh nix-build -A nixosConfigurations.default.config.system.build.tarballBuilder && sudo ./result/bin/nixos-wsl-tarball-builder - ``` The resulting tarball can then be found under `nixos.wsl`. + +## Copying files to the new installation + +The tarball builder supports copying in extra files and fixing up ownership before the tarball is packed. + +### `--extra-files ` + +The `--extra-files ` option allows copying files into the target root after installation. + +The contents of `` are recursively copied and overwrite the target\'s root (`/`). The structure and permissions of `` should already match how you want them on the target. + +For example, if you want to copy your SSH host key, you can prepare a directory structure like this: + +```sh +root=$(mktemp -d) +sudo mkdir -p $root/etc/ssh +sudo cp /etc/ssh/ssh_host_ed25519_key $root/etc/ssh +``` + +Then run: + +```sh +sudo nix run github:nix-community/NixOS-WSL#nixosConfigurations.default.config.system.build.tarballBuilder --extra-files $root +``` + +By default, everything ends up owned by root. + +### `--chown ` + +The `--chown` option allows adjusting ownership of directories or files inside the tarball after they\'re copied. + +For example: + +```sh +sudo nix run github:nix-community/NixOS-WSL#nixosConfigurations.default.config.system.build.tarballBuilder \ + --extra-files ./extra \ + --chown /home/myuser 1000:100 +``` + +This is equivalent to running inside the tarball root: + +```sh +chown -R 1000:100 /home/myuser +``` + +The `--chown` option can be used multiple times to set ownership for different paths. Only use this when you can guarantee what the UID/GID will be on the target system. diff --git a/modules/build-tarball.nix b/modules/build-tarball.nix index a31be325..3378c16e 100644 --- a/modules/build-tarball.nix +++ b/modules/build-tarball.nix @@ -77,20 +77,77 @@ in ]; text = '' + usage() { + echo "Usage: $0 [--extra-files PATH] [--chown PATH UID:GID] [output.tar.gz]" + exit 1 + } + if ! [ $EUID -eq 0 ]; then echo "This script must be run as root!" exit 1 fi # Use .wsl extension to support double-click installs on recent versions of Windows - out=''${1:-nixos.wsl} + out="nixos.wsl" + extra_files="" + + declare -A chowns=() + positionals=() + + while [ $# -gt 0 ]; do + case "$1" in + --extra-files) + shift + extra_files="$1" + ;; + --chown) + shift + path="$1" + shift + perms="$1" + chowns["$path"]="$perms" + ;; + -*) + echo "Unknown option: $1" + usage + ;; + *) + positionals+=("$1") + ;; + esac + shift + done + + if [ ''${#positionals[@]} -gt 1 ]; then + echo "Too many positional arguments: ''${positionals[*]}" + usage + fi + + if [ ''${#positionals[@]} -gt 0 ]; then + out="''${positionals[0]}" + fi root=$(mktemp -p "''${TMPDIR:-/tmp}" -d nixos-wsl-tarball.XXXXXXXXXX) # FIXME: fails in CI for some reason, but we don't really care because it's CI trap 'chattr -Rf -i "$root" || true && rm -rf "$root" || true' INT TERM EXIT + if [ -n "$extra_files" ]; then + if ! [ -d "$extra_files" ]; then + echo "The path passed to --extra-files must be a directory" + exit 1 + fi + + echo "[NixOS-WSL] Copying extra files to $root..." + cp --verbose --archive --no-preserve=ownership --no-target-directory "$extra_files" "$root" + fi + chmod o+rx "$root" + for path in "''${!chowns[@]}"; do + echo "[NixOS-WSL] Setting ownership for $path to ''${chowns[$path]}" + chown -R "''${chowns[$path]}" "$root/$path" + done + echo "[NixOS-WSL] Installing..." nixos-install \ --root "$root" \ @@ -119,8 +176,6 @@ in -c \ --sort=name \ --mtime='@1' \ - --owner=0 \ - --group=0 \ --numeric-owner \ --hard-dereference \ . \