diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..1de5659
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1 @@
+target
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f96e224..d539178 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -12,7 +12,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Install Nix
- uses: DeterminateSystems/nix-installer-action@main
+ uses: DeterminateSystems/nix-installer-action@start-daemon-and-init
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Cache lint store (x86_64-linux)
@@ -36,7 +36,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Install Nix
- uses: DeterminateSystems/nix-installer-action@main
+ uses: DeterminateSystems/nix-installer-action@start-daemon-and-init
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Cache build store (x86_64-linux)
@@ -67,7 +67,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Install Nix
- uses: DeterminateSystems/nix-installer-action@main
+ uses: DeterminateSystems/nix-installer-action@start-daemon-and-init
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Cache build store (x86_64-linux)
@@ -100,7 +100,7 @@ jobs:
cp nix-installer.sh install-root/nix-installer.sh
mv nix-installer install-root/nix-installer-x86_64-linux
- name: Initial install
- uses: DeterminateSystems/nix-installer-action@main
+ uses: DeterminateSystems/nix-installer-action@start-daemon-and-init
with:
local-root: install-root/
logger: pretty
@@ -129,7 +129,7 @@ jobs:
exit 1
fi
- name: Repeated install
- uses: DeterminateSystems/nix-installer-action@main
+ uses: DeterminateSystems/nix-installer-action@start-daemon-and-init
with:
local-root: install-root/
logger: pretty
@@ -184,6 +184,113 @@ jobs:
exit 1
fi
+ run-x86_64-linux-no-init:
+ name: Run x86_64 Linux (No init)
+ runs-on: ubuntu-22.04
+ needs: [build-x86_64-linux, lints]
+ steps:
+ - uses: actions/checkout@v3
+ - run: sudo apt install fish zsh
+ - uses: actions/download-artifact@v3
+ with:
+ name: nix-installer-x86_64-linux
+ - name: Move & set executable
+ run: |
+ chmod +x ./nix-installer
+ mkdir install-root
+ cp nix-installer.sh install-root/nix-installer.sh
+ mv nix-installer install-root/nix-installer-x86_64-linux
+ - name: Initial install
+ uses: DeterminateSystems/nix-installer-action@start-daemon-and-init
+ with:
+ init: none
+ planner: linux-multi
+ local-root: install-root/
+ logger: pretty
+ log-directives: nix_installer=trace
+ backtrace: full
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ - name: Ensure daemon was not configured with init
+ run: |
+ if systemctl is-active nix-daemon.socket; then
+ echo "nix-daemon.socket was running"
+ exit 1
+ fi
+ if systemctl is-active nix-daemon.service; then
+ echo "nix-daemon.service was running"
+ exit 1
+ fi
+ - name: Initial uninstall (without a `nix run` first)
+ run: sudo -E /nix/nix-installer uninstall
+ env:
+ NIX_INSTALLER_NO_CONFIRM: true
+ NIX_INSTALLER_LOGGER: pretty
+ NIX_INSTALLER_LOG_DIRECTIVES: nix_installer=trace
+ RUST_BACKTRACE: full
+ - name: Ensure `nix` is removed
+ run: |
+ if [ -e /nix ]; then
+ echo "/nix exists"
+ exit 1
+ fi
+ - name: Repeated install
+ uses: DeterminateSystems/nix-installer-action@start-daemon-and-init
+ with:
+ init: none
+ planner: linux-multi
+ local-root: install-root/
+ logger: pretty
+ log-directives: nix_installer=trace
+ backtrace: full
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ - name: echo $PATH
+ run: echo $PATH
+ - name: Test `nix` with `$GITHUB_PATH`
+ if: success() || failure()
+ run: |
+ sudo -i nix run nixpkgs#fortune
+ sudo -i nix profile install nixpkgs#fortune
+ fortune
+ sudo -i nix store gc
+ sudo -i nix run nixpkgs#fortune
+ - name: Test bash
+ run: sudo -i nix-instantiate -E 'builtins.currentTime' --eval
+ if: success() || failure()
+ shell: bash --login {0}
+ - name: Test sh
+ run: sudo -i nix-instantiate -E 'builtins.currentTime' --eval
+ if: success() || failure()
+ shell: sh -l {0}
+ - name: Test zsh
+ run: sudo -i nix-instantiate -E 'builtins.currentTime' --eval
+ if: success() || failure()
+ shell: zsh --login --interactive {0}
+ - name: Test fish
+ run: sudo -i nix-instantiate -E 'builtins.currentTime' --eval
+ if: success() || failure()
+ shell: fish --login {0}
+ - name: Repeated uninstall
+ run: sudo -E /nix/nix-installer uninstall
+ env:
+ NIX_INSTALLER_NO_CONFIRM: true
+ NIX_INSTALLER_LOGGER: pretty
+ NIX_INSTALLER_LOG_DIRECTIVES: nix_installer=trace
+ RUST_BACKTRACE: full
+ - name: Ensure `nix` is removed
+ run: |
+ if systemctl is-active nix-daemon.socket; then
+ echo "nix-daemon.socket was running"
+ exit 1
+ fi
+ if systemctl is-active nix-daemon.service; then
+ echo "nix-daemon.service was running"
+ exit 1
+ fi
+ if [ -e /nix ]; then
+ echo "/nix exists"
+ exit 1
+ fi
+
run-steam-deck:
name: Run Steam Deck (mock)
runs-on: ubuntu-22.04
@@ -207,7 +314,7 @@ jobs:
sudo chmod +x /bin/steamos-readonly
sudo useradd -m deck
- name: Initial install
- uses: DeterminateSystems/nix-installer-action@main
+ uses: DeterminateSystems/nix-installer-action@start-daemon-and-init
with:
local-root: install-root/
logger: pretty
@@ -242,7 +349,7 @@ jobs:
exit 1
fi
- name: Repeated install
- uses: DeterminateSystems/nix-installer-action@main
+ uses: DeterminateSystems/nix-installer-action@start-daemon-and-init
with:
local-root: install-root/
logger: pretty
@@ -309,7 +416,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Install Nix
- uses: DeterminateSystems/nix-installer-action@main
+ uses: DeterminateSystems/nix-installer-action@start-daemon-and-init
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
# Runs clippy as part of the preBuild.
@@ -339,7 +446,7 @@ jobs:
cp nix-installer.sh install-root/nix-installer.sh
mv nix-installer install-root/nix-installer-x86_64-darwin
- name: Initial install
- uses: DeterminateSystems/nix-installer-action@main
+ uses: DeterminateSystems/nix-installer-action@start-daemon-and-init
with:
local-root: install-root/
logger: pretty
@@ -356,7 +463,7 @@ jobs:
NIX_INSTALLER_LOG_DIRECTIVES: nix_installer=trace
RUST_BACKTRACE: full
- name: Repeated install
- uses: DeterminateSystems/nix-installer-action@main
+ uses: DeterminateSystems/nix-installer-action@start-daemon-and-init
with:
local-root: install-root/
logger: pretty
@@ -397,4 +504,3 @@ jobs:
NIX_INSTALLER_LOGGER: pretty
NIX_INSTALLER_LOG_DIRECTIVES: nix_installer=trace
RUST_BACKTRACE: full
-
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1807179..c23d7a4 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -156,7 +156,7 @@ It's perfectly fine if they are manual or labor intensive, as these should be a
## `qemu` VM tests
-In `nix/tests/vm-test` there exists some Nix derivations which we expose in the flake via `hydraJobs`.
+For x86_64 Linux we have some additional QEMU based tests. In `nix/tests/vm-test` there exists some Nix derivations which we expose in the flake via `hydraJobs`.
These should be visible in `nix flake show`:
@@ -190,13 +190,13 @@ git+file:///home/ana/git/determinatesystems/nix-installer
To run all of the currently supported tests:
```bash
-nix build .#hydraJobs.vm-test.all.x86_64-linux.install-default -L
+nix build .#hydraJobs.vm-test.all.x86_64-linux.all -L
```
To run a specific distribution listed in the `nix flake show` output:
```bash
-nix build .#hydraJobs.vm-test.rhel-v7.x86_64-linux.install-default -L
+nix build .#hydraJobs.vm-test.rhel-v7.x86_64-linux.all -L
```
For PR review, you can also test arbitrary branches or checkouts like so:
@@ -238,6 +238,120 @@ installer-test-rhel-v7-install-default> Formatting './disk.qcow2', fmt=qcow2 clu
+## Container tests
+
+
+For x86_64 Linux we have some additional container tests. In `nix/tests/container-test` there exists some Nix derivations which we expose in the flake via `hydraJobs`.
+
+These should be visible in `nix flake show`:
+
+```
+❯ nix flake show
+warning: Git tree '/home/ana/git/determinatesystems/nix-installer' is dirty
+git+file:///home/ana/git/determinatesystems/nix-installer
+# ...
+├───hydraJobs
+│ ├───container-test
+│ │ ├───all
+│ │ │ └───x86_64-linux
+│ │ │ ├───all: derivation 'all'
+│ │ │ ├───docker: derivation 'all'
+│ │ │ └───podman: derivation 'all'
+│ │ ├───ubuntu-v18_04
+│ │ │ └───x86_64-linux
+│ │ │ ├───all: derivation 'all'
+│ │ │ ├───docker: derivation 'vm-test-run-container-test-ubuntu-v18_04'
+│ │ │ └───podman: derivation 'vm-test-run-container-test-ubuntu-v18_04'
+│ │ ├───ubuntu-v20_04
+│ │ │ └───x86_64-linux
+│ │ │ ├───all: derivation 'all'
+│ │ │ ├───docker: derivation 'vm-test-run-container-test-ubuntu-v20_04'
+│ │ │ └───podman: derivation 'vm-test-run-container-test-ubuntu-v20_04'
+│ │ └───ubuntu-v22_04
+│ │ └───x86_64-linux
+│ │ ├───all: derivation 'all'
+│ │ ├───docker: derivation 'vm-test-run-container-test-ubuntu-v22_04'
+│ │ └───podman: derivation 'vm-test-run-container-test-ubuntu-v22_04'
+```
+
+To run all of the currently supported tests:
+
+```bash
+nix build .#hydraJobs.container-test.all.x86_64-linux.all -L
+```
+
+To run a specific distribution listed in the `nix flake show` output:
+
+```bash
+nix build .#hydraJobs.container-test.ubuntu-v22_04.x86_64-linux.docker -L
+```
+
+For PR review, you can also test arbitrary branches or checkouts like so:
+
+```bash
+nix build github:determinatesystems/nix-installer/${BRANCH}#hydraJobs.container-test.ubuntu-v22_04.x86_64-linux.podman -L
+```
+
+
+ Adding a distro?
+
+Notice how `ubuntu-v20_02` has a `v20`, not just `20`? That's so the test output shows correctly, as Nix will interpret the first `-\d` (eg `-20`, `-123213`) as a version, and not show it in the output.
+
+Using `v20` instead turns:
+
+```
+# ...
+vm-test-run-container-test-ubuntu> machine # [ 23.385182] dhcpcd[670]: vethae56f366: deleting address fe80::c036:c8ff:fe04:5832
+vm-test-run-container-test-ubuntu> machine # this derivation will be built:
+vm-test-run-container-test-ubuntu> machine # /nix/store/9qb0l9n1gsmcyynfmndnq3qpmlvq8rln-foo.drv
+vm-test-run-container-test-ubuntu> machine # [ 23.424605] dhcpcd[670]: vethae56f366: removing interface
+vm-test-run-container-test-ubuntu> machine # building '/nix/store/9qb0l9n1gsmcyynfmndnq3qpmlvq8rln-foo.drv'...
+vm-test-run-container-test-ubuntu> machine # [ 23.371066] systemd[1]: crun-buildah-buildah1810857047.scope: Deactivated successfully.
+# ...
+```
+
+Into this:
+
+```
+# ...
+vm-test-run-container-test-ubuntu-v18_04> machine # [ 23.385182] dhcpcd[670]: vethae56f366: deleting address fe80::c036:c8ff:fe04:5832
+vm-test-run-container-test-ubuntu-v20_04> machine # this derivation will be built:
+vm-test-run-container-test-ubuntu-v20_04> machine # /nix/store/9qb0l9n1gsmcyynfmndnq3qpmlvq8rln-foo.drv
+vm-test-run-container-test-ubuntu-v18_04> machine # [ 23.424605] dhcpcd[670]: vethae56f366: removing interface
+vm-test-run-container-test-ubuntu-v20_04> machine # building '/nix/store/9qb0l9n1gsmcyynfmndnq3qpmlvq8rln-foo.drv'...
+vm-test-run-container-test-ubuntu-v20_04> machine # [ 23.371066] systemd[1]: crun-buildah-buildah1810857047.scope: Deactivated successfully.
+# ...
+```
+
+
+
+## WSL tests
+
+On a Windows Machine with WSL2 enabled (and updated to [support systemd](https://ubuntu.com/blog/ubuntu-wsl-enable-systemd)) you can test using WSL the scripts in `tests/windows`:
+
+```powershell
+.\tests\windows\test-wsl.ps1
+.\tests\windows\test-wsl.ps1 -Systemd
+```
+
+If something breaks you may need to unregister the test WSL instance. First, look for the distro prefixed with `nix-installer-test`:
+
+```powershell
+$ wsl --list
+Windows Subsystem for Linux Distributions:
+Ubuntu (Default)
+nix-installer-test-ubuntu-jammy
+```
+
+Then delete it:
+
+```powershell
+wsl --unregister nix-installer-test-ubuntu-jammy
+```
+
+You can also remove your `$HOME/nix-installer-wsl-tests-temp` folder whenever you wish.
+
+
## Testing the `action.yml`
The `action.yml` is used directly in the CI process, so it is automatically tested for most changes.
diff --git a/README.md b/README.md
index 04754b5..2c4cc0d 100644
--- a/README.md
+++ b/README.md
@@ -16,12 +16,11 @@ curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix
Current and planned support:
-* [x] Multi-user Linux (aarch64 and x86_64) with systemd init, no SELinux
-* [x] Multi-user MacOS (aarch64 and x86_64)
- + Note: User deletion is currently unimplemented, you need to use a user with a secure token and `dscl . -delete /Users/_nixbuild*` where `*` is each user number.
-* [x] Valve Steam Deck
-* [ ] Multi-user Linux (aarch64 and x86_64) with systemd init & SELinux
-* [ ] Single-user Linux (aarch64 and x86_64)
+* [x] Multi-user Linux (aarch64 and x86_64) with systemd integration, no SELinux
+* [x] Root-only Linux (aarch64 and x86_64) with no init integration, no SELinux
+* [x] Multi-user MacOS (aarch64 and x86_64) with launchd integration
+* [x] SteamOS on the Valve Steam Deck
+* [ ] Multi-user Linux (aarch64 and x86_64) with systemd integration & SELinux
* [ ] Others...
## Installation Differences
@@ -95,16 +94,16 @@ Usage: nix-installer install linux-multi [OPTIONS]
Options:
# ...
- --nix-build-user-count
- Number of build users to create
+ --nix-build-group-name
+ The Nix build group name
- [env: NIX_INSTALLER_NIX_BUILD_USER_COUNT=]
- [default: 32]
+ [env: NIX_INSTALLER_NIX_BUILD_GROUP_NAME=]
+ [default: nixbld]
- --nix-build-user-id-base
- The Nix build user base UID (ascending)
+ --nix-build-group-id
+ The Nix build group GID
- [env: NIX_INSTALLER_NIX_BUILD_USER_ID_BASE=]
+ [env: NIX_INSTALLER_NIX_BUILD_GROUP_ID=]
[default: 3000]
# ...
```
@@ -112,9 +111,9 @@ Options:
Planners can be configured via environment variable or command arguments:
```bash
-$ curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | NIX_BUILD_USER_COUNT=4 sh -s -- install linux-multi --nix-build-user-id-base 4000
+$ curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | NIX_BUILD_GROUP_NAME=nixbuilder sh -s -- install linux-multi --nix-build-group-id 4000
# Or...
-$ NIX_BUILD_USER_COUNT=4 ./nix-installer install linux-multi --nix-build-user-id-base 4000
+$ NIX_BUILD_GROUP_NAME=nixbuilder ./nix-installer install linux-multi --nix-build-group-id 4000
```
@@ -145,28 +144,102 @@ jobs:
- uses: actions/checkout@v3
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- with:
- # Allow the installed Nix to make authenticated Github requests.
- # If you skip this, you will likely get rate limited.
- github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Run `nix build`
run: nix build .
```
+## In a container
-## Building
+In Docker/Podman containers or WSL instances where an init (like `systemd`) is not present, pass `--init none`.
+
+> When `--init none` is used, only `root` or sudoers can run Nix:
+>
+> ```bash
+> sudo -i nix run nixpkgs#hello
+> ```
+
+For Docker containers (without an init):
+
+```dockerfile
+# Dockerfile
+FROM ubuntu:latest
+RUN apt update -y
+RUN apt install curl -y
+COPY nix-installer /nix-installer
+RUN /nix-installer install linux-multi --init none --no-confirm
+ENV PATH="${PATH}:/nix/var/nix/profiles/default/bin"
+RUN nix run nixpkgs#hello
+```
+
+Podman containers require `sandbox = false` in your `Nix.conf`.
+
+For podman containers without an init:
+
+```dockerfile
+# Dockerfile
+FROM ubuntu:latest
+RUN apt update -y
+RUN apt install curl -y
+COPY nix-installer /nix-installer
+RUN /nix-installer install linux-multi --extra-conf "sandbox = false" --init none --no-confirm
+ENV PATH="${PATH}:/nix/var/nix/profiles/default/bin"
+RUN nix run nixpkgs#hello
+```
+
+For Podman containers with an init:
+
+```dockerfile
+# Dockerfile
+FROM ubuntu:latest
+RUN apt update -y
+RUN apt install curl systemd -y
+COPY nix-installer /nix-installer
+RUN /nix-installer install linux-multi --extra-conf "sandbox = false" --no-start-daemon --no-confirm
+ENV PATH="${PATH}:/nix/var/nix/profiles/default/bin"
+RUN nix run nixpkgs#hello
+CMD [ "/usr/sbin/init" ]
+```
+
+## In WSL
+
+If [systemd is enabled](https://ubuntu.com/blog/ubuntu-wsl-enable-systemd) it's possible to install Nix as normal using the command at the top of this document:
+
+```bash
+curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
+```
+
+If systemd is not enabled, pass `--init none` at the end of the command:
+
+> When `--init none` is used, only `root` or sudoers can run Nix:
+>
+> ```bash
+> sudo -i nix run nixpkgs#hello
+> ```
+
+
+```bash
+curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install --init none
+```
+
+## Building a binary
Since you'll be using `nix-installer` to install Nix on systems without Nix, the default build is a static binary.
-Build a portable binary on a system with Nix:
+Build a portable Linux binary on a system with Nix:
```bash
nix build -L github:determinatesystems/nix-installer#nix-installer-static
```
+On Mac:
+
+```bash
+nix build -L github:determinatesystems/nix-installer#nix-installer
+```
+
Then copy the `result/bin/nix-installer` to the machine you wish to run it on.
-You can also add `nix-installer` to your system without having Nix:
+You can also add `nix-installer` to a system without Nix via `cargo`:
```bash
RUSTFLAGS="--cfg tokio_unstable" cargo install nix-installer
@@ -188,7 +261,7 @@ cargo add nix-installer
> **Building a CLI?** Check out the `cli` feature flag for `clap` integration.
-You'll also need to edit your `.cargo/config.toml` to use `tokio_unstable`:
+You'll also need to edit your `.cargo/config.toml` to use `tokio_unstable` as we utilize [Tokio's process groups](https://docs.rs/tokio/1.24.1/tokio/process/struct.Command.html#method.process_group), which wrap stable `std` APIs, but are unstable due to it requiring an MSRV bump:
```toml
# .cargo/config.toml
@@ -208,3 +281,5 @@ Documentation is also available via `nix` build:
nix build github:DeterminateSystems/nix-installer#nix-installer.doc
firefox result-doc/nix-installer/index.html
```
+
+
diff --git a/flake.nix b/flake.nix
index 4942b8e..14145fd 100644
--- a/flake.nix
+++ b/flake.nix
@@ -182,6 +182,10 @@
inherit forSystem;
inherit (nix.hydraJobs) binaryTarball;
};
+ container-test = import ./nix/tests/container-test {
+ inherit forSystem;
+ inherit (nix.hydraJobs) binaryTarball;
+ };
};
};
}
diff --git a/nix/check.nix b/nix/check.nix
index e2a7255..5a45b57 100644
--- a/nix/check.nix
+++ b/nix/check.nix
@@ -18,8 +18,8 @@ in
runtimeInputs = with pkgs; [ git codespell ];
text = ''
codespell \
- --ignore-words-list ba,sur,crate,pullrequest,pullrequests,ser \
- --skip target \
+ --ignore-words-list ba,sur,crate,pullrequest,pullrequests,ser,distroname \
+ --skip target,.git \
.
'';
});
diff --git a/nix/tests/container-test/default.nix b/nix/tests/container-test/default.nix
new file mode 100644
index 0000000..ba66ab5
--- /dev/null
+++ b/nix/tests/container-test/default.nix
@@ -0,0 +1,100 @@
+# Largely derived from https://github.com/NixOS/nix/blob/14f7dae3e4eb0c34192d0077383a7f2a2d630129/tests/installer/default.nix
+{ forSystem, binaryTarball }:
+
+let
+ images = {
+
+ # Found via https://hub.docker.com/_/ubuntu/ under "How is the rootfs build?"
+ # Jammy
+ "ubuntu-v22_04" = {
+ tarball = import {
+ url = "https://launchpad.net/~cloud-images-release-managers/+livefs/ubuntu/jammy/ubuntu-oci/+build/408115/+files/livecd.ubuntu-oci.rootfs.tar.gz";
+ hash = "sha256-BirwSM4c+ZV1upU0yV3qa+BW9AvpBUxvZuPTeI9mA8M=";
+ };
+ tester = ./default/Dockerfile;
+ system = "x86_64-linux";
+ };
+
+ # focal
+ "ubuntu-v20_04" = {
+ tarball = import {
+ url = "https://launchpad.net/~cloud-images-release-managers/+livefs/ubuntu/focal/ubuntu-oci/+build/408120/+files/livecd.ubuntu-oci.rootfs.tar.gz";
+ hash = "sha256-iTJR+DeC5lT4PMqT/xFAFwmlC/qvslDFccDrVFLt/a8=";
+ };
+ tester = ./default/Dockerfile;
+ system = "x86_64-linux";
+ };
+
+ # bionic
+ "ubuntu-v18_04" = {
+ tarball = import {
+ url = "https://launchpad.net/~cloud-images-release-managers/+livefs/ubuntu/bionic/ubuntu-oci/+build/408103/+files/livecd.ubuntu-oci.rootfs.tar.gz";
+ hash = "sha256-gi48yl5laoKLoVCDIORsseOM6DI58FNpAjSVe7OOs7I=";
+ };
+ tester = ./default/Dockerfile;
+ system = "x86_64-linux";
+ };
+
+ };
+
+ makeTest = containerTool: imageName:
+ let image = images.${imageName}; in
+ with (forSystem image.system ({ system, pkgs, lib, ... }: pkgs));
+ testers.nixosTest
+ {
+ name = "container-test-${imageName}";
+ nodes = {
+ machine =
+ { config, pkgs, ... }: {
+ virtualisation.${containerTool}.enable = true;
+ };
+ };
+ testScript = ''
+ machine.start()
+ machine.copy_from_host("${image.tarball}", "/image")
+ machine.succeed("mkdir -p /test")
+ machine.copy_from_host("${image.tester}", "/test/Dockerfile")
+ machine.copy_from_host("${nix-installer-static}", "/test/nix-installer")
+ machine.copy_from_host("${binaryTarball.${system}}", "/test/binary-tarball")
+ machine.succeed("${containerTool} import /image default")
+ machine.succeed("${containerTool} build -t test /test")
+ '';
+ };
+
+ container-tests = builtins.mapAttrs
+ (imageName: image: (with (forSystem "x86_64-linux" ({ system, pkgs, ... }: pkgs)); {
+ ${image.system} = rec {
+ docker = makeTest "docker" imageName;
+ podman = makeTest "podman" imageName;
+ all = pkgs.releaseTools.aggregate {
+ name = "all";
+ constituents = [
+ docker
+ podman
+ ];
+ };
+ };
+ }))
+ images;
+
+in
+container-tests // {
+ all."x86_64-linux" = rec {
+ all = (with (forSystem "x86_64-linux" ({ system, pkgs, ... }: pkgs)); pkgs.releaseTools.aggregate {
+ name = "all";
+ constituents = [
+ docker
+ podman
+ ];
+ });
+ docker = (with (forSystem "x86_64-linux" ({ system, pkgs, ... }: pkgs)); pkgs.releaseTools.aggregate {
+ name = "all";
+ constituents = pkgs.lib.mapAttrsToList (name: value: value."x86_64-linux".docker) container-tests;
+ });
+ podman = (with (forSystem "x86_64-linux" ({ system, pkgs, ... }: pkgs)); pkgs.releaseTools.aggregate {
+ name = "all";
+ constituents = pkgs.lib.mapAttrsToList (name: value: value."x86_64-linux".podman) container-tests;
+ });
+ };
+}
+
diff --git a/nix/tests/container-test/default/Dockerfile b/nix/tests/container-test/default/Dockerfile
new file mode 100644
index 0000000..eac0f65
--- /dev/null
+++ b/nix/tests/container-test/default/Dockerfile
@@ -0,0 +1,8 @@
+FROM default
+COPY nix-installer /nix-installer
+RUN chmod +x /nix-installer
+COPY binary-tarball /binary-tarball
+RUN mv /binary-tarball/nix-*.tar.xz nix.tar.xz
+RUN /nix-installer/bin/nix-installer install linux-multi --nix-package-url file:///nix.tar.xz --init none --extra-conf "sandbox = false" --channel --no-confirm -vvv
+ENV PATH="${PATH}:/nix/var/nix/profiles/default/bin"
+RUN nix-build --no-substitute -E 'derivation { name = "foo"; system = "x86_64-linux"; builder = "/bin/sh"; args = ["-c" "echo foobar > $out"]; }'
\ No newline at end of file
diff --git a/nix/tests/vm-test/default.nix b/nix/tests/vm-test/default.nix
index fb18048..9ead800 100644
--- a/nix/tests/vm-test/default.nix
+++ b/nix/tests/vm-test/default.nix
@@ -5,10 +5,61 @@ let
installScripts = {
install-default = {
- script = ''
+ install = ''
NIX_PATH=$(readlink -f nix.tar.xz)
RUST_BACKTRACE="full" ./nix-installer install --logger pretty --log-directive nix_installer=trace --channel --nix-package-url "file://$NIX_PATH" --no-confirm
'';
+ check = ''
+ set -ex
+
+ nix-env --version
+ nix --extra-experimental-features nix-command store ping
+
+ out=$(nix-build --no-substitute -E 'derivation { name = "foo"; system = "x86_64-linux"; builder = "/bin/sh"; args = ["-c" "echo foobar > $out"]; }')
+ [[ $(cat $out) = foobar ]]
+ '';
+ };
+ install-no-start-daemon = {
+ install = ''
+ NIX_PATH=$(readlink -f nix.tar.xz)
+ RUST_BACKTRACE="full" ./nix-installer install linux-multi --no-start-daemon --logger pretty --log-directive nix_installer=trace --channel --nix-package-url "file://$NIX_PATH" --no-confirm
+ '';
+ check = ''
+ set -ex
+
+ if systemctl is-active nix-daemon.socket; then
+ echo "nix-daemon.socket was running, should not be"
+ exit 1
+ fi
+ if systemctl is-active nix-daemon.service; then
+ echo "nix-daemon.service was running, should not be"
+ exit 1
+ fi
+
+ sudo systemctl start nix-daemon.socket
+
+ nix-env --version
+ nix --extra-experimental-features nix-command store ping
+
+ out=$(nix-build --no-substitute -E 'derivation { name = "foo"; system = "x86_64-linux"; builder = "/bin/sh"; args = ["-c" "echo foobar > $out"]; }')
+ [[ $(cat $out) = foobar ]]
+ '';
+ };
+ install-daemonless = {
+ install = ''
+ NIX_PATH=$(readlink -f nix.tar.xz)
+ RUST_BACKTRACE="full" ./nix-installer install linux-multi --init none --logger pretty --log-directive nix_installer=trace --channel --nix-package-url "file://$NIX_PATH" --no-confirm
+ '';
+ check = ''
+ set -ex
+
+ sudo -i nix-env --version
+ sudo -i nix --extra-experimental-features nix-command store ping
+
+ echo 'derivation { name = "foo"; system = "x86_64-linux"; builder = "/bin/sh"; args = ["-c" "echo foobar > $out"]; }' | sudo tee -a /drv
+ out=$(sudo -i nix-build --no-substitute /drv)
+ [[ $(cat $out) = foobar ]]
+ '';
};
};
@@ -114,7 +165,8 @@ let
buildInputs = [ qemu_kvm openssh ];
image = image.image;
postBoot = image.postBoot or "";
- installScript = installScripts.${testName}.script;
+ installScript = installScripts.${testName}.install;
+ checkScript = installScripts.${testName}.check;
installer = nix-installer-static;
binaryTarball = binaryTarball.${system};
}
@@ -182,15 +234,7 @@ let
$ssh "set -eux; $installScript"
echo "Testing Nix installation..."
- $ssh < \$out"]; }')
- [[ \$(cat \$out) = foobar ]]
- EOF
+ $ssh "set -eux; $checkScript"
echo "Done!"
touch $out
@@ -198,20 +242,47 @@ let
vm-tests = builtins.mapAttrs
(imageName: image:
- {
- ${image.system} = builtins.mapAttrs
+ rec {
+ ${image.system} = (builtins.mapAttrs
(testName: test:
makeTest imageName testName
)
- installScripts;
+ installScripts) // {
+ all = (with (forSystem "x86_64-linux" ({ system, pkgs, ... }: pkgs)); pkgs.releaseTools.aggregate {
+ name = "all";
+ constituents = (
+ pkgs.lib.mapAttrsToList
+ (testName: test:
+ makeTest imageName testName
+ )
+ installScripts
+ );
+ });
+ };
}
)
images;
in
-vm-tests // {
+vm-tests // rec {
all."x86_64-linux".install-default = (with (forSystem "x86_64-linux" ({ system, pkgs, ... }: pkgs)); pkgs.releaseTools.aggregate {
name = "all";
constituents = pkgs.lib.mapAttrsToList (name: value: value."x86_64-linux".install-default) vm-tests;
});
+ all."x86_64-linux".install-no-start-daemon = (with (forSystem "x86_64-linux" ({ system, pkgs, ... }: pkgs)); pkgs.releaseTools.aggregate {
+ name = "all";
+ constituents = pkgs.lib.mapAttrsToList (name: value: value."x86_64-linux".install-default) vm-tests;
+ });
+ all."x86_64-linux".install-daemonless = (with (forSystem "x86_64-linux" ({ system, pkgs, ... }: pkgs)); pkgs.releaseTools.aggregate {
+ name = "all";
+ constituents = pkgs.lib.mapAttrsToList (name: value: value."x86_64-linux".install-daemonless) vm-tests;
+ });
+ all."x86_64-linux".all = (with (forSystem "x86_64-linux" ({ system, pkgs, ... }: pkgs)); pkgs.releaseTools.aggregate {
+ name = "all";
+ constituents = [
+ all."x86_64-linux".install-default
+ all."x86_64-linux".install-no-start-daemon
+ all."x86_64-linux".install-daemonless
+ ];
+ });
}
diff --git a/src/action/base/setup_default_profile.rs b/src/action/base/setup_default_profile.rs
index 7a77864..ac5cbe6 100644
--- a/src/action/base/setup_default_profile.rs
+++ b/src/action/base/setup_default_profile.rs
@@ -2,7 +2,7 @@ use std::path::{Path, PathBuf};
use crate::{
action::{ActionError, StatefulAction},
- execute_command, set_env,
+ execute_command, set_env, ChannelValue,
};
use glob::glob;
@@ -17,12 +17,12 @@ Setup the default Nix profile with `nss-cacert` and `nix` itself.
*/
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
pub struct SetupDefaultProfile {
- channels: Vec,
+ channels: Vec,
}
impl SetupDefaultProfile {
#[tracing::instrument(level = "debug", skip_all)]
- pub async fn plan(channels: Vec) -> Result, ActionError> {
+ pub async fn plan(channels: Vec) -> Result, ActionError> {
Ok(Self { channels }.into())
}
}
@@ -38,7 +38,12 @@ impl Action for SetupDefaultProfile {
span!(
tracing::Level::DEBUG,
"setup_default_profile",
- channels = self.channels.join(","),
+ channels = self
+ .channels
+ .iter()
+ .map(|ChannelValue(channel, url)| format!("{channel}={url}"))
+ .collect::>()
+ .join(","),
)
}
@@ -206,7 +211,7 @@ impl Action for SetupDefaultProfile {
command.process_group(0);
command.arg("--update");
for channel in channels {
- command.arg(channel);
+ command.arg(channel.0.clone());
}
command.env(
"NIX_SSL_CERT_FILE",
diff --git a/src/action/common/configure_nix_daemon_service.rs b/src/action/common/configure_init_service.rs
similarity index 62%
rename from src/action/common/configure_nix_daemon_service.rs
rename to src/action/common/configure_init_service.rs
index e76c8e5..ddd6fce 100644
--- a/src/action/common/configure_nix_daemon_service.rs
+++ b/src/action/common/configure_init_service.rs
@@ -1,7 +1,5 @@
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
-use target_lexicon::OperatingSystem;
-use tokio::fs::remove_file;
use tokio::process::Command;
use tracing::{span, Span};
@@ -9,48 +7,54 @@ use crate::action::{ActionError, StatefulAction};
use crate::execute_command;
use crate::action::{Action, ActionDescription};
+use crate::settings::InitSystem;
+#[cfg(target_os = "linux")]
const SERVICE_SRC: &str = "/nix/var/nix/profiles/default/lib/systemd/system/nix-daemon.service";
+#[cfg(target_os = "linux")]
const SOCKET_SRC: &str = "/nix/var/nix/profiles/default/lib/systemd/system/nix-daemon.socket";
+#[cfg(target_os = "linux")]
const TMPFILES_SRC: &str = "/nix/var/nix/profiles/default/lib/tmpfiles.d/nix-daemon.conf";
+#[cfg(target_os = "linux")]
const TMPFILES_DEST: &str = "/etc/tmpfiles.d/nix-daemon.conf";
+#[cfg(target_os = "macos")]
const DARWIN_NIX_DAEMON_DEST: &str = "/Library/LaunchDaemons/org.nixos.nix-daemon.plist";
+#[cfg(target_os = "macos")]
const DARWIN_NIX_DAEMON_SOURCE: &str =
"/nix/var/nix/profiles/default/Library/LaunchDaemons/org.nixos.nix-daemon.plist";
/**
-Run systemd utilities to configure the Nix daemon
+Configure the init to run the Nix daemon
*/
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
-pub struct ConfigureNixDaemonService {}
+pub struct ConfigureInitService {
+ init: InitSystem,
+ start_daemon: bool,
+}
-impl ConfigureNixDaemonService {
+impl ConfigureInitService {
#[tracing::instrument(level = "debug", skip_all)]
- pub async fn plan() -> Result, ActionError> {
- match OperatingSystem::host() {
- OperatingSystem::MacOSX {
- major: _,
- minor: _,
- patch: _,
- }
- | OperatingSystem::Darwin => (),
- _ => {
- if !Path::new("/run/systemd/system").exists() {
- return Err(ActionError::Custom(Box::new(
- ConfigureNixDaemonServiceError::InitNotSupported,
- )));
- }
- },
- };
-
- Ok(Self {}.into())
+ pub async fn plan(
+ init: InitSystem,
+ start_daemon: bool,
+ ) -> Result, ActionError> {
+ Ok(Self { init, start_daemon }.into())
}
}
#[async_trait::async_trait]
#[typetag::serde(name = "configure_nix_daemon")]
-impl Action for ConfigureNixDaemonService {
+impl Action for ConfigureInitService {
fn tracing_synopsis(&self) -> String {
- "Configure Nix daemon related settings with systemd".to_string()
+ match self.init {
+ #[cfg(target_os = "linux")]
+ InitSystem::Systemd => "Configure Nix daemon related settings with systemd".to_string(),
+ #[cfg(target_os = "macos")]
+ InitSystem::Launchd => {
+ "Configure Nix daemon related settings with launchctl".to_string()
+ },
+ #[cfg(not(target_os = "macos"))]
+ InitSystem::None => "Leave the Nix daemon unconfigured".to_string(),
+ }
}
fn tracing_span(&self) -> Span {
@@ -58,44 +62,45 @@ impl Action for ConfigureNixDaemonService {
}
fn execute_description(&self) -> Vec {
- match OperatingSystem::host() {
- OperatingSystem::MacOSX {
- major: _,
- minor: _,
- patch: _,
- }
- | OperatingSystem::Darwin => vec![ActionDescription::new(
- self.tracing_synopsis(),
- vec![
- format!("Copy `{DARWIN_NIX_DAEMON_SOURCE}` to `DARWIN_NIX_DAEMON_DEST`"),
- format!("Run `launchctl load {DARWIN_NIX_DAEMON_DEST}`"),
- ],
- )],
- _ => vec![ActionDescription::new(
- self.tracing_synopsis(),
- vec![
+ let mut vec = Vec::new();
+ match self.init {
+ #[cfg(target_os = "linux")]
+ InitSystem::Systemd => {
+ let mut explanation = vec![
"Run `systemd-tempfiles --create --prefix=/nix/var/nix`".to_string(),
format!("Run `systemctl link {SERVICE_SRC}`"),
format!("Run `systemctl link {SOCKET_SRC}`"),
"Run `systemctl daemon-reload`".to_string(),
- format!("Run `systemctl enable --now {SOCKET_SRC}`"),
- ],
- )],
+ ];
+ if self.start_daemon {
+ explanation.push(format!("Run `systemctl enable --now {SOCKET_SRC}`"));
+ }
+ vec.push(ActionDescription::new(self.tracing_synopsis(), explanation))
+ },
+ #[cfg(target_os = "macos")]
+ InitSystem::Launchd => {
+ let mut explanation = vec![format!(
+ "Copy `{DARWIN_NIX_DAEMON_SOURCE}` to `DARWIN_NIX_DAEMON_DEST`"
+ )];
+ if self.start_daemon {
+ explanation.push(format!("Run `launchctl load {DARWIN_NIX_DAEMON_DEST}`"));
+ }
+ vec.push(ActionDescription::new(self.tracing_synopsis(), explanation))
+ },
+ #[cfg(not(target_os = "macos"))]
+ InitSystem::None => (),
}
+ vec
}
#[tracing::instrument(level = "debug", skip_all)]
async fn execute(&mut self) -> Result<(), ActionError> {
- let Self {} = self;
+ let Self { init, start_daemon } = self;
- match OperatingSystem::host() {
- OperatingSystem::MacOSX {
- major: _,
- minor: _,
- patch: _,
- }
- | OperatingSystem::Darwin => {
- let src = Path::new(DARWIN_NIX_DAEMON_SOURCE);
+ match init {
+ #[cfg(target_os = "macos")]
+ InitSystem::Launchd => {
+ let src = std::path::Path::new(DARWIN_NIX_DAEMON_SOURCE);
tokio::fs::copy(src.clone(), DARWIN_NIX_DAEMON_DEST)
.await
.map_err(|e| {
@@ -115,8 +120,22 @@ impl Action for ConfigureNixDaemonService {
)
.await
.map_err(ActionError::Command)?;
+
+ if *start_daemon {
+ execute_command(
+ Command::new("launchctl")
+ .process_group(0)
+ .arg("kickstart")
+ .arg("-k")
+ .arg("system/org.nixos.nix-daemon")
+ .stdin(std::process::Stdio::null()),
+ )
+ .await
+ .map_err(ActionError::Command)?;
+ }
},
- _ => {
+ #[cfg(target_os = "linux")]
+ InitSystem::Systemd => {
tracing::trace!(src = TMPFILES_SRC, dest = TMPFILES_DEST, "Symlinking");
tokio::fs::symlink(TMPFILES_SRC, TMPFILES_DEST)
.await
@@ -158,24 +177,30 @@ impl Action for ConfigureNixDaemonService {
.await
.map_err(ActionError::Command)?;
- execute_command(
- Command::new("systemctl")
- .process_group(0)
- .arg("daemon-reload")
- .stdin(std::process::Stdio::null()),
- )
- .await
- .map_err(ActionError::Command)?;
+ if *start_daemon {
+ execute_command(
+ Command::new("systemctl")
+ .process_group(0)
+ .arg("daemon-reload")
+ .stdin(std::process::Stdio::null()),
+ )
+ .await
+ .map_err(ActionError::Command)?;
- execute_command(
- Command::new("systemctl")
- .process_group(0)
- .arg("enable")
- .arg("--now")
- .arg(SOCKET_SRC),
- )
- .await
- .map_err(ActionError::Command)?;
+ execute_command(
+ Command::new("systemctl")
+ .process_group(0)
+ .arg("enable")
+ .arg("--now")
+ .arg(SOCKET_SRC),
+ )
+ .await
+ .map_err(ActionError::Command)?;
+ }
+ },
+ #[cfg(not(target_os = "macos"))]
+ InitSystem::None => {
+ // Nothing here, no init system
},
};
@@ -183,37 +208,36 @@ impl Action for ConfigureNixDaemonService {
}
fn revert_description(&self) -> Vec {
- match OperatingSystem::host() {
- OperatingSystem::MacOSX {
- major: _,
- minor: _,
- patch: _,
- }
- | OperatingSystem::Darwin => vec![ActionDescription::new(
- "Unconfigure Nix daemon related settings with launchd".to_string(),
- vec!["Run `launchctl unload {DARWIN_NIX_DAEMON_DEST}`".to_string()],
- )],
- _ => vec![ActionDescription::new(
- "Unconfigure Nix daemon related settings with systemd".to_string(),
- vec![
- "Run `systemctl disable {SOCKET_SRC}`".to_string(),
- "Run `systemctl disable {SERVICE_SRC}`".to_string(),
- "Run `systemd-tempfiles --remove --prefix=/nix/var/nix`".to_string(),
- "Run `systemctl daemon-reload`".to_string(),
- ],
- )],
+ match self.init {
+ #[cfg(target_os = "linux")]
+ InitSystem::Systemd => {
+ vec![ActionDescription::new(
+ "Unconfigure Nix daemon related settings with systemd".to_string(),
+ vec![
+ "Run `systemctl disable {SOCKET_SRC}`".to_string(),
+ "Run `systemctl disable {SERVICE_SRC}`".to_string(),
+ "Run `systemd-tempfiles --remove --prefix=/nix/var/nix`".to_string(),
+ "Run `systemctl daemon-reload`".to_string(),
+ ],
+ )]
+ },
+ #[cfg(target_os = "macos")]
+ InitSystem::Launchd => {
+ vec![ActionDescription::new(
+ "Unconfigure Nix daemon related settings with launchctl".to_string(),
+ vec!["Run `launchctl unload {DARWIN_NIX_DAEMON_DEST}`".to_string()],
+ )]
+ },
+ #[cfg(not(target_os = "macos"))]
+ InitSystem::None => Vec::new(),
}
}
#[tracing::instrument(level = "debug", skip_all)]
async fn revert(&mut self) -> Result<(), ActionError> {
- match OperatingSystem::host() {
- OperatingSystem::MacOSX {
- major: _,
- minor: _,
- patch: _,
- }
- | OperatingSystem::Darwin => {
+ match self.init {
+ #[cfg(target_os = "macos")]
+ InitSystem::Launchd => {
execute_command(
Command::new("launchctl")
.process_group(0)
@@ -223,7 +247,8 @@ impl Action for ConfigureNixDaemonService {
.await
.map_err(ActionError::Command)?;
},
- _ => {
+ #[cfg(target_os = "linux")]
+ InitSystem::Systemd => {
// We separate stop and disable (instead of using `--now`) to avoid cases where the service isn't started, but is enabled.
let socket_is_active = is_active("nix-daemon.socket").await?;
@@ -285,7 +310,7 @@ impl Action for ConfigureNixDaemonService {
.await
.map_err(ActionError::Command)?;
- remove_file(TMPFILES_DEST)
+ tokio::fs::remove_file(TMPFILES_DEST)
.await
.map_err(|e| ActionError::Remove(PathBuf::from(TMPFILES_DEST), e))?;
@@ -298,6 +323,10 @@ impl Action for ConfigureNixDaemonService {
.await
.map_err(ActionError::Command)?;
},
+ #[cfg(not(target_os = "macos"))]
+ InitSystem::None => {
+ // Nothing here, no init
+ },
};
Ok(())
@@ -310,6 +339,7 @@ pub enum ConfigureNixDaemonServiceError {
InitNotSupported,
}
+#[cfg(target_os = "linux")]
async fn is_active(unit: &str) -> Result {
let output = Command::new("systemctl")
.arg("is-active")
@@ -326,6 +356,7 @@ async fn is_active(unit: &str) -> Result {
}
}
+#[cfg(target_os = "linux")]
async fn is_enabled(unit: &str) -> Result {
let output = Command::new("systemctl")
.arg("is-enabled")
diff --git a/src/action/common/configure_nix.rs b/src/action/common/configure_nix.rs
index fa10bf8..b7a6118 100644
--- a/src/action/common/configure_nix.rs
+++ b/src/action/common/configure_nix.rs
@@ -1,17 +1,12 @@
use crate::{
action::{
base::SetupDefaultProfile,
- common::{
- ConfigureNixDaemonService, ConfigureShellProfile, PlaceChannelConfiguration,
- PlaceNixConfiguration,
- },
+ common::{ConfigureShellProfile, PlaceChannelConfiguration, PlaceNixConfiguration},
Action, ActionDescription, ActionError, StatefulAction,
},
- channel_value::ChannelValue,
settings::CommonSettings,
};
-use reqwest::Url;
use tracing::{span, Instrument, Span};
/**
@@ -23,20 +18,12 @@ pub struct ConfigureNix {
configure_shell_profile: Option>,
place_channel_configuration: StatefulAction,
place_nix_configuration: StatefulAction,
- configure_nix_daemon_service: StatefulAction,
}
impl ConfigureNix {
#[tracing::instrument(level = "debug", skip_all)]
pub async fn plan(settings: &CommonSettings) -> Result, ActionError> {
- let channels: Vec<(String, Url)> = settings
- .channels
- .iter()
- .map(|ChannelValue(channel, url)| (channel.to_string(), url.clone()))
- .collect();
-
- let setup_default_profile =
- SetupDefaultProfile::plan(channels.iter().map(|(v, _k)| v.clone()).collect()).await?;
+ let setup_default_profile = SetupDefaultProfile::plan(settings.channels.clone()).await?;
let configure_shell_profile = if settings.modify_profile {
Some(ConfigureShellProfile::plan().await?)
@@ -44,20 +31,18 @@ impl ConfigureNix {
None
};
let place_channel_configuration =
- PlaceChannelConfiguration::plan(channels, settings.force).await?;
+ PlaceChannelConfiguration::plan(settings.channels.clone(), settings.force).await?;
let place_nix_configuration = PlaceNixConfiguration::plan(
settings.nix_build_group_name.clone(),
settings.extra_conf.clone(),
settings.force,
)
.await?;
- let configure_nix_daemon_service = ConfigureNixDaemonService::plan().await?;
Ok(Self {
place_channel_configuration,
place_nix_configuration,
setup_default_profile,
- configure_nix_daemon_service,
configure_shell_profile,
}
.into())
@@ -78,14 +63,12 @@ impl Action for ConfigureNix {
fn execute_description(&self) -> Vec {
let Self {
setup_default_profile,
- configure_nix_daemon_service,
place_nix_configuration,
place_channel_configuration,
configure_shell_profile,
} = &self;
let mut buf = setup_default_profile.describe_execute();
- buf.append(&mut configure_nix_daemon_service.describe_execute());
buf.append(&mut place_nix_configuration.describe_execute());
buf.append(&mut place_channel_configuration.describe_execute());
if let Some(configure_shell_profile) = configure_shell_profile {
@@ -98,7 +81,6 @@ impl Action for ConfigureNix {
async fn execute(&mut self) -> Result<(), ActionError> {
let Self {
setup_default_profile,
- configure_nix_daemon_service,
place_nix_configuration,
place_channel_configuration,
configure_shell_profile,
@@ -168,7 +150,6 @@ impl Action for ConfigureNix {
},
)?;
};
- configure_nix_daemon_service.try_execute().await?;
Ok(())
}
@@ -176,7 +157,6 @@ impl Action for ConfigureNix {
fn revert_description(&self) -> Vec {
let Self {
setup_default_profile,
- configure_nix_daemon_service,
place_nix_configuration,
place_channel_configuration,
configure_shell_profile,
@@ -188,7 +168,6 @@ impl Action for ConfigureNix {
}
buf.append(&mut place_channel_configuration.describe_revert());
buf.append(&mut place_nix_configuration.describe_revert());
- buf.append(&mut configure_nix_daemon_service.describe_revert());
buf.append(&mut setup_default_profile.describe_revert());
buf
@@ -198,13 +177,11 @@ impl Action for ConfigureNix {
async fn revert(&mut self) -> Result<(), ActionError> {
let Self {
setup_default_profile,
- configure_nix_daemon_service,
place_nix_configuration,
place_channel_configuration,
configure_shell_profile,
} = self;
- configure_nix_daemon_service.try_revert().await?;
if let Some(configure_shell_profile) = configure_shell_profile {
configure_shell_profile.try_revert().await?;
}
diff --git a/src/action/common/mod.rs b/src/action/common/mod.rs
index 48dd904..ae7c566 100644
--- a/src/action/common/mod.rs
+++ b/src/action/common/mod.rs
@@ -1,7 +1,7 @@
//! [`Action`](crate::action::Action)s which only call other base plugins
+pub(crate) mod configure_init_service;
pub(crate) mod configure_nix;
-pub(crate) mod configure_nix_daemon_service;
pub(crate) mod configure_shell_profile;
pub(crate) mod create_nix_tree;
pub(crate) mod create_users_and_groups;
@@ -9,8 +9,8 @@ pub(crate) mod place_channel_configuration;
pub(crate) mod place_nix_configuration;
pub(crate) mod provision_nix;
+pub use configure_init_service::{ConfigureInitService, ConfigureNixDaemonServiceError};
pub use configure_nix::ConfigureNix;
-pub use configure_nix_daemon_service::{ConfigureNixDaemonService, ConfigureNixDaemonServiceError};
pub use configure_shell_profile::ConfigureShellProfile;
pub use create_nix_tree::CreateNixTree;
pub use create_users_and_groups::CreateUsersAndGroups;
diff --git a/src/action/common/place_channel_configuration.rs b/src/action/common/place_channel_configuration.rs
index c8baba1..5805f1c 100644
--- a/src/action/common/place_channel_configuration.rs
+++ b/src/action/common/place_channel_configuration.rs
@@ -1,7 +1,7 @@
use crate::action::base::CreateFile;
use crate::action::ActionError;
use crate::action::{Action, ActionDescription, StatefulAction};
-use reqwest::Url;
+use crate::ChannelValue;
use tracing::{span, Span};
/**
@@ -9,19 +9,19 @@ Place a channel configuration containing `channels` to the `$ROOT_HOME/.nix-chan
*/
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
pub struct PlaceChannelConfiguration {
- channels: Vec<(String, Url)>,
+ channels: Vec,
create_file: StatefulAction,
}
impl PlaceChannelConfiguration {
#[tracing::instrument(level = "debug", skip_all)]
pub async fn plan(
- channels: Vec<(String, Url)>,
+ channels: Vec,
force: bool,
) -> Result, ActionError> {
let buf = channels
.iter()
- .map(|(name, url)| format!("{} {}", url, name))
+ .map(|ChannelValue(name, url)| format!("{} {}", url, name))
.collect::>()
.join("\n");
let create_file = CreateFile::plan(
@@ -62,7 +62,7 @@ impl Action for PlaceChannelConfiguration {
channels = self
.channels
.iter()
- .map(|(c, u)| format!("{c}={u}"))
+ .map(|ChannelValue(c, u)| format!("{c}={u}"))
.collect::>()
.join(", "),
)
diff --git a/src/action/darwin/create_fstab_entry.rs b/src/action/darwin/create_fstab_entry.rs
index 240c5b1..e0980ab 100644
--- a/src/action/darwin/create_fstab_entry.rs
+++ b/src/action/darwin/create_fstab_entry.rs
@@ -1,19 +1,13 @@
-use nix::unistd::{chown, Group, User};
use uuid::Uuid;
use crate::{
action::{Action, ActionDescription, ActionError, StatefulAction},
execute_command,
};
-use rand::Rng;
use serde::Deserialize;
-use std::{
- io::SeekFrom,
- path::{Path, PathBuf},
- str::FromStr,
-};
+use std::{io::SeekFrom, path::Path};
use tokio::{
- fs::{remove_file, OpenOptions},
+ fs::OpenOptions,
io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt},
process::Command,
};
diff --git a/src/action/darwin/kickstart_launchctl_service.rs b/src/action/darwin/kickstart_launchctl_service.rs
deleted file mode 100644
index 852d8d5..0000000
--- a/src/action/darwin/kickstart_launchctl_service.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-use tokio::process::Command;
-use tracing::{span, Span};
-
-use crate::action::{ActionError, StatefulAction};
-use crate::execute_command;
-
-use crate::action::{Action, ActionDescription};
-
-/**
-Kickstart a `launchctl` service
- */
-#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
-pub struct KickstartLaunchctlService {
- unit: String,
-}
-
-impl KickstartLaunchctlService {
- #[tracing::instrument(level = "debug", skip_all)]
- pub async fn plan(unit: String) -> Result, ActionError> {
- Ok(Self { unit }.into())
- }
-}
-
-#[async_trait::async_trait]
-#[typetag::serde(name = "kickstart_launchctl_service")]
-impl Action for KickstartLaunchctlService {
- fn tracing_synopsis(&self) -> String {
- let Self { unit, .. } = self;
- format!("Kickstart the launchctl unit `{unit}`")
- }
-
- fn tracing_span(&self) -> Span {
- span!(
- tracing::Level::DEBUG,
- "kickstart_launchctl_service",
- unit = %self.unit,
- )
- }
-
- fn execute_description(&self) -> Vec {
- vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
- }
-
- #[tracing::instrument(level = "debug", skip_all)]
- async fn execute(&mut self) -> Result<(), ActionError> {
- let Self { unit } = self;
-
- execute_command(
- Command::new("launchctl")
- .process_group(0)
- .arg("kickstart")
- .arg("-k")
- .arg(unit)
- .stdin(std::process::Stdio::null()),
- )
- .await
- .map_err(ActionError::Command)?;
-
- Ok(())
- }
-
- fn revert_description(&self) -> Vec {
- vec![]
- }
-
- #[tracing::instrument(level = "debug", skip_all)]
- async fn revert(&mut self) -> Result<(), ActionError> {
- // noop
- Ok(())
- }
-}
diff --git a/src/action/darwin/mod.rs b/src/action/darwin/mod.rs
index add755a..e0335f5 100644
--- a/src/action/darwin/mod.rs
+++ b/src/action/darwin/mod.rs
@@ -8,7 +8,6 @@ pub(crate) mod create_nix_volume;
pub(crate) mod create_synthetic_objects;
pub(crate) mod enable_ownership;
pub(crate) mod encrypt_apfs_volume;
-pub(crate) mod kickstart_launchctl_service;
pub(crate) mod unmount_apfs_volume;
pub use bootstrap_apfs_volume::{BootstrapApfsVolume, BootstrapVolumeError};
@@ -17,5 +16,4 @@ pub use create_nix_volume::{CreateNixVolume, NIX_VOLUME_MOUNTD_DEST};
pub use create_synthetic_objects::{CreateSyntheticObjects, CreateSyntheticObjectsError};
pub use enable_ownership::{EnableOwnership, EnableOwnershipError};
pub use encrypt_apfs_volume::EncryptApfsVolume;
-pub use kickstart_launchctl_service::KickstartLaunchctlService;
pub use unmount_apfs_volume::UnmountApfsVolume;
diff --git a/src/action/mod.rs b/src/action/mod.rs
index 1c1de5a..a05e8d3 100644
--- a/src/action/mod.rs
+++ b/src/action/mod.rs
@@ -32,7 +32,7 @@ action.try_revert().await.unwrap();
```
A general guidance for what determines how fine-grained an [`Action`] should be is the unit of
-reversion. The [`ConfigureNixDaemonService`](common::ConfigureNixDaemonService) action is a good
+reversion. The [`ConfigureInitService`](common::ConfigureInitService) action is a good
example of this, it takes several steps, such as running `systemd-tmpfiles`, and calling
`systemctl link` on some systemd units.
@@ -49,7 +49,7 @@ use tracing::{Span, span};
use nix_installer::{
InstallPlan,
settings::{CommonSettings, InstallSettingsError},
- planner::{Planner, PlannerError, linux::SteamDeck},
+ planner::{Planner, PlannerError},
action::{Action, ActionError, StatefulAction, ActionDescription},
};
@@ -112,7 +112,7 @@ pub struct MyPlanner {
impl Planner for MyPlanner {
async fn default() -> Result {
Ok(Self {
- common: CommonSettings::default()?,
+ common: CommonSettings::default().await?,
})
}
diff --git a/src/lib.rs b/src/lib.rs
index 5b80bde..1a67cca 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -34,14 +34,17 @@ match plan.install(None).await {
# }
```
-Sometimes choosing a specific plan is desired:
+Sometimes choosing a specific planner is desired:
```rust,no_run
use std::error::Error;
-use nix_installer::{InstallPlan, planner::{Planner, linux::SteamDeck}};
+use nix_installer::{InstallPlan, planner::Planner};
# async fn chosen_planner_install() -> color_eyre::Result<()> {
-let planner = SteamDeck::default().await?;
+#[cfg(target_os = "linux")]
+let planner = nix_installer::planner::linux::SteamDeck::default().await?;
+#[cfg(target_os = "macos")]
+let planner = nix_installer::planner::darwin::DarwinMulti::default().await?;
// Or call `crate::planner::BuiltinPlanner::default()`
// Match on the result to customize.
diff --git a/src/planner/darwin/multi.rs b/src/planner/darwin/multi.rs
index 7abacad..2e01539 100644
--- a/src/planner/darwin/multi.rs
+++ b/src/planner/darwin/multi.rs
@@ -6,15 +6,15 @@ use tokio::process::Command;
use crate::{
action::{
- common::{ConfigureNix, ProvisionNix},
- darwin::{CreateNixVolume, KickstartLaunchctlService},
+ common::{ConfigureInitService, ConfigureNix, ProvisionNix},
+ darwin::CreateNixVolume,
StatefulAction,
},
execute_command,
os::darwin::DiskUtilOutput,
planner::{Planner, PlannerError},
- settings::CommonSettings,
settings::InstallSettingsError,
+ settings::{CommonSettings, InitSystem},
Action, BuiltinPlanner,
};
@@ -24,6 +24,7 @@ use crate::{
pub struct DarwinMulti {
#[cfg_attr(feature = "cli", clap(flatten))]
pub settings: CommonSettings,
+
/// Force encryption on the volume
#[cfg_attr(
feature = "cli",
@@ -76,7 +77,7 @@ async fn default_root_disk() -> Result {
impl Planner for DarwinMulti {
async fn default() -> Result {
Ok(Self {
- settings: CommonSettings::default()?,
+ settings: CommonSettings::default().await?,
root_disk: Some(default_root_disk().await?),
case_sensitive: false,
encrypt: None,
@@ -140,7 +141,7 @@ impl Planner for DarwinMulti {
.await
.map_err(PlannerError::Action)?
.boxed(),
- KickstartLaunchctlService::plan("system/org.nixos.nix-daemon".into())
+ ConfigureInitService::plan(InitSystem::Launchd, true)
.await
.map_err(PlannerError::Action)?
.boxed(),
diff --git a/src/planner/linux/multi.rs b/src/planner/linux/multi.rs
index df84424..9b82d9a 100644
--- a/src/planner/linux/multi.rs
+++ b/src/planner/linux/multi.rs
@@ -1,12 +1,12 @@
use crate::{
action::{
base::CreateDirectory,
- common::{ConfigureNix, ProvisionNix},
+ common::{ConfigureInitService, ConfigureNix, ProvisionNix},
StatefulAction,
},
planner::{Planner, PlannerError},
settings::CommonSettings,
- settings::InstallSettingsError,
+ settings::{InitSettings, InstallSettingsError},
Action, BuiltinPlanner,
};
use std::{collections::HashMap, path::Path};
@@ -18,6 +18,8 @@ use tokio::process::Command;
pub struct LinuxMulti {
#[cfg_attr(feature = "cli", clap(flatten))]
pub settings: CommonSettings,
+ #[cfg_attr(feature = "cli", clap(flatten))]
+ pub init: InitSettings,
}
#[async_trait::async_trait]
@@ -25,7 +27,8 @@ pub struct LinuxMulti {
impl Planner for LinuxMulti {
async fn default() -> Result {
Ok(Self {
- settings: CommonSettings::default()?,
+ settings: CommonSettings::default().await?,
+ init: InitSettings::default().await?,
})
}
@@ -77,14 +80,19 @@ impl Planner for LinuxMulti {
.await
.map_err(PlannerError::Action)?
.boxed(),
+ ConfigureInitService::plan(self.init.init, self.init.start_daemon)
+ .await
+ .map_err(PlannerError::Action)?
+ .boxed(),
])
}
fn settings(&self) -> Result, InstallSettingsError> {
- let Self { settings } = self;
+ let Self { settings, init } = self;
let mut map = HashMap::default();
map.extend(settings.settings()?.into_iter());
+ map.extend(init.settings()?.into_iter());
Ok(map)
}
diff --git a/src/planner/linux/steam_deck.rs b/src/planner/linux/steam_deck.rs
index b34f635..170ddff 100644
--- a/src/planner/linux/steam_deck.rs
+++ b/src/planner/linux/steam_deck.rs
@@ -64,12 +64,12 @@ use std::{collections::HashMap, path::PathBuf};
use crate::{
action::{
base::{CreateDirectory, CreateFile},
- common::{ConfigureNix, ProvisionNix},
+ common::{ConfigureInitService, ConfigureNix, ProvisionNix},
linux::StartSystemdUnit,
Action, StatefulAction,
},
planner::{Planner, PlannerError},
- settings::{CommonSettings, InstallSettingsError},
+ settings::{CommonSettings, InitSystem, InstallSettingsError},
BuiltinPlanner,
};
@@ -95,7 +95,7 @@ impl Planner for SteamDeck {
async fn default() -> Result {
Ok(Self {
persistence: PathBuf::from("/home/nix"),
- settings: CommonSettings::default()?,
+ settings: CommonSettings::default().await?,
})
}
@@ -225,6 +225,11 @@ impl Planner for SteamDeck {
.await
.map_err(PlannerError::Action)?
.boxed(),
+ // Init is required for the steam-deck archetype to make the `/nix` mount
+ ConfigureInitService::plan(InitSystem::Systemd, true)
+ .await
+ .map_err(PlannerError::Action)?
+ .boxed(),
])
}
diff --git a/src/planner/mod.rs b/src/planner/mod.rs
index c394997..3c73b8d 100644
--- a/src/planner/mod.rs
+++ b/src/planner/mod.rs
@@ -1,7 +1,6 @@
/*! [`BuiltinPlanner`]s and traits to create new types which can be used to plan out an [`InstallPlan`]
-It's a [`Planner`]s job to construct (if possible) a valid [`InstallPlan`] for the host. Some planners,
-like [`LinuxMulti`](linux::LinuxMulti), are operating system specific. Others, like [`SteamDeck`](linux::SteamDeck), are device specific.
+It's a [`Planner`]s job to construct (if possible) a valid [`InstallPlan`] for the host. Some planners are operating system specific, others are device specific.
[`Planner`]s contain their planner specific settings, typically alongside a [`CommonSettings`][crate::settings::CommonSettings].
@@ -16,8 +15,8 @@ use std::{error::Error, collections::HashMap};
use nix_installer::{
InstallPlan,
settings::{CommonSettings, InstallSettingsError},
- planner::{Planner, PlannerError, linux::SteamDeck},
- action::{Action, StatefulAction, linux::StartSystemdUnit},
+ planner::{Planner, PlannerError},
+ action::{Action, StatefulAction, base::CreateFile},
};
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
@@ -31,7 +30,7 @@ pub struct MyPlanner {
impl Planner for MyPlanner {
async fn default() -> Result {
Ok(Self {
- common: CommonSettings::default()?,
+ common: CommonSettings::default().await?,
})
}
@@ -39,7 +38,7 @@ impl Planner for MyPlanner {
Ok(vec![
// ...
- StartSystemdUnit::plan("nix-daemon.socket")
+ CreateFile::plan("/example", None, None, None, "Example".to_string(), false)
.await
.map_err(PlannerError::Action)?.boxed(),
])
@@ -74,7 +73,9 @@ match plan.install(None).await {
```
*/
+#[cfg(target_os = "macos")]
pub mod darwin;
+#[cfg(target_os = "linux")]
pub mod linux;
use std::{collections::HashMap, string::FromUtf8Error};
@@ -113,11 +114,14 @@ dyn_clone::clone_trait_object!(Planner);
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "cli", derive(clap::Subcommand))]
pub enum BuiltinPlanner {
+ #[cfg(target_os = "linux")]
/// A standard Linux multi-user install
LinuxMulti(linux::LinuxMulti),
/// A standard MacOS (Darwin) multi-user install
+ #[cfg(target_os = "macos")]
DarwinMulti(darwin::DarwinMulti),
/// A specialized install suitable for the Valve Steam Deck console
+ #[cfg(target_os = "linux")]
SteamDeck(linux::SteamDeck),
}
@@ -126,16 +130,20 @@ impl BuiltinPlanner {
pub async fn default() -> Result {
use target_lexicon::{Architecture, OperatingSystem};
match (Architecture::host(), OperatingSystem::host()) {
+ #[cfg(target_os = "linux")]
(Architecture::X86_64, OperatingSystem::Linux) => {
Ok(Self::LinuxMulti(linux::LinuxMulti::default().await?))
},
+ #[cfg(target_os = "linux")]
(Architecture::Aarch64(_), OperatingSystem::Linux) => {
Ok(Self::LinuxMulti(linux::LinuxMulti::default().await?))
},
+ #[cfg(target_os = "macos")]
(Architecture::X86_64, OperatingSystem::MacOSX { .. })
| (Architecture::X86_64, OperatingSystem::Darwin) => {
Ok(Self::DarwinMulti(darwin::DarwinMulti::default().await?))
},
+ #[cfg(target_os = "macos")]
(Architecture::Aarch64(_), OperatingSystem::MacOSX { .. })
| (Architecture::Aarch64(_), OperatingSystem::Darwin) => {
Ok(Self::DarwinMulti(darwin::DarwinMulti::default().await?))
@@ -147,41 +155,56 @@ impl BuiltinPlanner {
pub async fn from_common_settings(settings: CommonSettings) -> Result {
let mut built = Self::default().await?;
match &mut built {
+ #[cfg(target_os = "linux")]
BuiltinPlanner::LinuxMulti(inner) => inner.settings = settings,
- BuiltinPlanner::DarwinMulti(inner) => inner.settings = settings,
+ #[cfg(target_os = "linux")]
BuiltinPlanner::SteamDeck(inner) => inner.settings = settings,
+ #[cfg(target_os = "macos")]
+ BuiltinPlanner::DarwinMulti(inner) => inner.settings = settings,
}
Ok(built)
}
pub async fn plan(self) -> Result {
match self {
+ #[cfg(target_os = "linux")]
BuiltinPlanner::LinuxMulti(planner) => InstallPlan::plan(planner).await,
- BuiltinPlanner::DarwinMulti(planner) => InstallPlan::plan(planner).await,
+ #[cfg(target_os = "linux")]
BuiltinPlanner::SteamDeck(planner) => InstallPlan::plan(planner).await,
+ #[cfg(target_os = "macos")]
+ BuiltinPlanner::DarwinMulti(planner) => InstallPlan::plan(planner).await,
}
}
pub fn boxed(self) -> Box {
match self {
+ #[cfg(target_os = "linux")]
BuiltinPlanner::LinuxMulti(i) => i.boxed(),
- BuiltinPlanner::DarwinMulti(i) => i.boxed(),
+ #[cfg(target_os = "linux")]
BuiltinPlanner::SteamDeck(i) => i.boxed(),
+ #[cfg(target_os = "macos")]
+ BuiltinPlanner::DarwinMulti(i) => i.boxed(),
}
}
pub fn typetag_name(&self) -> &'static str {
match self {
+ #[cfg(target_os = "linux")]
BuiltinPlanner::LinuxMulti(i) => i.typetag_name(),
- BuiltinPlanner::DarwinMulti(i) => i.typetag_name(),
+ #[cfg(target_os = "linux")]
BuiltinPlanner::SteamDeck(i) => i.typetag_name(),
+ #[cfg(target_os = "macos")]
+ BuiltinPlanner::DarwinMulti(i) => i.typetag_name(),
}
}
pub fn settings(&self) -> Result, InstallSettingsError> {
match self {
+ #[cfg(target_os = "linux")]
BuiltinPlanner::LinuxMulti(i) => i.settings(),
- BuiltinPlanner::DarwinMulti(i) => i.settings(),
+ #[cfg(target_os = "linux")]
BuiltinPlanner::SteamDeck(i) => i.settings(),
+ #[cfg(target_os = "macos")]
+ BuiltinPlanner::DarwinMulti(i) => i.settings(),
}
}
}
diff --git a/src/settings.rs b/src/settings.rs
index 0063884..3cf367b 100644
--- a/src/settings.rs
+++ b/src/settings.rs
@@ -21,6 +21,30 @@ pub const NIX_X64_64_DARWIN_URL: &str =
pub const NIX_AARCH64_DARWIN_URL: &str =
"https://releases.nixos.org/nix/nix-2.12.0/nix-2.12.0-aarch64-darwin.tar.xz";
+#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, Copy)]
+#[cfg_attr(feature = "cli", derive(clap::ValueEnum))]
+pub enum InitSystem {
+ #[cfg(not(target_os = "macos"))]
+ None,
+ #[cfg(target_os = "linux")]
+ Systemd,
+ #[cfg(target_os = "macos")]
+ Launchd,
+}
+
+impl std::fmt::Display for InitSystem {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ #[cfg(not(target_os = "macos"))]
+ InitSystem::None => write!(f, "none"),
+ #[cfg(target_os = "linux")]
+ InitSystem::Systemd => write!(f, "systemd"),
+ #[cfg(target_os = "macos")]
+ InitSystem::Launchd => write!(f, "launchd"),
+ }
+ }
+}
+
/** Common settings used by all [`BuiltinPlanner`](crate::planner::BuiltinPlanner)s
Settings which only apply to certain [`Planner`](crate::planner::Planner)s should be located in the planner.
@@ -173,29 +197,33 @@ pub struct CommonSettings {
impl CommonSettings {
/// The default settings for the given Architecture & Operating System
- pub fn default() -> Result {
+ pub async fn default() -> Result {
let url;
let nix_build_user_prefix;
let nix_build_user_id_base;
use target_lexicon::{Architecture, OperatingSystem};
match (Architecture::host(), OperatingSystem::host()) {
+ #[cfg(target_os = "linux")]
(Architecture::X86_64, OperatingSystem::Linux) => {
url = NIX_X64_64_LINUX_URL;
nix_build_user_prefix = "nixbld";
nix_build_user_id_base = 3000;
},
+ #[cfg(target_os = "linux")]
(Architecture::Aarch64(_), OperatingSystem::Linux) => {
url = NIX_AARCH64_LINUX_URL;
nix_build_user_prefix = "nixbld";
nix_build_user_id_base = 3000;
},
+ #[cfg(target_os = "macos")]
(Architecture::X86_64, OperatingSystem::MacOSX { .. })
| (Architecture::X86_64, OperatingSystem::Darwin) => {
url = NIX_X64_64_DARWIN_URL;
nix_build_user_prefix = "_nixbld";
nix_build_user_id_base = 300;
},
+ #[cfg(target_os = "macos")]
(Architecture::Aarch64(_), OperatingSystem::MacOSX { .. })
| (Architecture::Aarch64(_), OperatingSystem::Darwin) => {
url = NIX_AARCH64_DARWIN_URL;
@@ -286,6 +314,34 @@ impl CommonSettings {
Ok(map)
}
}
+#[cfg(target_os = "linux")]
+async fn linux_detect_init() -> (InitSystem, bool) {
+ use std::process::Stdio;
+
+ let mut detected = InitSystem::None;
+ let mut started = false;
+ if std::path::Path::new("/run/systemd/system").exists() {
+ detected = InitSystem::Systemd;
+ started = if tokio::process::Command::new("systemctl")
+ .arg("status")
+ .stdin(Stdio::null())
+ .stdout(Stdio::null())
+ .stderr(Stdio::null())
+ .status()
+ .await
+ .ok()
+ .map(|exit| exit.success())
+ .unwrap_or(false)
+ {
+ true
+ } else {
+ false
+ }
+ }
+
+ // TODO: Other inits
+ (detected, started)
+}
// Builder Pattern
impl CommonSettings {
@@ -349,6 +405,96 @@ impl CommonSettings {
}
}
+#[serde_with::serde_as]
+#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
+#[cfg_attr(feature = "cli", derive(clap::Parser))]
+pub struct InitSettings {
+ /// Which init system to configure (if `--init none` Nix will be root-only)
+ #[cfg_attr(feature = "cli", clap(value_parser, long, env = "NIX_INSTALLER_INIT",))]
+ #[cfg_attr(
+ all(target_os = "macos", feature = "cli"),
+ clap(default_value_t = InitSystem::Launchd)
+ )]
+ #[cfg_attr(
+ all(target_os = "linux", feature = "cli"),
+ clap(default_value_t = InitSystem::Systemd)
+ )]
+ pub(crate) init: InitSystem,
+
+ /// Start the daemon (if not `--init none`)
+ #[cfg_attr(
+ feature = "cli",
+ clap(
+ value_parser,
+ long,
+ action(ArgAction::SetFalse),
+ env = "NIX_INSTALLER_START_DAEMON",
+ default_value_t = true,
+ long = "no-start-daemon"
+ )
+ )]
+ pub(crate) start_daemon: bool,
+}
+
+impl InitSettings {
+ /// The default settings for the given Architecture & Operating System
+ pub async fn default() -> Result {
+ let init;
+ let start_daemon;
+
+ use target_lexicon::{Architecture, OperatingSystem};
+ match (Architecture::host(), OperatingSystem::host()) {
+ #[cfg(target_os = "linux")]
+ (Architecture::X86_64, OperatingSystem::Linux) => {
+ (init, start_daemon) = linux_detect_init().await;
+ },
+ #[cfg(target_os = "linux")]
+ (Architecture::Aarch64(_), OperatingSystem::Linux) => {
+ (init, start_daemon) = linux_detect_init().await;
+ },
+ #[cfg(target_os = "macos")]
+ (Architecture::X86_64, OperatingSystem::MacOSX { .. })
+ | (Architecture::X86_64, OperatingSystem::Darwin) => {
+ (init, start_daemon) = (InitSystem::Launchd, true);
+ },
+ #[cfg(target_os = "macos")]
+ (Architecture::Aarch64(_), OperatingSystem::MacOSX { .. })
+ | (Architecture::Aarch64(_), OperatingSystem::Darwin) => {
+ (init, start_daemon) = (InitSystem::Launchd, true);
+ },
+ _ => {
+ return Err(InstallSettingsError::UnsupportedArchitecture(
+ target_lexicon::HOST,
+ ))
+ },
+ };
+
+ Ok(Self { init, start_daemon })
+ }
+
+ /// A listing of the settings, suitable for [`Planner::settings`](crate::planner::Planner::settings)
+ pub fn settings(&self) -> Result, InstallSettingsError> {
+ let Self { init, start_daemon } = self;
+ let mut map = HashMap::default();
+
+ map.insert("init".into(), serde_json::to_value(init)?);
+ map.insert("start_daemon".into(), serde_json::to_value(start_daemon)?);
+ Ok(map)
+ }
+
+ /// Which init system to configure
+ pub fn init(&mut self, init: InitSystem) -> &mut Self {
+ self.init = init;
+ self
+ }
+
+ /// Start the daemon (if one is configured)
+ pub fn start_daemon(&mut self, toggle: bool) -> &mut Self {
+ self.start_daemon = toggle;
+ self
+ }
+}
+
/// An error originating from a [`Planner::settings`](crate::planner::Planner::settings)
#[derive(thiserror::Error, Debug)]
pub enum InstallSettingsError {
@@ -369,4 +515,6 @@ pub enum InstallSettingsError {
#[from]
serde_json::Error,
),
+ #[error("No supported init system found")]
+ InitNotSupported,
}
diff --git a/tests/fixtures/darwin/darwin-multi.json b/tests/fixtures/darwin/darwin-multi.json
index fcd7ae7..f263f50 100644
--- a/tests/fixtures/darwin/darwin-multi.json
+++ b/tests/fixtures/darwin/darwin-multi.json
@@ -546,7 +546,10 @@
"setup_default_profile": {
"action": {
"channels": [
- "nixpkgs"
+ [
+ "nixpkgs",
+ "https://nixos.org/channels/nixpkgs-unstable"
+ ]
]
},
"state": "Uncompleted"
@@ -632,25 +635,22 @@
"user": null,
"group": null,
"mode": 436,
- "buf": "\n\nbuild-users-group = nixbld\n\nexperimental-features = nix-command flakes\n\nauto-optimise-store = true\n",
+ "buf": "# Generated by https://github.com/DeterminateSystems/nix-installer, version 0.1.0-unreleased.\n\n\n\nbuild-users-group = nixbld\n\nexperimental-features = nix-command flakes\n\nauto-optimise-store = true\n\nbash-prompt-prefix = (nix:$name)\\040\n",
"force": false
},
"state": "Uncompleted"
}
},
"state": "Uncompleted"
- },
- "configure_nix_daemon_service": {
- "action": {},
- "state": "Uncompleted"
}
},
"state": "Uncompleted"
},
{
"action": {
- "action": "kickstart_launchctl_service",
- "unit": "system/org.nixos.nix-daemon"
+ "action": "configure_nix_daemon",
+ "init": "Launchd",
+ "start_daemon": true
},
"state": "Uncompleted"
}
diff --git a/tests/fixtures/linux/linux-multi.json b/tests/fixtures/linux/linux-multi.json
index 6042d0f..4b049b2 100644
--- a/tests/fixtures/linux/linux-multi.json
+++ b/tests/fixtures/linux/linux-multi.json
@@ -1,617 +1,628 @@
{
- "version": "0.1.0-unreleased",
- "actions": [
- {
- "action": {
- "action": "create_directory",
- "path": "/nix",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": true
- },
- "state": "Skipped"
- },
- {
- "action": {
- "action": "provision_nix",
- "fetch_nix": {
- "action": {
- "url": "https://releases.nixos.org/nix/nix-2.12.0/nix-2.12.0-x86_64-linux.tar.xz",
- "dest": "/nix/temp-install-dir"
- },
- "state": "Uncompleted"
+ "version": "0.1.0-unreleased",
+ "actions": [
+ {
+ "action": {
+ "action": "create_directory",
+ "path": "/nix",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": true
},
- "create_users_and_group": {
- "action": {
- "nix_build_user_count": 32,
- "nix_build_group_name": "nixbld",
- "nix_build_group_id": 3000,
- "nix_build_user_prefix": "nixbld",
- "nix_build_user_id_base": 3000,
- "create_group": {
- "action": {
- "name": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "action": "provision_nix",
+ "fetch_nix": {
+ "action": {
+ "url": "https://releases.nixos.org/nix/nix-2.12.0/nix-2.12.0-x86_64-linux.tar.xz",
+ "dest": "/nix/temp-install-dir"
},
- "create_users": [
- {
- "action": {
- "name": "nixbld0",
- "uid": 3000,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld1",
- "uid": 3001,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld2",
- "uid": 3002,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld3",
- "uid": 3003,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld4",
- "uid": 3004,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld5",
- "uid": 3005,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld6",
- "uid": 3006,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld7",
- "uid": 3007,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld8",
- "uid": 3008,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld9",
- "uid": 3009,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld10",
- "uid": 3010,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld11",
- "uid": 3011,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld12",
- "uid": 3012,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld13",
- "uid": 3013,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld14",
- "uid": 3014,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld15",
- "uid": 3015,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld16",
- "uid": 3016,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld17",
- "uid": 3017,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld18",
- "uid": 3018,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld19",
- "uid": 3019,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld20",
- "uid": 3020,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld21",
- "uid": 3021,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld22",
- "uid": 3022,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld23",
- "uid": 3023,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld24",
- "uid": 3024,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld25",
- "uid": 3025,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld26",
- "uid": 3026,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld27",
- "uid": 3027,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld28",
- "uid": 3028,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld29",
- "uid": 3029,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld30",
- "uid": 3030,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld31",
- "uid": 3031,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- }
- ]
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- "create_nix_tree": {
- "action": {
- "create_directories": [
- {
+ "create_users_and_group": {
+ "action": {
+ "nix_build_user_count": 32,
+ "nix_build_group_name": "nixbld",
+ "nix_build_group_id": 3000,
+ "nix_build_user_prefix": "nixbld",
+ "nix_build_user_id_base": 3000,
+ "create_group": {
"action": {
- "path": "/nix/var",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ "name": "nixbld",
+ "gid": 3000
},
"state": "Uncompleted"
},
- {
- "action": {
- "path": "/nix/var/log",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ "create_users": [
+ {
+ "action": {
+ "name": "nixbld0",
+ "uid": 3000,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/log/nix",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld1",
+ "uid": 3001,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/log/nix/drvs",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld2",
+ "uid": 3002,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld3",
+ "uid": 3003,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix/db",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld4",
+ "uid": 3004,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix/gcroots",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld5",
+ "uid": 3005,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix/gcroots/per-user",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld6",
+ "uid": 3006,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix/profiles",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld7",
+ "uid": 3007,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix/profiles/per-user",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld8",
+ "uid": 3008,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix/temproots",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld9",
+ "uid": 3009,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix/userpool",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld10",
+ "uid": 3010,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix/daemon-socket",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld11",
+ "uid": 3011,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- }
- ]
- },
- "state": "Uncompleted"
- },
- "move_unpacked_nix": {
- "action": {
- "src": "/nix/temp-install-dir"
- },
- "state": "Uncompleted"
- }
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "action": "configure_nix",
- "setup_default_profile": {
- "action": {
- "channels": [
- "nixpkgs"
- ]
- },
- "state": "Uncompleted"
- },
- "configure_shell_profile": {
- "action": {
- "create_directories": [],
- "create_or_insert_into_files": [
- {
- "action": {
- "path": "/etc/bashrc",
- "user": null,
- "group": null,
- "mode": 493,
- "buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
- "position": "Beginning"
+ {
+ "action": {
+ "name": "nixbld12",
+ "uid": 3012,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/etc/profile.d/nix.sh",
- "user": null,
- "group": null,
- "mode": 493,
- "buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
- "position": "Beginning"
+ {
+ "action": {
+ "name": "nixbld13",
+ "uid": 3013,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/etc/zshenv",
- "user": null,
- "group": null,
- "mode": 493,
- "buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
- "position": "Beginning"
+ {
+ "action": {
+ "name": "nixbld14",
+ "uid": 3014,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/etc/bash.bashrc",
- "user": null,
- "group": null,
- "mode": 493,
- "buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
- "position": "Beginning"
+ {
+ "action": {
+ "name": "nixbld15",
+ "uid": 3015,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- }
- ]
- },
- "state": "Uncompleted"
- },
- "place_channel_configuration": {
- "action": {
- "channels": [
- [
- "nixpkgs",
- "https://nixos.org/channels/nixpkgs-unstable"
+ {
+ "action": {
+ "name": "nixbld16",
+ "uid": 3016,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld17",
+ "uid": 3017,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld18",
+ "uid": 3018,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld19",
+ "uid": 3019,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld20",
+ "uid": 3020,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld21",
+ "uid": 3021,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld22",
+ "uid": 3022,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld23",
+ "uid": 3023,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld24",
+ "uid": 3024,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld25",
+ "uid": 3025,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld26",
+ "uid": 3026,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld27",
+ "uid": 3027,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld28",
+ "uid": 3028,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld29",
+ "uid": 3029,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld30",
+ "uid": 3030,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld31",
+ "uid": 3031,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ }
]
- ],
- "create_file": {
- "action": {
- "path": "/root/.nix-channels",
- "user": null,
- "group": null,
- "mode": 436,
- "buf": "https://nixos.org/channels/nixpkgs-unstable nixpkgs",
- "force": false
- },
- "state": "Uncompleted"
- }
- },
- "state": "Uncompleted"
- },
- "place_nix_configuration": {
- "action": {
- "create_directory": {
- "action": {
- "path": "/etc/nix",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
- },
- "state": "Uncompleted"
},
- "create_file": {
- "action": {
- "path": "/etc/nix/nix.conf",
- "user": null,
- "group": null,
- "mode": 436,
- "buf": "\n\nbuild-users-group = nixbld\n\nexperimental-features = nix-command flakes\n\nauto-optimise-store = true\n",
- "force": false
- },
- "state": "Uncompleted"
- }
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
+ "create_nix_tree": {
+ "action": {
+ "create_directories": [
+ {
+ "action": {
+ "path": "/nix/var",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/log",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/log/nix",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/log/nix/drvs",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix/db",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix/gcroots",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix/gcroots/per-user",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix/profiles",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix/profiles/per-user",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix/temproots",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix/userpool",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix/daemon-socket",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ }
+ ]
+ },
+ "state": "Uncompleted"
+ },
+ "move_unpacked_nix": {
+ "action": {
+ "src": "/nix/temp-install-dir"
+ },
+ "state": "Uncompleted"
+ }
},
- "configure_nix_daemon_service": {
- "action": {},
- "state": "Uncompleted"
- }
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
+ {
+ "action": {
+ "action": "configure_nix",
+ "setup_default_profile": {
+ "action": {
+ "channels": [
+ [
+ "nixpkgs",
+ "https://nixos.org/channels/nixpkgs-unstable"
+ ]
+ ]
+ },
+ "state": "Uncompleted"
+ },
+ "configure_shell_profile": {
+ "action": {
+ "create_directories": [],
+ "create_or_insert_into_files": [
+ {
+ "action": {
+ "path": "/etc/bashrc",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
+ "position": "Beginning"
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/etc/profile.d/nix.sh",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
+ "position": "Beginning"
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/etc/zshenv",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
+ "position": "Beginning"
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/etc/bash.bashrc",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
+ "position": "Beginning"
+ },
+ "state": "Uncompleted"
+ }
+ ]
+ },
+ "state": "Uncompleted"
+ },
+ "place_channel_configuration": {
+ "action": {
+ "channels": [
+ [
+ "nixpkgs",
+ "https://nixos.org/channels/nixpkgs-unstable"
+ ]
+ ],
+ "create_file": {
+ "action": {
+ "path": "/home/ana/.nix-channels",
+ "user": null,
+ "group": null,
+ "mode": 436,
+ "buf": "https://nixos.org/channels/nixpkgs-unstable nixpkgs",
+ "force": false
+ },
+ "state": "Uncompleted"
+ }
+ },
+ "state": "Uncompleted"
+ },
+ "place_nix_configuration": {
+ "action": {
+ "create_directory": {
+ "action": {
+ "path": "/etc/nix",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ "create_file": {
+ "action": {
+ "path": "/etc/nix/nix.conf",
+ "user": null,
+ "group": null,
+ "mode": 436,
+ "buf": "# Generated by https://github.com/DeterminateSystems/nix-installer, version 0.1.0-unreleased.\n\n\n\nbuild-users-group = nixbld\n\nexperimental-features = nix-command flakes\n\nauto-optimise-store = true\n\nbash-prompt-prefix = (nix:$name)\\040\n",
+ "force": false
+ },
+ "state": "Uncompleted"
+ }
+ },
+ "state": "Uncompleted"
+ }
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "action": "configure_nix_daemon",
+ "init": "Systemd",
+ "start_daemon": true
+ },
+ "state": "Uncompleted"
+ }
+ ],
+ "planner": {
+ "planner": "linux-multi",
+ "settings": {
+ "channels": [
+ [
+ "nixpkgs",
+ "https://nixos.org/channels/nixpkgs-unstable"
+ ]
+ ],
+ "modify_profile": true,
+ "nix_build_user_count": 32,
+ "nix_build_group_name": "nixbld",
+ "nix_build_group_id": 3000,
+ "nix_build_user_prefix": "nixbld",
+ "nix_build_user_id_base": 3000,
+ "nix_package_url": "https://releases.nixos.org/nix/nix-2.12.0/nix-2.12.0-x86_64-linux.tar.xz",
+ "extra_conf": [],
+ "force": false
+ },
+ "init": {
+ "init": "Systemd",
+ "start_daemon": true
+ }
}
- ],
- "planner": {
- "planner": "linux-multi",
- "settings": {
- "channels": [
- [
- "nixpkgs",
- "https://nixos.org/channels/nixpkgs-unstable"
- ]
- ],
- "modify_profile": true,
- "nix_build_user_count": 32,
- "nix_build_group_name": "nixbld",
- "nix_build_group_id": 3000,
- "nix_build_user_prefix": "nixbld",
- "nix_build_user_id_base": 3000,
- "nix_package_url": "https://releases.nixos.org/nix/nix-2.12.0/nix-2.12.0-x86_64-linux.tar.xz",
- "extra_conf": [],
- "force": false
- }
- }
-}
\ No newline at end of file
+ }
\ No newline at end of file
diff --git a/tests/fixtures/linux/steam-deck.json b/tests/fixtures/linux/steam-deck.json
index e86ad0e..172e5d0 100644
--- a/tests/fixtures/linux/steam-deck.json
+++ b/tests/fixtures/linux/steam-deck.json
@@ -1,661 +1,668 @@
{
- "version": "0.1.0-unreleased",
- "actions": [
- {
- "action": {
- "action": "create_directory",
- "path": "/home/nix",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": true
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "action": "create_file",
- "path": "/etc/systemd/system/nix-directory.service",
- "user": null,
- "group": null,
- "mode": 420,
- "buf": "[Unit]\nDescription=Create a `/nix` directory to be used for bind mounting\nPropagatesStopTo=nix-daemon.service\nPropagatesStopTo=nix.mount\nDefaultDependencies=no\nAfter=grub-recordfail.service\nAfter=steamos-finish-oobe-migration.service\n\n[Service]\nType=oneshot\nExecStart=steamos-readonly disable\nExecStart=mkdir -vp /nix\nExecStart=chmod -v 0755 /nix\nExecStart=chown -v root /nix\nExecStart=chgrp -v root /nix\nExecStart=steamos-readonly enable\nExecStop=steamos-readonly disable\nExecStop=rmdir /nix\nExecStop=steamos-readonly enable\nRemainAfterExit=true\n",
- "force": false
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "action": "create_file",
- "path": "/etc/systemd/system/nix.mount",
- "user": null,
- "group": null,
- "mode": 420,
- "buf": "[Unit]\nDescription=Mount `/home/nix` on `/nix`\nPropagatesStopTo=nix-daemon.service\nPropagatesStopTo=nix-directory.service\nAfter=nix-directory.service\nRequires=nix-directory.service\nConditionPathIsDirectory=/nix\nDefaultDependencies=no\n\n[Mount]\nWhat=/home/nix\nWhere=/nix\nType=none\nDirectoryMode=0755\nOptions=bind\n",
- "force": false
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "action": "create_file",
- "path": "/etc/systemd/system/ensure-symlinked-units-resolve.service",
- "user": null,
- "group": null,
- "mode": 420,
- "buf": "[Unit]\nDescription=Ensure Nix related units which are symlinked resolve\nAfter=nix.mount\nRequires=nix-directory.service\nRequires=nix.mount\nPropagatesStopTo=nix-directory.service\nPropagatesStopTo=nix.mount\nDefaultDependencies=no\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nExecStart=/usr/bin/systemctl daemon-reload\nExecStart=/usr/bin/systemctl restart --no-block sockets.target timers.target multi-user.target\n\n[Install]\nWantedBy=sysinit.target\n",
- "force": false
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "action": "start_systemd_unit",
- "unit": "ensure-symlinked-units-resolve.service"
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "action": "provision_nix",
- "fetch_nix": {
- "action": {
- "url": "https://releases.nixos.org/nix/nix-2.12.0/nix-2.12.0-x86_64-linux.tar.xz",
- "dest": "/nix/temp-install-dir"
- },
- "state": "Uncompleted"
+ "version": "0.1.0-unreleased",
+ "actions": [
+ {
+ "action": {
+ "action": "create_directory",
+ "path": "/home/nix",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": true
},
- "create_users_and_group": {
- "action": {
- "nix_build_user_count": 32,
- "nix_build_group_name": "nixbld",
- "nix_build_group_id": 3000,
- "nix_build_user_prefix": "nixbld",
- "nix_build_user_id_base": 3000,
- "create_group": {
- "action": {
- "name": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "action": "create_file",
+ "path": "/etc/systemd/system/nix-directory.service",
+ "user": null,
+ "group": null,
+ "mode": 420,
+ "buf": "[Unit]\nDescription=Create a `/nix` directory to be used for bind mounting\nPropagatesStopTo=nix-daemon.service\nPropagatesStopTo=nix.mount\nDefaultDependencies=no\nAfter=grub-recordfail.service\nAfter=steamos-finish-oobe-migration.service\n\n[Service]\nType=oneshot\nExecStart=steamos-readonly disable\nExecStart=mkdir -vp /nix\nExecStart=chmod -v 0755 /nix\nExecStart=chown -v root /nix\nExecStart=chgrp -v root /nix\nExecStart=steamos-readonly enable\nExecStop=steamos-readonly disable\nExecStop=rmdir /nix\nExecStop=steamos-readonly enable\nRemainAfterExit=true\n",
+ "force": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "action": "create_file",
+ "path": "/etc/systemd/system/nix.mount",
+ "user": null,
+ "group": null,
+ "mode": 420,
+ "buf": "[Unit]\nDescription=Mount `/home/nix` on `/nix`\nPropagatesStopTo=nix-daemon.service\nPropagatesStopTo=nix-directory.service\nAfter=nix-directory.service\nRequires=nix-directory.service\nConditionPathIsDirectory=/nix\nDefaultDependencies=no\n\n[Mount]\nWhat=/home/nix\nWhere=/nix\nType=none\nDirectoryMode=0755\nOptions=bind\n",
+ "force": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "action": "create_file",
+ "path": "/etc/systemd/system/ensure-symlinked-units-resolve.service",
+ "user": null,
+ "group": null,
+ "mode": 420,
+ "buf": "[Unit]\nDescription=Ensure Nix related units which are symlinked resolve\nAfter=nix.mount\nRequires=nix-directory.service\nRequires=nix.mount\nPropagatesStopTo=nix-directory.service\nPropagatesStopTo=nix.mount\nDefaultDependencies=no\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nExecStart=/usr/bin/systemctl daemon-reload\nExecStart=/usr/bin/systemctl restart --no-block sockets.target timers.target multi-user.target\n\n[Install]\nWantedBy=sysinit.target\n",
+ "force": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "action": "start_systemd_unit",
+ "unit": "ensure-symlinked-units-resolve.service"
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "action": "provision_nix",
+ "fetch_nix": {
+ "action": {
+ "url": "https://releases.nixos.org/nix/nix-2.12.0/nix-2.12.0-x86_64-linux.tar.xz",
+ "dest": "/nix/temp-install-dir"
},
- "create_users": [
- {
- "action": {
- "name": "nixbld0",
- "uid": 3000,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld1",
- "uid": 3001,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld2",
- "uid": 3002,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld3",
- "uid": 3003,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld4",
- "uid": 3004,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld5",
- "uid": 3005,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld6",
- "uid": 3006,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld7",
- "uid": 3007,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld8",
- "uid": 3008,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld9",
- "uid": 3009,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld10",
- "uid": 3010,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld11",
- "uid": 3011,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld12",
- "uid": 3012,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld13",
- "uid": 3013,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld14",
- "uid": 3014,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld15",
- "uid": 3015,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld16",
- "uid": 3016,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld17",
- "uid": 3017,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld18",
- "uid": 3018,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld19",
- "uid": 3019,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld20",
- "uid": 3020,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld21",
- "uid": 3021,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld22",
- "uid": 3022,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld23",
- "uid": 3023,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld24",
- "uid": 3024,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld25",
- "uid": 3025,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld26",
- "uid": 3026,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld27",
- "uid": 3027,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld28",
- "uid": 3028,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld29",
- "uid": 3029,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld30",
- "uid": 3030,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "name": "nixbld31",
- "uid": 3031,
- "groupname": "nixbld",
- "gid": 3000
- },
- "state": "Uncompleted"
- }
- ]
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- "create_nix_tree": {
- "action": {
- "create_directories": [
- {
+ "create_users_and_group": {
+ "action": {
+ "nix_build_user_count": 32,
+ "nix_build_group_name": "nixbld",
+ "nix_build_group_id": 3000,
+ "nix_build_user_prefix": "nixbld",
+ "nix_build_user_id_base": 3000,
+ "create_group": {
"action": {
- "path": "/nix/var",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ "name": "nixbld",
+ "gid": 3000
},
"state": "Uncompleted"
},
- {
- "action": {
- "path": "/nix/var/log",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ "create_users": [
+ {
+ "action": {
+ "name": "nixbld0",
+ "uid": 3000,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/log/nix",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld1",
+ "uid": 3001,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/log/nix/drvs",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld2",
+ "uid": 3002,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld3",
+ "uid": 3003,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix/db",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld4",
+ "uid": 3004,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix/gcroots",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld5",
+ "uid": 3005,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix/gcroots/per-user",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld6",
+ "uid": 3006,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix/profiles",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld7",
+ "uid": 3007,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix/profiles/per-user",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld8",
+ "uid": 3008,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix/temproots",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld9",
+ "uid": 3009,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix/userpool",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld10",
+ "uid": 3010,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/nix/var/nix/daemon-socket",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
+ {
+ "action": {
+ "name": "nixbld11",
+ "uid": 3011,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- }
- ]
- },
- "state": "Uncompleted"
- },
- "move_unpacked_nix": {
- "action": {
- "src": "/nix/temp-install-dir"
- },
- "state": "Uncompleted"
- }
- },
- "state": "Uncompleted"
- },
- {
- "action": {
- "action": "configure_nix",
- "setup_default_profile": {
- "action": {
- "channels": [
- "nixpkgs"
- ]
- },
- "state": "Uncompleted"
- },
- "configure_shell_profile": {
- "action": {
- "create_directories": [],
- "create_or_insert_into_files": [
- {
- "action": {
- "path": "/etc/bashrc",
- "user": null,
- "group": null,
- "mode": 493,
- "buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
- "position": "Beginning"
+ {
+ "action": {
+ "name": "nixbld12",
+ "uid": 3012,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/etc/profile.d/nix.sh",
- "user": null,
- "group": null,
- "mode": 493,
- "buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
- "position": "Beginning"
+ {
+ "action": {
+ "name": "nixbld13",
+ "uid": 3013,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/etc/zshenv",
- "user": null,
- "group": null,
- "mode": 493,
- "buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
- "position": "Beginning"
+ {
+ "action": {
+ "name": "nixbld14",
+ "uid": 3014,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- },
- {
- "action": {
- "path": "/etc/bash.bashrc",
- "user": null,
- "group": null,
- "mode": 493,
- "buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
- "position": "Beginning"
+ {
+ "action": {
+ "name": "nixbld15",
+ "uid": 3015,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
- }
- ]
- },
- "state": "Uncompleted"
- },
- "place_channel_configuration": {
- "action": {
- "channels": [
- [
- "nixpkgs",
- "https://nixos.org/channels/nixpkgs-unstable"
+ {
+ "action": {
+ "name": "nixbld16",
+ "uid": 3016,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld17",
+ "uid": 3017,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld18",
+ "uid": 3018,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld19",
+ "uid": 3019,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld20",
+ "uid": 3020,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld21",
+ "uid": 3021,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld22",
+ "uid": 3022,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld23",
+ "uid": 3023,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld24",
+ "uid": 3024,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld25",
+ "uid": 3025,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld26",
+ "uid": 3026,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld27",
+ "uid": 3027,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld28",
+ "uid": 3028,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld29",
+ "uid": 3029,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld30",
+ "uid": 3030,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "name": "nixbld31",
+ "uid": 3031,
+ "groupname": "nixbld",
+ "gid": 3000
+ },
+ "state": "Uncompleted"
+ }
]
- ],
- "create_file": {
- "action": {
- "path": "/root/.nix-channels",
- "user": null,
- "group": null,
- "mode": 436,
- "buf": "https://nixos.org/channels/nixpkgs-unstable nixpkgs",
- "force": false
- },
- "state": "Uncompleted"
- }
- },
- "state": "Uncompleted"
- },
- "place_nix_configuration": {
- "action": {
- "create_directory": {
- "action": {
- "path": "/etc/nix",
- "user": null,
- "group": null,
- "mode": 493,
- "force_prune_on_revert": false
- },
- "state": "Uncompleted"
},
- "create_file": {
- "action": {
- "path": "/etc/nix/nix.conf",
- "user": null,
- "group": null,
- "mode": 436,
- "buf": "\n\nbuild-users-group = nixbld\n\nexperimental-features = nix-command flakes\n\nauto-optimise-store = true\n",
- "force": false
- },
- "state": "Uncompleted"
- }
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
+ "create_nix_tree": {
+ "action": {
+ "create_directories": [
+ {
+ "action": {
+ "path": "/nix/var",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/log",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/log/nix",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/log/nix/drvs",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix/db",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix/gcroots",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix/gcroots/per-user",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix/profiles",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix/profiles/per-user",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix/temproots",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix/userpool",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/nix/var/nix/daemon-socket",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ }
+ ]
+ },
+ "state": "Uncompleted"
+ },
+ "move_unpacked_nix": {
+ "action": {
+ "src": "/nix/temp-install-dir"
+ },
+ "state": "Uncompleted"
+ }
},
- "configure_nix_daemon_service": {
- "action": {},
- "state": "Uncompleted"
- }
+ "state": "Uncompleted"
},
- "state": "Uncompleted"
+ {
+ "action": {
+ "action": "configure_nix",
+ "setup_default_profile": {
+ "action": {
+ "channels": [
+ [
+ "nixpkgs",
+ "https://nixos.org/channels/nixpkgs-unstable"
+ ]
+ ]
+ },
+ "state": "Uncompleted"
+ },
+ "configure_shell_profile": {
+ "action": {
+ "create_directories": [],
+ "create_or_insert_into_files": [
+ {
+ "action": {
+ "path": "/etc/bashrc",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
+ "position": "Beginning"
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/etc/profile.d/nix.sh",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
+ "position": "Beginning"
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/etc/zshenv",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
+ "position": "Beginning"
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "path": "/etc/bash.bashrc",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
+ "position": "Beginning"
+ },
+ "state": "Uncompleted"
+ }
+ ]
+ },
+ "state": "Uncompleted"
+ },
+ "place_channel_configuration": {
+ "action": {
+ "channels": [
+ [
+ "nixpkgs",
+ "https://nixos.org/channels/nixpkgs-unstable"
+ ]
+ ],
+ "create_file": {
+ "action": {
+ "path": "/home/ana/.nix-channels",
+ "user": null,
+ "group": null,
+ "mode": 436,
+ "buf": "https://nixos.org/channels/nixpkgs-unstable nixpkgs",
+ "force": false
+ },
+ "state": "Uncompleted"
+ }
+ },
+ "state": "Uncompleted"
+ },
+ "place_nix_configuration": {
+ "action": {
+ "create_directory": {
+ "action": {
+ "path": "/etc/nix",
+ "user": null,
+ "group": null,
+ "mode": 493,
+ "force_prune_on_revert": false
+ },
+ "state": "Uncompleted"
+ },
+ "create_file": {
+ "action": {
+ "path": "/etc/nix/nix.conf",
+ "user": null,
+ "group": null,
+ "mode": 436,
+ "buf": "# Generated by https://github.com/DeterminateSystems/nix-installer, version 0.1.0-unreleased.\n\n\n\nbuild-users-group = nixbld\n\nexperimental-features = nix-command flakes\n\nauto-optimise-store = true\n\nbash-prompt-prefix = (nix:$name)\\040\n",
+ "force": false
+ },
+ "state": "Uncompleted"
+ }
+ },
+ "state": "Uncompleted"
+ }
+ },
+ "state": "Uncompleted"
+ },
+ {
+ "action": {
+ "action": "configure_nix_daemon",
+ "init": "Systemd",
+ "start_daemon": true
+ },
+ "state": "Uncompleted"
+ }
+ ],
+ "planner": {
+ "planner": "steam-deck",
+ "persistence": "/home/nix",
+ "settings": {
+ "channels": [
+ [
+ "nixpkgs",
+ "https://nixos.org/channels/nixpkgs-unstable"
+ ]
+ ],
+ "modify_profile": true,
+ "nix_build_user_count": 32,
+ "nix_build_group_name": "nixbld",
+ "nix_build_group_id": 3000,
+ "nix_build_user_prefix": "nixbld",
+ "nix_build_user_id_base": 3000,
+ "nix_package_url": "https://releases.nixos.org/nix/nix-2.12.0/nix-2.12.0-x86_64-linux.tar.xz",
+ "extra_conf": [],
+ "force": false
+ }
}
- ],
- "planner": {
- "planner": "steam-deck",
- "persistence": "/home/nix",
- "settings": {
- "channels": [
- [
- "nixpkgs",
- "https://nixos.org/channels/nixpkgs-unstable"
- ]
- ],
- "modify_profile": true,
- "nix_build_user_count": 32,
- "nix_build_group_name": "nixbld",
- "nix_build_group_id": 3000,
- "nix_build_user_prefix": "nixbld",
- "nix_build_user_id_base": 3000,
- "nix_package_url": "https://releases.nixos.org/nix/nix-2.12.0/nix-2.12.0-x86_64-linux.tar.xz",
- "extra_conf": [],
- "force": false
- }
- }
-}
\ No newline at end of file
+ }
\ No newline at end of file
diff --git a/tests/plan.rs b/tests/plan.rs
index 05653de..bf5d8e2 100644
--- a/tests/plan.rs
+++ b/tests/plan.rs
@@ -1,11 +1,15 @@
use nix_installer::InstallPlan;
+#[cfg(target_os = "linux")]
const LINUX_MULTI: &str = include_str!("./fixtures/linux/linux-multi.json");
+#[cfg(target_os = "linux")]
const STEAM_DECK: &str = include_str!("./fixtures/linux/steam-deck.json");
+#[cfg(target_os = "macos")]
const DARWIN_MULTI: &str = include_str!("./fixtures/darwin/darwin-multi.json");
// Ensure existing plans still parse
// If this breaks and you need to update the fixture, disable these tests, bump `nix_installer` to a new version, and update the plans.
+#[cfg(target_os = "linux")]
#[test]
fn plan_compat_linux_multi() -> eyre::Result<()> {
let _: InstallPlan = serde_json::from_str(LINUX_MULTI)?;
@@ -14,6 +18,7 @@ fn plan_compat_linux_multi() -> eyre::Result<()> {
// Ensure existing plans still parse
// If this breaks and you need to update the fixture, disable these tests, bump `nix_installer` to a new version, and update the plans.
+#[cfg(target_os = "linux")]
#[test]
fn plan_compat_steam_deck() -> eyre::Result<()> {
let _: InstallPlan = serde_json::from_str(STEAM_DECK)?;
@@ -22,6 +27,7 @@ fn plan_compat_steam_deck() -> eyre::Result<()> {
// Ensure existing plans still parse
// If this breaks and you need to update the fixture, disable these tests, bump `nix_installer` to a new version, and update the plans.
+#[cfg(target_os = "macos")]
#[test]
fn plan_compat_darwin_multi() -> eyre::Result<()> {
let _: InstallPlan = serde_json::from_str(DARWIN_MULTI)?;
diff --git a/tests/windows/test-wsl.ps1 b/tests/windows/test-wsl.ps1
new file mode 100644
index 0000000..8eae4fd
--- /dev/null
+++ b/tests/windows/test-wsl.ps1
@@ -0,0 +1,75 @@
+param([switch]$Systemd = $false)
+Set-StrictMode -Version Latest
+$ErrorActionPreference = "Stop"
+
+
+# 22.04 https://cloud-images.ubuntu.com/wsl/jammy/current/
+$url = "https://cloud-images.ubuntu.com/wsl/jammy/current/ubuntu-jammy-wsl-amd64-wsl.rootfs.tar.gz"
+$File = "ubuntu-jammy-wsl-amd64-wsl.rootfs.tar.gz"
+$Name = "ubuntu-jammy"
+
+
+$TemporaryDirectory = "$HOME/nix-installer-wsl-tests-temp"
+$Image = "$TemporaryDirectory\$File"
+if (!(Test-Path -Path $Image)) {
+ Write-Output "Fetching $File to $Image..."
+ New-Item $TemporaryDirectory -ItemType Directory | Out-Null
+ Invoke-WebRequest -Uri "https://cloud-images.ubuntu.com/wsl/jammy/current/ubuntu-jammy-wsl-amd64-wsl.rootfs.tar.gz" -OutFile $Image
+} else {
+ Write-Output "Found existing $Image..."
+}
+
+$DistroName = "nix-installer-test-$Name"
+$InstallRoot = "$TemporaryDirectory\wsl-$Name"
+Write-Output "Creating WSL distribution $DistroName from $Image at $InstallRoot..."
+wsl --import $DistroName $InstallRoot $Image
+if ($LastExitCode -ne 0) {
+ exit $LastExitCode
+}
+
+Write-Output "Preparing $DistroName for nix-installer..."
+wsl --distribution $DistroName bash --login -c "apt update --quiet"
+if ($LastExitCode -ne 0) {
+ exit $LastExitCode
+}
+wsl --distribution $DistroName bash --login -c "apt install --quiet --yes curl build-essential"
+if ($LastExitCode -ne 0) {
+ exit $LastExitCode
+}
+wsl --distribution $DistroName bash --login -c "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --quiet"
+if ($LastExitCode -ne 0) {
+ exit $LastExitCode
+}
+
+if ($Systemd) {
+ $wslConf = "[boot]`nsystemd=true"
+ New-Item -Path "\\wsl$\$DistroName\etc\wsl.conf" -ItemType "file" -Value $wslConf
+ wsl --shutdown
+ if ($LastExitCode -ne 0) {
+ exit $LastExitCode
+ }
+}
+
+Write-Output "Building and runnings nix-installer in $DistroName..."
+Copy-Item -Recurse "$PSScriptRoot\..\.." -Destination "\\wsl$\$DistroName\nix-installer"
+$MaybeInitChoice = switch ($Systemd) {
+ $true { "" }
+ $false { "--init none" }
+}
+wsl --distribution $DistroName bash --login -c "/root/.cargo/bin/cargo run --quiet --manifest-path /nix-installer/Cargo.toml -- install linux-multi --no-confirm $MaybeInitChoice"
+if ($LastExitCode -ne 0) {
+ exit $LastExitCode
+}
+
+Write-Output "Testing installed Nix on $DistroName..."
+wsl --distribution $DistroName bash --login -c "nix run nixpkgs#hello"
+if ($LastExitCode -ne 0) {
+ exit $LastExitCode
+}
+
+Write-Output "Unregistering $DistroName and removing $InstallRoot..."
+wsl --unregister $DistroName
+if ($LastExitCode -ne 0) {
+ exit $LastExitCode
+}
+Remove-Item $InstallRoot
\ No newline at end of file