Skip to content

Commit 3231e4f

Browse files
karaolidisnzbr
andauthored
feat: add --extra-files and --chown parameters (#752)
* feat: add --extra-files and --chown parameters Signed-off-by: Nikolaos Karaolidis <[email protected]> * add test * fix nix run invocation --------- Signed-off-by: Nikolaos Karaolidis <[email protected]> Co-authored-by: nzbr <[email protected]>
1 parent 2afe5f8 commit 3231e4f

File tree

4 files changed

+164
-6
lines changed

4 files changed

+164
-6
lines changed

docs/src/building.md

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
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.
44

5-
If you have a flakes-enabled Nix, you can use the following command to
6-
build your own tarball instead of relying on a prebuilt one:
5+
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:
76

87
```sh
98
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:
1918

2019
```sh
2120
nix-build -A nixosConfigurations.default.config.system.build.tarballBuilder && sudo ./result/bin/nixos-wsl-tarball-builder
22-
2321
```
2422

2523
The resulting tarball can then be found under `nixos.wsl`.
24+
25+
## Copying files to the new installation
26+
27+
The tarball builder supports copying in extra files and fixing up ownership before the tarball is packed.
28+
29+
### `--extra-files <path>`
30+
31+
The `--extra-files <path>` option allows copying files into the target root after installation.
32+
33+
The contents of `<path>` are recursively copied and overwrite the target\'s root (`/`). The structure and permissions of `<path>` should already match how you want them on the target.
34+
35+
For example, if you want to copy your SSH host key, you can prepare a directory structure like this:
36+
37+
```sh
38+
root=$(mktemp -d)
39+
sudo mkdir -p $root/etc/ssh
40+
sudo cp /etc/ssh/ssh_host_ed25519_key $root/etc/ssh
41+
```
42+
43+
Then run:
44+
45+
```sh
46+
sudo nix run github:nix-community/NixOS-WSL#nixosConfigurations.default.config.system.build.tarballBuilder -- --extra-files $root
47+
```
48+
49+
By default, everything ends up owned by root.
50+
51+
### `--chown <path> <uid:gid>`
52+
53+
The `--chown` option allows adjusting ownership of directories or files inside the tarball after they\'re copied.
54+
55+
For example:
56+
57+
```sh
58+
sudo nix run github:nix-community/NixOS-WSL#nixosConfigurations.default.config.system.build.tarballBuilder -- \
59+
--extra-files ./extra \
60+
--chown /home/myuser 1000:100
61+
```
62+
63+
This is equivalent to running inside the tarball root:
64+
65+
```sh
66+
chown -R 1000:100 /home/myuser
67+
```
68+
69+
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.

modules/build-tarball.nix

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,20 +77,77 @@ in
7777
];
7878

7979
text = ''
80+
usage() {
81+
echo "Usage: $0 [--extra-files PATH] [--chown PATH UID:GID] [output.tar.gz]"
82+
exit 1
83+
}
84+
8085
if ! [ $EUID -eq 0 ]; then
8186
echo "This script must be run as root!"
8287
exit 1
8388
fi
8489
8590
# Use .wsl extension to support double-click installs on recent versions of Windows
86-
out=''${1:-nixos.wsl}
91+
out="nixos.wsl"
92+
extra_files=""
93+
94+
declare -A chowns=()
95+
positionals=()
96+
97+
while [ $# -gt 0 ]; do
98+
case "$1" in
99+
--extra-files)
100+
shift
101+
extra_files="$1"
102+
;;
103+
--chown)
104+
shift
105+
path="$1"
106+
shift
107+
perms="$1"
108+
chowns["$path"]="$perms"
109+
;;
110+
-*)
111+
echo "Unknown option: $1"
112+
usage
113+
;;
114+
*)
115+
positionals+=("$1")
116+
;;
117+
esac
118+
shift
119+
done
120+
121+
if [ ''${#positionals[@]} -gt 1 ]; then
122+
echo "Too many positional arguments: ''${positionals[*]}"
123+
usage
124+
fi
125+
126+
if [ ''${#positionals[@]} -gt 0 ]; then
127+
out="''${positionals[0]}"
128+
fi
87129
88130
root=$(mktemp -p "''${TMPDIR:-/tmp}" -d nixos-wsl-tarball.XXXXXXXXXX)
89131
# FIXME: fails in CI for some reason, but we don't really care because it's CI
90132
trap 'chattr -Rf -i "$root" || true && rm -rf "$root" || true' INT TERM EXIT
91133
134+
if [ -n "$extra_files" ]; then
135+
if ! [ -d "$extra_files" ]; then
136+
echo "The path passed to --extra-files must be a directory"
137+
exit 1
138+
fi
139+
140+
echo "[NixOS-WSL] Copying extra files to $root..."
141+
cp --verbose --archive --no-preserve=ownership --no-target-directory "$extra_files" "$root"
142+
fi
143+
92144
chmod o+rx "$root"
93145
146+
for path in "''${!chowns[@]}"; do
147+
echo "[NixOS-WSL] Setting ownership for $path to ''${chowns[$path]}"
148+
chown -R "''${chowns[$path]}" "$root/$path"
149+
done
150+
94151
echo "[NixOS-WSL] Installing..."
95152
nixos-install \
96153
--root "$root" \
@@ -119,8 +176,6 @@ in
119176
-c \
120177
--sort=name \
121178
--mtime='@1' \
122-
--owner=0 \
123-
--group=0 \
124179
--numeric-owner \
125180
--hard-dereference \
126181
. \

tests/extra-files.Tests.ps1

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
BeforeAll {
2+
. $PSScriptRoot/lib/lib.ps1
3+
}
4+
5+
Describe "Extra Files" {
6+
BeforeAll {
7+
$distro = [Distro]::new()
8+
$tmpdir = New-TemporaryFile
9+
Remove-Item $tmpdir
10+
$tmpdir = New-Item -ItemType Directory -Path $tmpdir.FullName
11+
$tarball = "$tmpdir/nixos.wsl"
12+
$Global:distroWithExtras = $null
13+
}
14+
15+
It "should be possible to build a tarball with extra files" {
16+
$distro.Launch("nix-build -A config.system.build.tarballBuilder '<nixpkgs/nixos>'")
17+
18+
$distro.Launch("mkdir -p extra-files/root")
19+
$distro.Launch("mkdir -p extra-files/home/nixos")
20+
$distro.Launch("echo 'extra' > extra-files/root/extra-file")
21+
$distro.Launch("echo 'extra' > extra-files/home/nixos/extra-file")
22+
23+
$distro.Launch("sudo ./result/bin/nixos-wsl-tarball-builder --extra-files extra-files --chown /home/nixos/extra-file 1000:100 $($distro.GetPath($tarball))")
24+
25+
$tarball | Should -Exist
26+
}
27+
28+
It "should be possible to import the tarball" {
29+
$tarball | Should -Exist
30+
Write-Host $tarball
31+
$Global:distroWithExtras = [Distro]::new($tarball)
32+
}
33+
34+
It "should be possible to read the extra files in the new installation" {
35+
$Global:distroWithExtras.Launch("cat /home/nixos/extra-file") | Select-Object -Last 1 | Should -BeExactly "extra"
36+
37+
$Global:distroWithExtras.Launch("cat /root/extra-file")
38+
$LASTEXITCODE | Should -Not -Be 0
39+
$Global:distroWithExtras.Launch("sudo cat /root/extra-file") | Select-Object -Last 1 | Should -BeExactly "extra"
40+
}
41+
42+
AfterAll {
43+
$distro.Uninstall()
44+
if (Test-Path $tmpdir) {
45+
Remove-Item -Recurse $tmpdir
46+
}
47+
if ($Global:distroWithExtras -ne $null) {
48+
$Global:distroWithExtras.Uninstall()
49+
}
50+
}
51+
}

tests/lib/lib.ps1

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,19 @@ class Distro {
2121

2222
Distro() {
2323
$tarball = $this.FindTarball()
24+
$this.Setup($tarball)
25+
}
26+
27+
Distro([string]$tarball) {
28+
$this.Setup($tarball)
29+
}
2430

31+
hidden [void]Setup([string]$tarball) {
2532
$this.id = $(New-Guid).ToString()
2633
$this.tempdir = Join-Path $([System.IO.Path]::GetTempPath()) $this.id
2734
New-Item -ItemType Directory $this.tempdir
2835

36+
Write-Host ">" wsl.exe --import $this.id $this.tempdir $tarball --version 2
2937
& wsl.exe --import $this.id $this.tempdir $tarball --version 2 | Write-Host
3038
if ($LASTEXITCODE -ne 0) {
3139
throw "Failed to import distro"

0 commit comments

Comments
 (0)