forked from lix-project/lix-installer
Add action & Tune Tracing (#119)
* Add action * Checkout so we have actions.yml * yaml poking * Handle GITHUB_TOKEN * Don't ask github to do templating, use directives for logging * Missing changes * Fix build error * Fix yaml even more * Add shell command * Add a wait on the socket again * Print some debugging * Use more correct env vars * Correct install url logic * Use different style for inputs * Fix yaml errror * Tweak around local-root * provision nix-install.sh as well * Use nix-install.sh path directory in NIX_INSTALL_URL * Tweak variables to hopefully work * Call it BINARY_ROOT instead * Add exec output * Set no-confirm * no echo * Add token to workflow * Set no-confirm properly * Add no-confirm back for uninstall * Correct some env and vars * CreateDirectory respects existing symlink * Add a few more checks to the CI * pass valid yaml... * Slightly more aggressive cleanup of /nix * Ensure steam-deck cleans /home/nix * Add steam-deck check for persistence * Canonicalize steam-deck persistence * Ensure absolute path * Inverted logic sad * python3 on mac * Add readme info and fix a extra-conf mistype * Add unsaved changes * More fine grained trace logging * Restore spans we lost in refactor * BuiltinPlanner can accept settings * Reflect feedback * Push actually working code hopefully this time * Speeling
This commit is contained in:
parent
cc3521a798
commit
c4274c93fb
202
.github/workflows/ci.yml
vendored
202
.github/workflows/ci.yml
vendored
|
@ -5,14 +5,6 @@ on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
|
|
||||||
env:
|
|
||||||
NIX_INSTALL_FORCE_ALLOW_HTTP: "1"
|
|
||||||
NIX_INSTALL_UPDATE_ROOT: "http://0.0.0.0:8000"
|
|
||||||
RUST_BACKTRACE: "full"
|
|
||||||
HARMONIC_VERBOSITY: "2"
|
|
||||||
HARMONIC_NO_CONFIRM: "true"
|
|
||||||
HARMONIC_LOGGER: "pretty"
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lints:
|
lints:
|
||||||
name: Lints
|
name: Lints
|
||||||
|
@ -37,12 +29,6 @@ jobs:
|
||||||
run: nix develop --store ~/.ci-store --command check-nixpkgs-fmt
|
run: nix develop --store ~/.ci-store --command check-nixpkgs-fmt
|
||||||
- name: Check EditorConfig conformance
|
- name: Check EditorConfig conformance
|
||||||
run: nix develop --store ~/.ci-store --command check-editorconfig
|
run: nix develop --store ~/.ci-store --command check-editorconfig
|
||||||
- name: Create artifact for `nix-install.sh`
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: nix-install
|
|
||||||
path: |
|
|
||||||
nix-install.sh
|
|
||||||
|
|
||||||
build-x86_64-linux:
|
build-x86_64-linux:
|
||||||
name: Build x86_64 Linux
|
name: Build x86_64 Linux
|
||||||
|
@ -102,29 +88,54 @@ jobs:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
needs: [build-x86_64-linux, lints]
|
needs: [build-x86_64-linux, lints]
|
||||||
steps:
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
- run: sudo apt install fish zsh
|
- run: sudo apt install fish zsh
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: harmonic-x86_64-linux
|
name: harmonic-x86_64-linux
|
||||||
- uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: nix-install
|
|
||||||
- name: Move & set executable
|
- name: Move & set executable
|
||||||
run: |
|
run: |
|
||||||
chmod +x ./harmonic
|
chmod +x ./harmonic
|
||||||
mv harmonic harmonic-x86_64-linux
|
mkdir install-root
|
||||||
|
cp nix-install.sh install-root/nix-install.sh
|
||||||
|
mv harmonic install-root/harmonic-x86_64-linux
|
||||||
- name: Initial install
|
- name: Initial install
|
||||||
run: |
|
uses: ./
|
||||||
python -m http.server --bind 0.0.0.0 8000 &
|
with:
|
||||||
timeout 20 bash -c 'until printf "" 2>>/dev/null >>/dev/tcp/localhost/8000; do echo "Waiting for server..."; sleep 1; done'
|
local-root: install-root/
|
||||||
curl -L http://0.0.0.0:8000/nix-install.sh | sh -s -- install linux-multi --extra-conf "access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}"
|
logger: pretty
|
||||||
|
log-directives: harmonic=trace
|
||||||
|
backtrace: full
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Initial uninstall (without a `nix run` first)
|
- name: Initial uninstall (without a `nix run` first)
|
||||||
run: sudo -E /nix/harmonic uninstall
|
run: sudo -E /nix/harmonic uninstall
|
||||||
- name: Repeated install
|
env:
|
||||||
|
HARMONIC_NO_CONFIRM: true
|
||||||
|
HARMONIC_LOGGER: pretty
|
||||||
|
HARMONIC_LOG_DIRECTIVES: harmonic=trace
|
||||||
|
RUST_BACKTRACE: full
|
||||||
|
- name: Ensure `nix` is removed
|
||||||
run: |
|
run: |
|
||||||
python -m http.server --bind 0.0.0.0 8000 &
|
if systemctl is-active nix-daemon.socket; then
|
||||||
timeout 20 bash -c 'until printf "" 2>>/dev/null >>/dev/tcp/localhost/8000; do echo "Waiting for server..."; sleep 1; done'
|
echo "nix-daemon.socket was still running"
|
||||||
curl -L http://0.0.0.0:8000/nix-install.sh | sh -s -- install linux-multi --extra-conf "access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}"
|
exit 1
|
||||||
|
fi
|
||||||
|
if systemctl is-active nix-daemon.service; then
|
||||||
|
echo "nix-daemon.service was still running"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -e /nix ]; then
|
||||||
|
echo "/nix exists"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
- name: Repeated install
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
local-root: install-root/
|
||||||
|
logger: pretty
|
||||||
|
log-directives: harmonic=trace
|
||||||
|
backtrace: full
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: echo $PATH
|
- name: echo $PATH
|
||||||
run: echo $PATH
|
run: echo $PATH
|
||||||
- name: Test `nix` with `$GITHUB_PATH`
|
- name: Test `nix` with `$GITHUB_PATH`
|
||||||
|
@ -148,23 +159,42 @@ jobs:
|
||||||
shell: fish --login {0}
|
shell: fish --login {0}
|
||||||
- name: Repeated uninstall
|
- name: Repeated uninstall
|
||||||
run: sudo -E /nix/harmonic uninstall
|
run: sudo -E /nix/harmonic uninstall
|
||||||
|
env:
|
||||||
|
HARMONIC_NO_CONFIRM: true
|
||||||
|
HARMONIC_LOGGER: pretty
|
||||||
|
HARMONIC_LOG_DIRECTIVES: harmonic=trace
|
||||||
|
RUST_BACKTRACE: full
|
||||||
|
- name: Ensure `nix` is removed
|
||||||
|
run: |
|
||||||
|
if systemctl is-active nix-daemon.socket; then
|
||||||
|
echo "nix-daemon.socket was still running"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if systemctl is-active nix-daemon.service; then
|
||||||
|
echo "nix-daemon.service was still running"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -e /nix ]; then
|
||||||
|
echo "/nix exists"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
run-steam-deck:
|
run-steam-deck:
|
||||||
name: Run Steam Deck (mock)
|
name: Run Steam Deck (mock)
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
needs: [build-x86_64-linux, lints]
|
needs: [build-x86_64-linux, lints]
|
||||||
steps:
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
- run: sudo apt install fish zsh
|
- run: sudo apt install fish zsh
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: harmonic-x86_64-linux
|
name: harmonic-x86_64-linux
|
||||||
- uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: nix-install
|
|
||||||
- name: Move & set executable
|
- name: Move & set executable
|
||||||
run: |
|
run: |
|
||||||
chmod +x ./harmonic
|
chmod +x ./harmonic
|
||||||
mv harmonic harmonic-x86_64-linux
|
mkdir install-root
|
||||||
|
cp nix-install.sh install-root/nix-install.sh
|
||||||
|
mv harmonic install-root/harmonic-x86_64-linux
|
||||||
- name: Make the CI look like a steam deck
|
- name: Make the CI look like a steam deck
|
||||||
run: |
|
run: |
|
||||||
mkdir -p ~/bin
|
mkdir -p ~/bin
|
||||||
|
@ -172,17 +202,50 @@ jobs:
|
||||||
sudo chmod +x /bin/steamos-readonly
|
sudo chmod +x /bin/steamos-readonly
|
||||||
sudo useradd -m deck
|
sudo useradd -m deck
|
||||||
- name: Initial install
|
- name: Initial install
|
||||||
run: |
|
uses: ./
|
||||||
python -m http.server --bind 0.0.0.0 8000 &
|
with:
|
||||||
timeout 20 bash -c 'until printf "" 2>>/dev/null >>/dev/tcp/localhost/8000; do echo "Waiting for server..."; sleep 1; done'
|
local-root: install-root/
|
||||||
curl -L http://0.0.0.0:8000/nix-install.sh | sh -s -- install steam-deck --persistence `pwd`/ci-test-nix --extra-conf "access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}"
|
logger: pretty
|
||||||
|
log-directives: harmonic=trace
|
||||||
|
backtrace: full
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
planner: steam-deck
|
||||||
|
extra-args: --persistence /home/runner/.ci-test-nix-home
|
||||||
- name: Initial uninstall (without a `nix run` first)
|
- name: Initial uninstall (without a `nix run` first)
|
||||||
run: sudo -E /nix/harmonic uninstall
|
run: sudo -E /nix/harmonic uninstall
|
||||||
- name: Repeated install
|
env:
|
||||||
|
HARMONIC_NO_CONFIRM: true
|
||||||
|
HARMONIC_LOGGER: pretty
|
||||||
|
HARMONIC_LOG_DIRECTIVES: harmonic=trace
|
||||||
|
RUST_BACKTRACE: full
|
||||||
|
- name: Ensure `nix` is removed
|
||||||
run: |
|
run: |
|
||||||
python -m http.server --bind 0.0.0.0 8000 &
|
if systemctl is-active nix-daemon.socket; then
|
||||||
timeout 20 bash -c 'until printf "" 2>>/dev/null >>/dev/tcp/localhost/8000; do echo "Waiting for server..."; sleep 1; done'
|
echo "nix-daemon.socket was still running"
|
||||||
curl -L http://0.0.0.0:8000/nix-install.sh | sh -s -- install steam-deck --persistence `pwd`/ci-test-nix --extra-conf "access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}"
|
exit 1
|
||||||
|
fi
|
||||||
|
if systemctl is-active nix-daemon.service; then
|
||||||
|
echo "nix-daemon.service was still running"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -e /nix ]; then
|
||||||
|
echo "/nix exists"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -e /home/runner/.ci-test-nix-home ]; then
|
||||||
|
echo "/home/runner/.ci-test-nix-home exists"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
- name: Repeated install
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
local-root: install-root/
|
||||||
|
logger: pretty
|
||||||
|
log-directives: harmonic=trace
|
||||||
|
backtrace: full
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
planner: steam-deck
|
||||||
|
extra-args: --persistence /home/runner/.ci-test-nix-home
|
||||||
- name: echo $PATH
|
- name: echo $PATH
|
||||||
run: echo $PATH
|
run: echo $PATH
|
||||||
- name: Test `nix` with `$GITHUB_PATH`
|
- name: Test `nix` with `$GITHUB_PATH`
|
||||||
|
@ -206,6 +269,29 @@ jobs:
|
||||||
shell: fish --login {0}
|
shell: fish --login {0}
|
||||||
- name: Repeated uninstall
|
- name: Repeated uninstall
|
||||||
run: sudo -E /nix/harmonic uninstall
|
run: sudo -E /nix/harmonic uninstall
|
||||||
|
env:
|
||||||
|
HARMONIC_NO_CONFIRM: true
|
||||||
|
HARMONIC_LOGGER: pretty
|
||||||
|
HARMONIC_LOG_DIRECTIVES: harmonic=trace
|
||||||
|
RUST_BACKTRACE: full
|
||||||
|
- name: Ensure `nix` is removed
|
||||||
|
run: |
|
||||||
|
if systemctl is-active nix-daemon.socket; then
|
||||||
|
echo "nix-daemon.socket was still running"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if systemctl is-active nix-daemon.service; then
|
||||||
|
echo "nix-daemon.service was still running"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -e /nix ]; then
|
||||||
|
echo "/nix exists"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -e /home/runner/.ci-test-nix-home ]; then
|
||||||
|
echo "/home/runner/.ci-test-nix-home exists"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
build-x86_64-darwin:
|
build-x86_64-darwin:
|
||||||
name: Build x86_64 Darwin
|
name: Build x86_64 Darwin
|
||||||
|
@ -231,29 +317,40 @@ jobs:
|
||||||
runs-on: macos-12
|
runs-on: macos-12
|
||||||
needs: [build-x86_64-darwin, lints]
|
needs: [build-x86_64-darwin, lints]
|
||||||
steps:
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
- run: brew install fish coreutils
|
- run: brew install fish coreutils
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: harmonic-x86_64-darwin
|
name: harmonic-x86_64-darwin
|
||||||
- uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: nix-install
|
|
||||||
- name: Move & set executable
|
- name: Move & set executable
|
||||||
run: |
|
run: |
|
||||||
chmod +x ./harmonic
|
chmod +x ./harmonic
|
||||||
mv harmonic harmonic-x86_64-darwin
|
mkdir install-root
|
||||||
|
cp nix-install.sh install-root/nix-install.sh
|
||||||
|
mv harmonic install-root/harmonic-x86_64-darwin
|
||||||
- name: Initial install
|
- name: Initial install
|
||||||
run: |
|
uses: ./
|
||||||
python3 -m http.server --bind 0.0.0.0 8000 &
|
with:
|
||||||
gtimeout 20 bash -c 'until printf "" 2>>/dev/null >>/dev/tcp/localhost/8000; do echo "Waiting for server..."; sleep 1; done'
|
local-root: install-root/
|
||||||
curl -L http://0.0.0.0:8000/nix-install.sh | sh -s -- install darwin-multi --extra-conf "access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}"
|
logger: pretty
|
||||||
|
log-directives: harmonic=trace
|
||||||
|
backtrace: full
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Initial uninstall (without a `nix run` first)
|
- name: Initial uninstall (without a `nix run` first)
|
||||||
run: sudo -E /nix/harmonic uninstall
|
run: sudo -E /nix/harmonic uninstall
|
||||||
|
env:
|
||||||
|
HARMONIC_NO_CONFIRM: true
|
||||||
|
HARMONIC_LOGGER: pretty
|
||||||
|
HARMONIC_LOG_DIRECTIVES: harmonic=trace
|
||||||
|
RUST_BACKTRACE: full
|
||||||
- name: Repeated install
|
- name: Repeated install
|
||||||
run: |
|
uses: ./
|
||||||
python -m http.server --bind 0.0.0.0 8000 &
|
with:
|
||||||
timeout 20 bash -c 'until printf "" 2>>/dev/null >>/dev/tcp/localhost/8000; do echo "Waiting for server..."; sleep 1; done'
|
local-root: install-root/
|
||||||
curl -L http://0.0.0.0:8000/nix-install.sh | sh -s -- install darwin-multi --extra-conf "access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}"
|
logger: pretty
|
||||||
|
log-directives: harmonic=trace
|
||||||
|
backtrace: full
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: echo $PATH
|
- name: echo $PATH
|
||||||
run: echo $PATH
|
run: echo $PATH
|
||||||
- name: Test `nix` with `$GITHUB_PATH`
|
- name: Test `nix` with `$GITHUB_PATH`
|
||||||
|
@ -277,4 +374,9 @@ jobs:
|
||||||
shell: fish --login {0}
|
shell: fish --login {0}
|
||||||
- name: Repeated uninstall
|
- name: Repeated uninstall
|
||||||
run: sudo -E /nix/harmonic uninstall
|
run: sudo -E /nix/harmonic uninstall
|
||||||
|
env:
|
||||||
|
HARMONIC_NO_CONFIRM: true
|
||||||
|
HARMONIC_LOGGER: pretty
|
||||||
|
HARMONIC_LOG_DIRECTIVES: harmonic=trace
|
||||||
|
RUST_BACKTRACE: full
|
||||||
|
|
24
README.md
24
README.md
|
@ -174,3 +174,27 @@ Documentation is also available via `nix` build:
|
||||||
nix build github:DeterminateSystems/harmonic#harmonic.doc
|
nix build github:DeterminateSystems/harmonic#harmonic.doc
|
||||||
firefox result-doc/harmonic/index.html
|
firefox result-doc/harmonic/index.html
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## As a Github Action
|
||||||
|
|
||||||
|
You can use Harmonic as a Github action like so:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lints:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Install Nix
|
||||||
|
uses: DeterminateSystems/harmonic@main
|
||||||
|
with:
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
- name: Run `nix build`
|
||||||
|
run: nix build .
|
||||||
|
```
|
199
action.yml
Normal file
199
action.yml
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
name: Harmonic
|
||||||
|
description: Install Nix
|
||||||
|
inputs:
|
||||||
|
planner:
|
||||||
|
description: A planner to use
|
||||||
|
required: false
|
||||||
|
extra-args:
|
||||||
|
description: Extra args to pass to the planner (prefer using structured `with:` arguments unless using a custom planner!)
|
||||||
|
required: false
|
||||||
|
github-token:
|
||||||
|
description: A Github Token so that authenticated requests can be made (set this to `secrets.GITHUB_TOKEN`)
|
||||||
|
channels:
|
||||||
|
description: Channel(s) to add (eg `nixpkgs=https://nixos.org/channels/nixpkgs-unstable`)
|
||||||
|
required: false
|
||||||
|
modify-profile:
|
||||||
|
description: Modify the user profile to automatically load nix
|
||||||
|
required: false
|
||||||
|
daemon-user-count:
|
||||||
|
description: Number of build users to create
|
||||||
|
required: false
|
||||||
|
nix-build-group-name:
|
||||||
|
description: The Nix build group name
|
||||||
|
required: false
|
||||||
|
nix-build-group-id:
|
||||||
|
description: The Nix build group GID
|
||||||
|
required: false
|
||||||
|
nix-build-user-prefix:
|
||||||
|
description: The Nix build user prefix (user numbers will be postfixed)
|
||||||
|
required: false
|
||||||
|
nix-build-user-base:
|
||||||
|
description: The Nix build user base UID (ascending)
|
||||||
|
required: false
|
||||||
|
nix-package-url:
|
||||||
|
description: The Nix package URL
|
||||||
|
required: false
|
||||||
|
extra-conf:
|
||||||
|
description: Extra configuration lines for `/etc/nix.conf` (includes `access-tokens` with `secrets.GITHUB_TOKEN` automatically if `github-token` is set)
|
||||||
|
required: false
|
||||||
|
mac-encrypt:
|
||||||
|
description: Force encryption on the volume (Mac only)
|
||||||
|
required: false
|
||||||
|
mac-case-sensitive:
|
||||||
|
description: Use a case sensitive volume (Mac only)
|
||||||
|
required: false
|
||||||
|
mac-volume-label:
|
||||||
|
description: The label for the created APFS volume (Mac only)
|
||||||
|
required: false
|
||||||
|
mac-root-disk:
|
||||||
|
description: The root disk of the target (Mac only)
|
||||||
|
required: false
|
||||||
|
nix-install-url:
|
||||||
|
description: A URL pointing to a harmonic `nix-install.sh` script
|
||||||
|
required: true
|
||||||
|
default: https://install.determinate.systems/nix
|
||||||
|
local-root:
|
||||||
|
description: A local `harmonic` binary root, overrides the `nix-install` setting (binaries should be named `harmonic-$ARCH`, eg. `harmonic-x86_64-linux`)
|
||||||
|
required: false
|
||||||
|
logger:
|
||||||
|
description: The logger to use for install (eg. `pretty`, `json`, `full`, `compact`)
|
||||||
|
required: false
|
||||||
|
log-directives:
|
||||||
|
description: A list of Tracing directives, comma separated (eg. `harmonic=trace`, see https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives)
|
||||||
|
required: false
|
||||||
|
backtrace:
|
||||||
|
description: The setting for `RUST_BACKTRACE` (see https://doc.rust-lang.org/std/backtrace/index.html#environment-variables)
|
||||||
|
required: false
|
||||||
|
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Install Nix
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
if [ -n "${{ inputs.channels }}" ]; then
|
||||||
|
export HARMONIC_CHANNELS=${{ inputs.channels }}
|
||||||
|
echo "Set HARMONIC_CHANNELS=$HARMONIC_CHANNELS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.modify-profile }}" ]; then
|
||||||
|
export HARMONIC_MODIFY_PROFILE=${{ inputs.modify-profile }}
|
||||||
|
echo "Set HARMONIC_MODIFY_PROFILE=$HARMONIC_MODIFY_PROFILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.daemon-user-count }}" ]; then
|
||||||
|
export HARMONIC_DAEMON_USER_COUNT=${{ inputs.daemon-user-count }}
|
||||||
|
echo "Set HARMONIC_DAEMON_USER_COUNT=$HARMONIC_DAEMON_USER_COUNT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.nix-build-group-name }}" ]; then
|
||||||
|
export HARMONIC_NIX_BUILD_GROUP_NAME=${{ inputs.nix-build-group-name }}
|
||||||
|
echo "Set HARMONIC_NIX_BUILD_GROUP_NAME=$HARMONIC_NIX_BUILD_GROUP_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.nix-build-group-id }}" ]; then
|
||||||
|
export HARMONIC_NIX_BUILD_GROUP_ID=${{ inputs.nix-build-group-id }}
|
||||||
|
echo "Set HARMONIC_NIX_BUILD_GROUP_ID=$HARMONIC_NIX_BUILD_GROUP_ID"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.nix-build-user-prefix }}" ]; then
|
||||||
|
export HARMONIC_NIX_BUILD_USER_ID_BASE=${{ inputs.nix-build-user-prefix }}
|
||||||
|
echo "Set HARMONIC_NIX_BUILD_USER_ID_BASE=$HARMONIC_NIX_BUILD_USER_ID_BASE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.nix-build-user-base }}" ]; then
|
||||||
|
export HARMONIC_NIX_BUILD_USER_PREFIX=${{ inputs.nix-build-user-base }}
|
||||||
|
echo "Set HARMONIC_NIX_BUILD_USER_PREFIX=$HARMONIC_NIX_BUILD_USER_PREFIX"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.nix-package-url }}" ]; then
|
||||||
|
export HARMONIC_NIX_PACKAGE_URL=${{ inputs.nix-package-url }}
|
||||||
|
echo "Set HARMONIC_NIX_PACKAGE_URL=$HARMONIC_NIX_PACKAGE_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.extra-conf }}" ]; then
|
||||||
|
if [ -n "${{ inputs.github-token }}" ]; then
|
||||||
|
export HARMONIC_EXTRA_CONF="${{ inputs.extra-conf }}\naccess-tokens = github.com=${{ inputs.github-token }}"
|
||||||
|
else
|
||||||
|
export HARMONIC_EXTRA_CONF="${{ inputs.extra-conf }}"
|
||||||
|
fi
|
||||||
|
echo "Set HARMONIC_EXTRA_CONF=$HARMONIC_EXTRA_CONF"
|
||||||
|
else
|
||||||
|
if [ -n "${{ inputs.github-token }}" ]; then
|
||||||
|
export HARMONIC_EXTRA_CONF="access-tokens = github.com=${{ inputs.github-token }}"
|
||||||
|
echo "Set HARMONIC_EXTRA_CONF=$HARMONIC_EXTRA_CONF"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.mac-encrypt }}" ]; then
|
||||||
|
export HARMONIC_ENCRYPT=${{ inputs.mac-encrypt }}
|
||||||
|
echo "Set HARMONIC_ENCRYPT=$HARMONIC_ENCRYPT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.mac-case-sensitive }}" ]; then
|
||||||
|
export HARMONIC_CASE_SENSITIVE=${{ inputs.mac-case-sensitive }}
|
||||||
|
echo "Set HARMONIC_CASE_SENSITIVE=$HARMONIC_CASE_SENSITIVE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.mac-volume-label }}" ]; then
|
||||||
|
export HARMONIC_VOLUME_LABEL=${{ inputs.mac-volume-label }}
|
||||||
|
echo "Set HARMONIC_VOLUME_LABEL=$HARMONIC_VOLUME_LABEL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.mac-root-disk }}" ]; then
|
||||||
|
export HARMONIC_ROOT_DISK=${{ inputs.mac-root-disk }}
|
||||||
|
echo "Set HARMONIC_ROOT_DISK=$HARMONIC_ROOT_DISK"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.local-root }}" ]; then
|
||||||
|
if [ "$RUNNER_OS" == "macOS" ]; then
|
||||||
|
export PYTHON="python3"
|
||||||
|
else
|
||||||
|
export PYTHON="python"
|
||||||
|
fi
|
||||||
|
$PYTHON -m http.server --directory ${{ inputs.local-root }} --bind 0.0.0.0 8000 &
|
||||||
|
export HTTP_PID=$!
|
||||||
|
echo "Started simple http server for ${{ inputs.local-root }} on 0.0.0.0:8000"
|
||||||
|
while (! (: </dev/tcp/localhost/8000) &> /dev/null); do
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
export NIX_INSTALL_FORCE_ALLOW_HTTP="1"
|
||||||
|
echo "Set NIX_INSTALL_FORCE_ALLOW_HTTP=$NIX_INSTALL_FORCE_ALLOW_HTTP"
|
||||||
|
export NIX_INSTALL_URL=0.0.0.0:8000/nix-install.sh
|
||||||
|
echo "Set NIX_INSTALL_URL=$NIX_INSTALL_URL"
|
||||||
|
export NIX_INSTALL_BINARY_ROOT=http://0.0.0.0:8000/
|
||||||
|
echo "Set NIX_INSTALL_BINARY_ROOT=$NIX_INSTALL_BINARY_ROOT"
|
||||||
|
export NIX_INSTALL_FORCE_ALLOW_HTTP=1
|
||||||
|
echo "Set NIX_INSTALL_FORCE_ALLOW_HTTP=$NIX_INSTALL_FORCE_ALLOW_HTTP"
|
||||||
|
else
|
||||||
|
export NIX_INSTALL_URL=${{ inputs.nix-install-url }}
|
||||||
|
echo "Set NIX_INSTALL_URL=$NIX_INSTALL_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.logger }}" ]; then
|
||||||
|
export HARMONIC_LOGGER=${{ inputs.logger }}
|
||||||
|
echo "Set HARMONIC_LOGGER=$HARMONIC_LOGGER"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.log-directives }}" ]; then
|
||||||
|
export HARMONIC_LOG_DIRECTIVES=${{ inputs.log-directives }}
|
||||||
|
echo "Set HARMONIC_LOG_DIRECTIVES=$HARMONIC_LOG_DIRECTIVES"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.backtrace }}" ]; then
|
||||||
|
export RUST_BACKTRACE=${{ inputs.backtrace }}
|
||||||
|
echo "Set RUST_BACKTRACE=$RUST_BACKTRACE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
export HARMONIC_NO_CONFIRM=true
|
||||||
|
echo "Set HARMONIC_NO_CONFIRM=$HARMONIC_NO_CONFIRM"
|
||||||
|
|
||||||
|
curl --retry 20 -L $NIX_INSTALL_URL | sh -s -- install ${{ inputs.planner }} ${{ inputs.extra-args }}
|
||||||
|
|
||||||
|
if [ -n "$HTTP_PID" ]; then
|
||||||
|
kill $HTTP_PID
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@ fi
|
||||||
|
|
||||||
set -u
|
set -u
|
||||||
|
|
||||||
# If NIX_INSTALL_UPDATE_ROOT is unset or empty, default it.
|
# If NIX_INSTALL_BINARY_ROOT is unset or empty, default it.
|
||||||
NIX_INSTALL_UPDATE_ROOT="${NIX_INSTALL_UPDATE_ROOT:-https://install.determinate.systems/nix}"
|
NIX_INSTALL_BINARY_ROOT="${NIX_INSTALL_BINARY_ROOT:-https://install.determinate.systems/nix}"
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
downloader --check
|
downloader --check
|
||||||
|
@ -44,7 +44,7 @@ main() {
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
local _url="${NIX_INSTALL_OVERRIDE_URL-${NIX_INSTALL_UPDATE_ROOT}/harmonic-${_arch}${_ext}}"
|
local _url="${NIX_INSTALL_OVERRIDE_URL-${NIX_INSTALL_BINARY_ROOT}/harmonic-${_arch}${_ext}}"
|
||||||
|
|
||||||
local _dir
|
local _dir
|
||||||
if ! _dir="$(ensure mktemp -d)"; then
|
if ! _dir="$(ensure mktemp -d)"; then
|
||||||
|
|
|
@ -4,6 +4,7 @@ use std::path::{Path, PathBuf};
|
||||||
use nix::unistd::{chown, Group, User};
|
use nix::unistd::{chown, Group, User};
|
||||||
|
|
||||||
use tokio::fs::{create_dir, remove_dir_all};
|
use tokio::fs::{create_dir, remove_dir_all};
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use crate::action::{Action, ActionDescription, ActionState};
|
use crate::action::{Action, ActionDescription, ActionState};
|
||||||
use crate::action::{ActionError, StatefulAction};
|
use crate::action::{ActionError, StatefulAction};
|
||||||
|
@ -74,16 +75,24 @@ impl Action for CreateDirectory {
|
||||||
format!("Create directory `{}`", self.path.display())
|
format!("Create directory `{}`", self.path.display())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"create_directory",
|
||||||
|
path = tracing::field::display(self.path.display()),
|
||||||
|
user = self.user,
|
||||||
|
group = self.group,
|
||||||
|
mode = self
|
||||||
|
.mode
|
||||||
|
.map(|v| tracing::field::display(format!("{:#o}", v))),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
path = %self.path.display(),
|
|
||||||
user = self.user,
|
|
||||||
group = self.group,
|
|
||||||
mode = self.mode.map(|v| tracing::field::display(format!("{:#o}", v))),
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self {
|
let Self {
|
||||||
path,
|
path,
|
||||||
|
@ -150,12 +159,7 @@ impl Action for CreateDirectory {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
path = %self.path.display(),
|
|
||||||
user = self.user,
|
|
||||||
group = self.group,
|
|
||||||
mode = self.mode.map(|v| tracing::field::display(format!("{:#o}", v))),
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
let Self {
|
let Self {
|
||||||
path,
|
path,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use nix::unistd::{chown, Group, User};
|
use nix::unistd::{chown, Group, User};
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
|
@ -58,16 +59,31 @@ impl Action for CreateFile {
|
||||||
fn tracing_synopsis(&self) -> String {
|
fn tracing_synopsis(&self) -> String {
|
||||||
format!("Create or overwrite file `{}`", self.path.display())
|
format!("Create or overwrite file `{}`", self.path.display())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
let span = span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"create_file",
|
||||||
|
path = tracing::field::display(self.path.display()),
|
||||||
|
user = self.user,
|
||||||
|
group = self.group,
|
||||||
|
mode = self
|
||||||
|
.mode
|
||||||
|
.map(|v| tracing::field::display(format!("{:#o}", v))),
|
||||||
|
buf = tracing::field::Empty,
|
||||||
|
);
|
||||||
|
|
||||||
|
if tracing::enabled!(tracing::Level::TRACE) {
|
||||||
|
span.record("buf", &self.buf);
|
||||||
|
}
|
||||||
|
span
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
path = %self.path.display(),
|
|
||||||
user = self.user,
|
|
||||||
group = self.group,
|
|
||||||
mode = self.mode.map(|v| tracing::field::display(format!("{:#o}", v))),
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self {
|
let Self {
|
||||||
path,
|
path,
|
||||||
|
@ -78,6 +94,11 @@ impl Action for CreateFile {
|
||||||
force: _,
|
force: _,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
|
if tracing::enabled!(tracing::Level::TRACE) {
|
||||||
|
let span = tracing::Span::current();
|
||||||
|
span.record("buf", &buf);
|
||||||
|
}
|
||||||
|
|
||||||
let mut options = OpenOptions::new();
|
let mut options = OpenOptions::new();
|
||||||
options.create_new(true).write(true).read(true);
|
options.create_new(true).write(true).read(true);
|
||||||
|
|
||||||
|
@ -135,12 +156,7 @@ impl Action for CreateFile {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
path = %self.path.display(),
|
|
||||||
user = self.user,
|
|
||||||
group = self.group,
|
|
||||||
mode = self.mode.map(|v| tracing::field::display(format!("{:#o}", v))),
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
let Self {
|
let Self {
|
||||||
path,
|
path,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use crate::action::ActionError;
|
use crate::action::ActionError;
|
||||||
use crate::execute_command;
|
use crate::execute_command;
|
||||||
|
@ -37,10 +38,16 @@ impl Action for CreateGroup {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"create_group",
|
||||||
user = self.name,
|
user = self.name,
|
||||||
gid = self.gid,
|
gid = self.gid,
|
||||||
))]
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self { name, gid } = self;
|
let Self { name, gid } = self;
|
||||||
|
|
||||||
|
@ -108,10 +115,7 @@ impl Action for CreateGroup {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
user = self.name,
|
|
||||||
gid = self.gid,
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
let Self { name, gid: _ } = self;
|
let Self { name, gid: _ } = self;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use nix::unistd::{chown, Group, User};
|
use nix::unistd::{chown, Group, User};
|
||||||
|
|
||||||
|
use crate::action::{Action, ActionDescription, ActionError, StatefulAction};
|
||||||
use std::{
|
use std::{
|
||||||
io::SeekFrom,
|
io::SeekFrom,
|
||||||
os::unix::prelude::PermissionsExt,
|
os::unix::prelude::PermissionsExt,
|
||||||
|
@ -9,8 +10,7 @@ use tokio::{
|
||||||
fs::{remove_file, OpenOptions},
|
fs::{remove_file, OpenOptions},
|
||||||
io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt},
|
io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt},
|
||||||
};
|
};
|
||||||
|
use tracing::{span, Span};
|
||||||
use crate::action::{Action, ActionDescription, ActionError, StatefulAction};
|
|
||||||
|
|
||||||
/** Create a file at the given location with the provided `buf`,
|
/** Create a file at the given location with the provided `buf`,
|
||||||
optionally with an owning user, group, and mode.
|
optionally with an owning user, group, and mode.
|
||||||
|
@ -58,16 +58,30 @@ impl Action for CreateOrAppendFile {
|
||||||
format!("Create or append file `{}`", self.path.display())
|
format!("Create or append file `{}`", self.path.display())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
let span = span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"create_or_append_file",
|
||||||
|
path = tracing::field::display(self.path.display()),
|
||||||
|
user = self.user,
|
||||||
|
group = self.group,
|
||||||
|
mode = self
|
||||||
|
.mode
|
||||||
|
.map(|v| tracing::field::display(format!("{:#o}", v))),
|
||||||
|
buf = tracing::field::Empty,
|
||||||
|
);
|
||||||
|
|
||||||
|
if tracing::enabled!(tracing::Level::TRACE) {
|
||||||
|
span.record("buf", &self.buf);
|
||||||
|
}
|
||||||
|
span
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
path = %self.path.display(),
|
|
||||||
user = self.user,
|
|
||||||
group = self.group,
|
|
||||||
mode = self.mode.map(|v| tracing::field::display(format!("{:#o}", v))),
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self {
|
let Self {
|
||||||
path,
|
path,
|
||||||
|
@ -142,12 +156,7 @@ impl Action for CreateOrAppendFile {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
path = %self.path.display(),
|
|
||||||
user = self.user,
|
|
||||||
group = self.group,
|
|
||||||
mode = self.mode.map(|v| tracing::field::display(format!("{:#o}", v))),
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
let Self {
|
let Self {
|
||||||
path,
|
path,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use crate::action::ActionError;
|
use crate::action::ActionError;
|
||||||
use crate::execute_command;
|
use crate::execute_command;
|
||||||
|
@ -38,6 +39,18 @@ impl Action for CreateUser {
|
||||||
self.name, self.uid, self.groupname, self.gid
|
self.name, self.uid, self.groupname, self.gid
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"create_user",
|
||||||
|
user = self.name,
|
||||||
|
uid = self.uid,
|
||||||
|
groupname = self.groupname,
|
||||||
|
gid = self.gid,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
self.tracing_synopsis(),
|
self.tracing_synopsis(),
|
||||||
|
@ -47,12 +60,7 @@ impl Action for CreateUser {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
user = self.name,
|
|
||||||
uid = self.uid,
|
|
||||||
groupname = self.groupname,
|
|
||||||
gid = self.gid,
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self {
|
let Self {
|
||||||
name,
|
name,
|
||||||
|
@ -231,11 +239,7 @@ impl Action for CreateUser {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
user = self.name,
|
|
||||||
uid = self.uid,
|
|
||||||
gid = self.gid,
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
let Self {
|
let Self {
|
||||||
name,
|
name,
|
||||||
|
|
|
@ -2,6 +2,7 @@ use std::path::PathBuf;
|
||||||
|
|
||||||
use bytes::Buf;
|
use bytes::Buf;
|
||||||
use reqwest::Url;
|
use reqwest::Url;
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use crate::action::{Action, ActionDescription, ActionError, StatefulAction};
|
use crate::action::{Action, ActionDescription, ActionError, StatefulAction};
|
||||||
|
|
||||||
|
@ -31,14 +32,20 @@ impl Action for FetchAndUnpackNix {
|
||||||
format!("Fetch `{}` to `{}`", self.url, self.dest.display())
|
format!("Fetch `{}` to `{}`", self.url, self.dest.display())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"fetch_and_unpack_nix",
|
||||||
|
url = tracing::field::display(&self.url),
|
||||||
|
dest = tracing::field::display(self.dest.display()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
url = %self.url,
|
|
||||||
dest = %self.dest.display(),
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self { url, dest } = self;
|
let Self { url, dest } = self;
|
||||||
|
|
||||||
|
@ -66,10 +73,7 @@ impl Action for FetchAndUnpackNix {
|
||||||
vec![/* Deliberately empty -- this is a noop */]
|
vec![/* Deliberately empty -- this is a noop */]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
url = %self.url,
|
|
||||||
dest = %self.dest.display(),
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
let Self { url: _, dest: _ } = self;
|
let Self { url: _, dest: _ } = self;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use crate::action::{Action, ActionDescription, ActionError, StatefulAction};
|
use crate::action::{Action, ActionDescription, ActionError, StatefulAction};
|
||||||
|
|
||||||
const DEST: &str = "/nix/store";
|
const DEST: &str = "/nix/store";
|
||||||
|
@ -27,6 +29,15 @@ impl Action for MoveUnpackedNix {
|
||||||
"Move the downloaded Nix into `/nix`".to_string()
|
"Move the downloaded Nix into `/nix`".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"mount_unpacked_nix",
|
||||||
|
src = tracing::field::display(self.src.display()),
|
||||||
|
dest = DEST,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
format!("Move the downloaded Nix into `/nix`"),
|
format!("Move the downloaded Nix into `/nix`"),
|
||||||
|
@ -37,10 +48,7 @@ impl Action for MoveUnpackedNix {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
src = %self.src.display(),
|
|
||||||
dest = DEST,
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self { src } = self;
|
let Self { src } = self;
|
||||||
|
|
||||||
|
@ -73,10 +81,7 @@ impl Action for MoveUnpackedNix {
|
||||||
vec![/* Deliberately empty -- this is a noop */]
|
vec![/* Deliberately empty -- this is a noop */]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
src = %self.src.display(),
|
|
||||||
dest = DEST,
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
// Noop
|
// Noop
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -6,6 +6,7 @@ use crate::{
|
||||||
use glob::glob;
|
use glob::glob;
|
||||||
|
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use crate::action::{Action, ActionDescription};
|
use crate::action::{Action, ActionDescription};
|
||||||
|
|
||||||
|
@ -31,13 +32,19 @@ impl Action for SetupDefaultProfile {
|
||||||
"Setup the default Nix profile".to_string()
|
"Setup the default Nix profile".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"setup_default_profile",
|
||||||
|
channels = self.channels.join(","),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
channels = %self.channels.join(","),
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self { channels } = self;
|
let Self { channels } = self;
|
||||||
|
|
||||||
|
@ -156,9 +163,7 @@ impl Action for SetupDefaultProfile {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
channels = %self.channels.join(","),
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
std::env::remove_var("NIX_SSL_CERT_FILE");
|
std::env::remove_var("NIX_SSL_CERT_FILE");
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use reqwest::Url;
|
use reqwest::Url;
|
||||||
|
use tracing::{span, Instrument, Span};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Configure Nix and start it
|
Configure Nix and start it
|
||||||
|
@ -68,6 +69,10 @@ impl Action for ConfigureNix {
|
||||||
"Configure Nix".to_string()
|
"Configure Nix".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(tracing::Level::DEBUG, "configure_nix",)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
let Self {
|
let Self {
|
||||||
setup_default_profile,
|
setup_default_profile,
|
||||||
|
@ -98,17 +103,67 @@ impl Action for ConfigureNix {
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
if let Some(configure_shell_profile) = configure_shell_profile {
|
if let Some(configure_shell_profile) = configure_shell_profile {
|
||||||
|
let setup_default_profile_span = tracing::Span::current().clone();
|
||||||
|
let (
|
||||||
|
place_nix_configuration_span,
|
||||||
|
place_channel_configuration_span,
|
||||||
|
configure_shell_profile_span,
|
||||||
|
) = (
|
||||||
|
setup_default_profile_span.clone(),
|
||||||
|
setup_default_profile_span.clone(),
|
||||||
|
setup_default_profile_span.clone(),
|
||||||
|
);
|
||||||
tokio::try_join!(
|
tokio::try_join!(
|
||||||
async move { setup_default_profile.try_execute().await },
|
async move {
|
||||||
async move { place_nix_configuration.try_execute().await },
|
setup_default_profile
|
||||||
async move { place_channel_configuration.try_execute().await },
|
.try_execute()
|
||||||
async move { configure_shell_profile.try_execute().await },
|
.instrument(setup_default_profile_span)
|
||||||
|
.await
|
||||||
|
},
|
||||||
|
async move {
|
||||||
|
place_nix_configuration
|
||||||
|
.try_execute()
|
||||||
|
.instrument(place_nix_configuration_span)
|
||||||
|
.await
|
||||||
|
},
|
||||||
|
async move {
|
||||||
|
place_channel_configuration
|
||||||
|
.try_execute()
|
||||||
|
.instrument(place_channel_configuration_span)
|
||||||
|
.await
|
||||||
|
},
|
||||||
|
async move {
|
||||||
|
configure_shell_profile
|
||||||
|
.try_execute()
|
||||||
|
.instrument(configure_shell_profile_span)
|
||||||
|
.await
|
||||||
|
},
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
|
let place_channel_configuration_span = tracing::Span::current().clone();
|
||||||
|
let (setup_default_profile_span, place_nix_configuration_span) = (
|
||||||
|
place_channel_configuration_span.clone(),
|
||||||
|
place_channel_configuration_span.clone(),
|
||||||
|
);
|
||||||
tokio::try_join!(
|
tokio::try_join!(
|
||||||
async move { setup_default_profile.try_execute().await },
|
async move {
|
||||||
async move { place_nix_configuration.try_execute().await },
|
setup_default_profile
|
||||||
async move { place_channel_configuration.try_execute().await },
|
.try_execute()
|
||||||
|
.instrument(setup_default_profile_span)
|
||||||
|
.await
|
||||||
|
},
|
||||||
|
async move {
|
||||||
|
place_nix_configuration
|
||||||
|
.try_execute()
|
||||||
|
.instrument(place_nix_configuration_span)
|
||||||
|
.await
|
||||||
|
},
|
||||||
|
async move {
|
||||||
|
place_channel_configuration
|
||||||
|
.try_execute()
|
||||||
|
.instrument(place_channel_configuration_span)
|
||||||
|
.await
|
||||||
|
},
|
||||||
)?;
|
)?;
|
||||||
};
|
};
|
||||||
configure_nix_daemon_service.try_execute().await?;
|
configure_nix_daemon_service.try_execute().await?;
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::action::{Action, ActionDescription, ActionError, StatefulAction};
|
||||||
use nix::unistd::User;
|
use nix::unistd::User;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use tokio::task::JoinSet;
|
use tokio::task::JoinSet;
|
||||||
|
use tracing::{span, Instrument, Span};
|
||||||
|
|
||||||
// Fish has different syntax than zsh/bash, treat it separate
|
// Fish has different syntax than zsh/bash, treat it separate
|
||||||
const PROFILE_FISH_SUFFIX: &str = "conf.d/nix.fish";
|
const PROFILE_FISH_SUFFIX: &str = "conf.d/nix.fish";
|
||||||
|
@ -141,6 +142,10 @@ impl Action for ConfigureShellProfile {
|
||||||
"Configure the shell profiles".to_string()
|
"Configure the shell profiles".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(tracing::Level::DEBUG, "configure_shell_profile",)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
self.tracing_synopsis(),
|
self.tracing_synopsis(),
|
||||||
|
@ -166,8 +171,10 @@ impl Action for ConfigureShellProfile {
|
||||||
let span = tracing::Span::current().clone();
|
let span = tracing::Span::current().clone();
|
||||||
let mut create_or_append_file_clone = create_or_append_file.clone();
|
let mut create_or_append_file_clone = create_or_append_file.clone();
|
||||||
let _abort_handle = set.spawn(async move {
|
let _abort_handle = set.spawn(async move {
|
||||||
let _ = span.enter();
|
create_or_append_file_clone
|
||||||
create_or_append_file_clone.try_execute().await?;
|
.try_execute()
|
||||||
|
.instrument(span)
|
||||||
|
.await?;
|
||||||
Result::<_, ActionError>::Ok((idx, create_or_append_file_clone))
|
Result::<_, ActionError>::Ok((idx, create_or_append_file_clone))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use crate::action::base::CreateDirectory;
|
use crate::action::base::CreateDirectory;
|
||||||
use crate::action::{Action, ActionDescription, ActionError, StatefulAction};
|
use crate::action::{Action, ActionDescription, ActionError, StatefulAction};
|
||||||
|
|
||||||
|
@ -45,6 +47,10 @@ impl Action for CreateNixTree {
|
||||||
"Create a directory tree in `/nix`".to_string()
|
"Create a directory tree in `/nix`".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(tracing::Level::DEBUG, "create_nix_tree",)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
self.tracing_synopsis(),
|
self.tracing_synopsis(),
|
||||||
|
|
|
@ -6,6 +6,7 @@ use crate::{
|
||||||
settings::CommonSettings,
|
settings::CommonSettings,
|
||||||
};
|
};
|
||||||
use tokio::task::JoinSet;
|
use tokio::task::JoinSet;
|
||||||
|
use tracing::{span, Instrument, Span};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct CreateUsersAndGroups {
|
pub struct CreateUsersAndGroups {
|
||||||
|
@ -62,6 +63,18 @@ impl Action for CreateUsersAndGroups {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"create_users_and_group",
|
||||||
|
daemon_user_count = self.daemon_user_count,
|
||||||
|
nix_build_group_name = self.nix_build_group_name,
|
||||||
|
nix_build_group_id = self.nix_build_group_id,
|
||||||
|
nix_build_user_prefix = self.nix_build_user_prefix,
|
||||||
|
nix_build_user_id_base = self.nix_build_user_id_base,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
let Self {
|
let Self {
|
||||||
daemon_user_count: _,
|
daemon_user_count: _,
|
||||||
|
@ -91,13 +104,7 @@ impl Action for CreateUsersAndGroups {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), explanation)]
|
vec![ActionDescription::new(self.tracing_synopsis(), explanation)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
daemon_user_count = self.daemon_user_count,
|
|
||||||
nix_build_group_name = self.nix_build_group_name,
|
|
||||||
nix_build_group_id = self.nix_build_group_id,
|
|
||||||
nix_build_user_prefix = self.nix_build_user_prefix,
|
|
||||||
nix_build_user_id_base = self.nix_build_user_id_base,
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self {
|
let Self {
|
||||||
create_users,
|
create_users,
|
||||||
|
@ -129,9 +136,10 @@ impl Action for CreateUsersAndGroups {
|
||||||
let mut set = JoinSet::new();
|
let mut set = JoinSet::new();
|
||||||
let mut errors: Vec<Box<ActionError>> = Vec::new();
|
let mut errors: Vec<Box<ActionError>> = Vec::new();
|
||||||
for (idx, create_user) in create_users.iter_mut().enumerate() {
|
for (idx, create_user) in create_users.iter_mut().enumerate() {
|
||||||
|
let span = tracing::Span::current().clone();
|
||||||
let mut create_user_clone = create_user.clone();
|
let mut create_user_clone = create_user.clone();
|
||||||
let _abort_handle = set.spawn(async move {
|
let _abort_handle = set.spawn(async move {
|
||||||
create_user_clone.try_execute().await?;
|
create_user_clone.try_execute().instrument(span).await?;
|
||||||
Result::<_, _>::Ok((idx, create_user_clone))
|
Result::<_, _>::Ok((idx, create_user_clone))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -188,13 +196,7 @@ impl Action for CreateUsersAndGroups {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
daemon_user_count = self.daemon_user_count,
|
|
||||||
nix_build_group_name = self.nix_build_group_name,
|
|
||||||
nix_build_group_id = self.nix_build_group_id,
|
|
||||||
nix_build_user_prefix = self.nix_build_user_prefix,
|
|
||||||
nix_build_user_id_base = self.nix_build_user_id_base,
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
let Self {
|
let Self {
|
||||||
create_users,
|
create_users,
|
||||||
|
@ -210,9 +212,10 @@ impl Action for CreateUsersAndGroups {
|
||||||
let mut errors = Vec::default();
|
let mut errors = Vec::default();
|
||||||
|
|
||||||
for (idx, create_user) in create_users.iter().enumerate() {
|
for (idx, create_user) in create_users.iter().enumerate() {
|
||||||
|
let span = tracing::Span::current().clone();
|
||||||
let mut create_user_clone = create_user.clone();
|
let mut create_user_clone = create_user.clone();
|
||||||
let _abort_handle = set.spawn(async move {
|
let _abort_handle = set.spawn(async move {
|
||||||
create_user_clone.try_revert().await?;
|
create_user_clone.try_revert().instrument(span).await?;
|
||||||
Result::<_, ActionError>::Ok((idx, create_user_clone))
|
Result::<_, ActionError>::Ok((idx, create_user_clone))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::action::base::CreateFile;
|
||||||
use crate::action::ActionError;
|
use crate::action::ActionError;
|
||||||
use crate::action::{Action, ActionDescription, StatefulAction};
|
use crate::action::{Action, ActionDescription, StatefulAction};
|
||||||
use reqwest::Url;
|
use reqwest::Url;
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Place a channel configuration containing `channels` to the `$ROOT_HOME/.nix-channels` file
|
Place a channel configuration containing `channels` to the `$ROOT_HOME/.nix-channels` file
|
||||||
|
@ -54,13 +55,24 @@ impl Action for PlaceChannelConfiguration {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"place_channel_configuration",
|
||||||
|
channels = self
|
||||||
|
.channels
|
||||||
|
.iter()
|
||||||
|
.map(|(c, u)| format!("{c}={u}"))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", "),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
channels = self.channels.iter().map(|(c, u)| format!("{c}={u}")).collect::<Vec<_>>().join(", "),
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self {
|
let Self {
|
||||||
create_file,
|
create_file,
|
||||||
|
@ -82,9 +94,7 @@ impl Action for PlaceChannelConfiguration {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
channels = self.channels.iter().map(|(c, u)| format!("{c}={u}")).collect::<Vec<_>>().join(", "),
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
let Self {
|
let Self {
|
||||||
create_file,
|
create_file,
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use crate::action::base::{CreateDirectory, CreateFile};
|
use crate::action::base::{CreateDirectory, CreateFile};
|
||||||
use crate::action::{Action, ActionDescription, ActionError, StatefulAction};
|
use crate::action::{Action, ActionDescription, ActionError, StatefulAction};
|
||||||
|
|
||||||
|
@ -50,6 +52,10 @@ impl Action for PlaceNixConfiguration {
|
||||||
format!("Place the Nix configuration in `{NIX_CONF}`")
|
format!("Place the Nix configuration in `{NIX_CONF}`")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(tracing::Level::DEBUG, "place_nix_configuration",)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
self.tracing_synopsis(),
|
self.tracing_synopsis(),
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use super::{CreateNixTree, CreateUsersAndGroups};
|
use super::{CreateNixTree, CreateUsersAndGroups};
|
||||||
use crate::{
|
use crate::{
|
||||||
action::{
|
action::{
|
||||||
|
@ -48,6 +50,10 @@ impl Action for ProvisionNix {
|
||||||
"Provision Nix".to_string()
|
"Provision Nix".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(tracing::Level::DEBUG, "provision_nix",)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
let Self {
|
let Self {
|
||||||
fetch_nix,
|
fetch_nix,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use crate::action::{ActionError, StatefulAction};
|
use crate::action::{ActionError, StatefulAction};
|
||||||
use crate::execute_command;
|
use crate::execute_command;
|
||||||
|
@ -32,13 +33,19 @@ impl Action for BootstrapApfsVolume {
|
||||||
format!("Bootstrap and kickstart `{}`", self.path.display())
|
format!("Bootstrap and kickstart `{}`", self.path.display())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"bootstrap_volume",
|
||||||
|
path = %self.path.display(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
path = %self.path.display(),
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self { path } = self;
|
let Self { path } = self;
|
||||||
|
|
||||||
|
@ -70,9 +77,7 @@ impl Action for BootstrapApfsVolume {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
path = %self.path.display(),
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
let Self { path } = self;
|
let Self { path } = self;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use crate::action::{ActionError, StatefulAction};
|
use crate::action::{ActionError, StatefulAction};
|
||||||
use crate::execute_command;
|
use crate::execute_command;
|
||||||
|
@ -41,15 +42,21 @@ impl Action for CreateApfsVolume {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"create_volume",
|
||||||
|
disk = %self.disk.display(),
|
||||||
|
name = %self.name,
|
||||||
|
case_sensitive = %self.case_sensitive,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
disk = %self.disk.display(),
|
|
||||||
name = %self.name,
|
|
||||||
case_sensitive = %self.case_sensitive,
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self {
|
let Self {
|
||||||
disk,
|
disk,
|
||||||
|
@ -91,11 +98,7 @@ impl Action for CreateApfsVolume {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
disk = %self.disk.display(),
|
|
||||||
name = %self.name,
|
|
||||||
case_sensitive = %self.case_sensitive,
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
let Self {
|
let Self {
|
||||||
disk: _,
|
disk: _,
|
||||||
|
|
|
@ -11,6 +11,7 @@ use std::{
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
pub const NIX_VOLUME_MOUNTD_DEST: &str = "/Library/LaunchDaemons/org.nixos.darwin-store.plist";
|
pub const NIX_VOLUME_MOUNTD_DEST: &str = "/Library/LaunchDaemons/org.nixos.darwin-store.plist";
|
||||||
|
|
||||||
|
@ -143,6 +144,15 @@ impl Action for CreateNixVolume {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"create_apfs_volume",
|
||||||
|
disk = tracing::field::display(self.disk.display()),
|
||||||
|
name = self.name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
let Self {
|
let Self {
|
||||||
disk: _, name: _, ..
|
disk: _, name: _, ..
|
||||||
|
@ -150,7 +160,7 @@ impl Action for CreateNixVolume {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(destination,))]
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self {
|
let Self {
|
||||||
disk: _,
|
disk: _,
|
||||||
|
@ -213,7 +223,7 @@ impl Action for CreateNixVolume {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(disk, name))]
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
let Self {
|
let Self {
|
||||||
disk: _,
|
disk: _,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use crate::execute_command;
|
use crate::execute_command;
|
||||||
|
|
||||||
|
@ -22,6 +23,10 @@ impl Action for CreateSyntheticObjects {
|
||||||
"Create objects defined in `/etc/synthetic.conf`".to_string()
|
"Create objects defined in `/etc/synthetic.conf`".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(tracing::Level::DEBUG, "create_synthetic_objects",)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
self.tracing_synopsis(),
|
self.tracing_synopsis(),
|
||||||
|
@ -29,7 +34,7 @@ impl Action for CreateSyntheticObjects {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields())]
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
// Yup we literally call both and ignore the error! Reasoning: https://github.com/NixOS/nix/blob/95331cb9c99151cbd790ceb6ddaf49fc1c0da4b3/scripts/create-darwin-volume.sh#L261
|
// Yup we literally call both and ignore the error! Reasoning: https://github.com/NixOS/nix/blob/95331cb9c99151cbd790ceb6ddaf49fc1c0da4b3/scripts/create-darwin-volume.sh#L261
|
||||||
execute_command(
|
execute_command(
|
||||||
|
@ -59,7 +64,7 @@ impl Action for CreateSyntheticObjects {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields())]
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
// Yup we literally call both and ignore the error! Reasoning: https://github.com/NixOS/nix/blob/95331cb9c99151cbd790ceb6ddaf49fc1c0da4b3/scripts/create-darwin-volume.sh#L261
|
// Yup we literally call both and ignore the error! Reasoning: https://github.com/NixOS/nix/blob/95331cb9c99151cbd790ceb6ddaf49fc1c0da4b3/scripts/create-darwin-volume.sh#L261
|
||||||
execute_command(
|
execute_command(
|
||||||
|
|
|
@ -2,6 +2,7 @@ use std::io::Cursor;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use crate::action::{ActionError, StatefulAction};
|
use crate::action::{ActionError, StatefulAction};
|
||||||
use crate::execute_command;
|
use crate::execute_command;
|
||||||
|
@ -34,13 +35,19 @@ impl Action for EnableOwnership {
|
||||||
format!("Enable ownership on {}", self.path.display())
|
format!("Enable ownership on {}", self.path.display())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"enable_ownership",
|
||||||
|
path = %self.path.display(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
path = %self.path.display(),
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self { path } = self;
|
let Self { path } = self;
|
||||||
|
|
||||||
|
@ -79,9 +86,7 @@ impl Action for EnableOwnership {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
path = %self.path.display(),
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
// noop
|
// noop
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -7,6 +7,7 @@ use crate::{
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Encrypt an APFS volume
|
Encrypt an APFS volume
|
||||||
|
@ -43,6 +44,14 @@ impl Action for EncryptApfsVolume {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"encrypt_volume",
|
||||||
|
disk = tracing::field::display(self.disk.display()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use crate::action::{ActionError, StatefulAction};
|
use crate::action::{ActionError, StatefulAction};
|
||||||
use crate::execute_command;
|
use crate::execute_command;
|
||||||
|
@ -28,13 +29,19 @@ impl Action for KickstartLaunchctlService {
|
||||||
format!("Kickstart the launchctl unit `{unit}`")
|
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<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
unit = %self.unit,
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self { unit } = self;
|
let Self { unit } = self;
|
||||||
|
|
||||||
|
@ -56,9 +63,7 @@ impl Action for KickstartLaunchctlService {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
unit = %self.unit,
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
// noop
|
// noop
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use crate::action::{ActionError, StatefulAction};
|
use crate::action::{ActionError, StatefulAction};
|
||||||
use crate::execute_command;
|
use crate::execute_command;
|
||||||
|
@ -34,14 +35,20 @@ impl Action for UnmountApfsVolume {
|
||||||
format!("Unmount the `{}` APFS volume", self.name)
|
format!("Unmount the `{}` APFS volume", self.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"unmount_volume",
|
||||||
|
disk = tracing::field::display(self.disk.display()),
|
||||||
|
name = self.name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
disk = %self.disk.display(),
|
|
||||||
name = %self.name,
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self { disk: _, name } = self;
|
let Self { disk: _, name } = self;
|
||||||
|
|
||||||
|
@ -62,10 +69,7 @@ impl Action for UnmountApfsVolume {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
disk = %self.disk.display(),
|
|
||||||
name = %self.name,
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
let Self { disk: _, name } = self;
|
let Self { disk: _, name } = self;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ use std::path::{Path, PathBuf};
|
||||||
use target_lexicon::OperatingSystem;
|
use target_lexicon::OperatingSystem;
|
||||||
use tokio::fs::remove_file;
|
use tokio::fs::remove_file;
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use crate::action::{ActionError, StatefulAction};
|
use crate::action::{ActionError, StatefulAction};
|
||||||
use crate::execute_command;
|
use crate::execute_command;
|
||||||
|
@ -50,6 +51,11 @@ impl Action for ConfigureNixDaemonService {
|
||||||
fn tracing_synopsis(&self) -> String {
|
fn tracing_synopsis(&self) -> String {
|
||||||
"Configure Nix daemon related settings with systemd".to_string()
|
"Configure Nix daemon related settings with systemd".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(tracing::Level::DEBUG, "configure_nix_daemon",)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
self.tracing_synopsis(),
|
self.tracing_synopsis(),
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
use crate::action::{ActionError, ActionState, StatefulAction};
|
use crate::action::{ActionError, ActionState, StatefulAction};
|
||||||
use crate::execute_command;
|
use crate::execute_command;
|
||||||
|
@ -32,13 +33,19 @@ impl Action for StartSystemdUnit {
|
||||||
format!("Enable (and start) the systemd unit {}", self.unit)
|
format!("Enable (and start) the systemd unit {}", self.unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"start_systemd_unit",
|
||||||
|
unit = %self.unit,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
unit = %self.unit,
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
let Self { unit, .. } = self;
|
let Self { unit, .. } = self;
|
||||||
|
|
||||||
|
@ -64,9 +71,7 @@ impl Action for StartSystemdUnit {
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
unit = %self.unit,
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
let Self { unit, .. } = self;
|
let Self { unit, .. } = self;
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ A custom [`Action`] can be created then used in a custom [`Planner`](crate::plan
|
||||||
|
|
||||||
```rust,no_run
|
```rust,no_run
|
||||||
use std::{error::Error, collections::HashMap};
|
use std::{error::Error, collections::HashMap};
|
||||||
|
use tracing::{Span, span};
|
||||||
use harmonic::{
|
use harmonic::{
|
||||||
InstallPlan,
|
InstallPlan,
|
||||||
settings::{CommonSettings, InstallSettingsError},
|
settings::{CommonSettings, InstallSettingsError},
|
||||||
|
@ -71,13 +72,19 @@ impl Action for MyAction {
|
||||||
"My action".to_string()
|
"My action".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"my_action",
|
||||||
|
// Tracing fields here ...
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
// Tracing fields...
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
// Execute steps ...
|
// Execute steps ...
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -87,9 +94,7 @@ impl Action for MyAction {
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![])]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
// Tracing fields...
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
// Revert steps...
|
// Revert steps...
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -159,6 +164,7 @@ mod stateful;
|
||||||
pub use stateful::{ActionState, StatefulAction};
|
pub use stateful::{ActionState, StatefulAction};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use tokio::task::JoinError;
|
use tokio::task::JoinError;
|
||||||
|
use tracing::Span;
|
||||||
|
|
||||||
use crate::error::HasExpectedErrors;
|
use crate::error::HasExpectedErrors;
|
||||||
|
|
||||||
|
@ -172,6 +178,14 @@ use crate::error::HasExpectedErrors;
|
||||||
pub trait Action: Send + Sync + std::fmt::Debug + dyn_clone::DynClone {
|
pub trait Action: Send + Sync + std::fmt::Debug + dyn_clone::DynClone {
|
||||||
/// A synopsis of the action for tracing purposes
|
/// A synopsis of the action for tracing purposes
|
||||||
fn tracing_synopsis(&self) -> String;
|
fn tracing_synopsis(&self) -> String;
|
||||||
|
/// A tracing span suitable for the action
|
||||||
|
///
|
||||||
|
/// It should be [`tracing::Level::DEBUG`] and contain the same name as the [`typetag::serde`] entry.
|
||||||
|
///
|
||||||
|
/// It may contain any fields, and will be attached in the [`StatefulAction::try_execute`] and [`StatefulAction::try_revert`] functions.
|
||||||
|
///
|
||||||
|
/// See [`tracing::Span`] for more details.
|
||||||
|
fn tracing_span(&self) -> Span;
|
||||||
/// A description of what this action would do during execution
|
/// A description of what this action would do during execution
|
||||||
///
|
///
|
||||||
/// If this action calls sub-[`Action`]s, care should be taken to use [`StatefulAction::describe_execute`] on those actions, not [`execute_description`][Action::execute_description].
|
/// If this action calls sub-[`Action`]s, care should be taken to use [`StatefulAction::describe_execute`] on those actions, not [`execute_description`][Action::execute_description].
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tracing::{Instrument, Span};
|
||||||
|
|
||||||
use super::{Action, ActionDescription, ActionError};
|
use super::{Action, ActionDescription, ActionError};
|
||||||
|
|
||||||
|
@ -26,6 +27,10 @@ impl StatefulAction<Box<dyn Action>> {
|
||||||
pub fn tracing_synopsis(&self) -> String {
|
pub fn tracing_synopsis(&self) -> String {
|
||||||
self.action.tracing_synopsis()
|
self.action.tracing_synopsis()
|
||||||
}
|
}
|
||||||
|
/// A tracing span suitable for the action
|
||||||
|
pub fn tracing_span(&self) -> Span {
|
||||||
|
self.action.tracing_span()
|
||||||
|
}
|
||||||
/// A description of what this action would do during execution
|
/// A description of what this action would do during execution
|
||||||
pub fn describe_execute(&self) -> Vec<ActionDescription> {
|
pub fn describe_execute(&self) -> Vec<ActionDescription> {
|
||||||
match self.state {
|
match self.state {
|
||||||
|
@ -47,6 +52,7 @@ impl StatefulAction<Box<dyn Action>> {
|
||||||
/// Perform any execution steps
|
/// Perform any execution steps
|
||||||
///
|
///
|
||||||
/// You should prefer this ([`try_execute`][StatefulAction::try_execute]) over [`execute`][Action::execute] as it handles [`ActionState`] and does tracing
|
/// You should prefer this ([`try_execute`][StatefulAction::try_execute]) over [`execute`][Action::execute] as it handles [`ActionState`] and does tracing
|
||||||
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
pub async fn try_execute(&mut self) -> Result<(), ActionError> {
|
pub async fn try_execute(&mut self) -> Result<(), ActionError> {
|
||||||
match self.state {
|
match self.state {
|
||||||
ActionState::Completed => {
|
ActionState::Completed => {
|
||||||
|
@ -73,6 +79,7 @@ impl StatefulAction<Box<dyn Action>> {
|
||||||
/// Perform any revert steps
|
/// Perform any revert steps
|
||||||
///
|
///
|
||||||
/// You should prefer this ([`try_revert`][StatefulAction::try_revert]) over [`revert`][Action::revert] as it handles [`ActionState`] and does tracing
|
/// You should prefer this ([`try_revert`][StatefulAction::try_revert]) over [`revert`][Action::revert] as it handles [`ActionState`] and does tracing
|
||||||
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
pub async fn try_revert(&mut self) -> Result<(), ActionError> {
|
pub async fn try_revert(&mut self) -> Result<(), ActionError> {
|
||||||
match self.state {
|
match self.state {
|
||||||
ActionState::Uncompleted => {
|
ActionState::Uncompleted => {
|
||||||
|
@ -106,6 +113,11 @@ where
|
||||||
self.action.tracing_synopsis()
|
self.action.tracing_synopsis()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A tracing span suitable for the action
|
||||||
|
pub fn tracing_span(&self) -> Span {
|
||||||
|
self.action.tracing_span()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn inner(&self) -> &A {
|
pub fn inner(&self) -> &A {
|
||||||
&self.action
|
&self.action
|
||||||
}
|
}
|
||||||
|
@ -137,24 +149,34 @@ where
|
||||||
///
|
///
|
||||||
/// You should prefer this ([`try_execute`][StatefulAction::try_execute]) over [`execute`][Action::execute] as it handles [`ActionState`] and does tracing
|
/// You should prefer this ([`try_execute`][StatefulAction::try_execute]) over [`execute`][Action::execute] as it handles [`ActionState`] and does tracing
|
||||||
pub async fn try_execute(&mut self) -> Result<(), ActionError> {
|
pub async fn try_execute(&mut self) -> Result<(), ActionError> {
|
||||||
|
let span = self.action.tracing_span();
|
||||||
match self.state {
|
match self.state {
|
||||||
ActionState::Completed => {
|
ActionState::Completed => {
|
||||||
tracing::trace!(
|
tracing::trace!(
|
||||||
|
parent: &span,
|
||||||
"Completed: (Already done) {}",
|
"Completed: (Already done) {}",
|
||||||
self.action.tracing_synopsis()
|
self.action.tracing_synopsis()
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
ActionState::Skipped => {
|
ActionState::Skipped => {
|
||||||
tracing::trace!("Skipped: {}", self.action.tracing_synopsis());
|
tracing::trace!(parent: &span, "Skipped: {}", self.action.tracing_synopsis());
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
self.state = ActionState::Progress;
|
self.state = ActionState::Progress;
|
||||||
tracing::debug!("Executing: {}", self.action.tracing_synopsis());
|
tracing::debug!(
|
||||||
self.action.execute().await?;
|
parent: &span,
|
||||||
|
"Executing: {}",
|
||||||
|
self.action.tracing_synopsis()
|
||||||
|
);
|
||||||
|
self.action.execute().instrument(span.clone()).await?;
|
||||||
self.state = ActionState::Completed;
|
self.state = ActionState::Completed;
|
||||||
tracing::debug!("Completed: {}", self.action.tracing_synopsis());
|
tracing::debug!(
|
||||||
|
parent: &span,
|
||||||
|
"Completed: {}",
|
||||||
|
self.action.tracing_synopsis()
|
||||||
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -163,23 +185,33 @@ where
|
||||||
///
|
///
|
||||||
/// You should prefer this ([`try_revert`][StatefulAction::try_revert]) over [`revert`][Action::revert] as it handles [`ActionState`] and does tracing
|
/// You should prefer this ([`try_revert`][StatefulAction::try_revert]) over [`revert`][Action::revert] as it handles [`ActionState`] and does tracing
|
||||||
pub async fn try_revert(&mut self) -> Result<(), ActionError> {
|
pub async fn try_revert(&mut self) -> Result<(), ActionError> {
|
||||||
|
let span = self.action.tracing_span();
|
||||||
match self.state {
|
match self.state {
|
||||||
ActionState::Uncompleted => {
|
ActionState::Uncompleted => {
|
||||||
tracing::trace!(
|
tracing::trace!(
|
||||||
|
parent: &span,
|
||||||
"Reverted: (Already done) {}",
|
"Reverted: (Already done) {}",
|
||||||
self.action.tracing_synopsis()
|
self.action.tracing_synopsis()
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
ActionState::Skipped => {
|
ActionState::Skipped => {
|
||||||
tracing::trace!("Skipped: {}", self.action.tracing_synopsis());
|
tracing::trace!(parent: &span, "Skipped: {}", self.action.tracing_synopsis());
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
self.state = ActionState::Progress;
|
self.state = ActionState::Progress;
|
||||||
tracing::debug!("Reverting: {}", self.action.tracing_synopsis());
|
tracing::debug!(
|
||||||
self.action.revert().await?;
|
parent: &span,
|
||||||
tracing::debug!("Reverted: {}", self.action.tracing_synopsis());
|
"Reverting: {}",
|
||||||
|
self.action.tracing_synopsis()
|
||||||
|
);
|
||||||
|
self.action.revert().instrument(span.clone()).await?;
|
||||||
|
tracing::debug!(
|
||||||
|
parent: &span,
|
||||||
|
"Reverted: {}",
|
||||||
|
self.action.tracing_synopsis()
|
||||||
|
);
|
||||||
self.state = ActionState::Uncompleted;
|
self.state = ActionState::Uncompleted;
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,7 +2,9 @@ use atty::Stream;
|
||||||
use eyre::WrapErr;
|
use eyre::WrapErr;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use tracing_error::ErrorLayer;
|
use tracing_error::ErrorLayer;
|
||||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
|
use tracing_subscriber::{
|
||||||
|
filter::Directive, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Default, Debug, clap::ValueEnum)]
|
#[derive(Clone, Default, Debug, clap::ValueEnum)]
|
||||||
pub enum Logger {
|
pub enum Logger {
|
||||||
|
@ -33,6 +35,11 @@ pub struct Instrumentation {
|
||||||
/// Which logger to use
|
/// Which logger to use
|
||||||
#[clap(long, env = "HARMONIC_LOGGER", default_value_t = Default::default(), global = true)]
|
#[clap(long, env = "HARMONIC_LOGGER", default_value_t = Default::default(), global = true)]
|
||||||
pub logger: Logger,
|
pub logger: Logger,
|
||||||
|
/// Tracing directives
|
||||||
|
///
|
||||||
|
/// See https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives
|
||||||
|
#[clap(long = "log-directive", global = true, env = "HARMONIC_LOG_DIRECTIVES", value_delimiter = ',', num_args = 0..)]
|
||||||
|
pub log_directives: Vec<Directive>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Instrumentation {
|
impl<'a> Instrumentation {
|
||||||
|
@ -120,7 +127,7 @@ impl<'a> Instrumentation {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn filter_layer(&self) -> eyre::Result<EnvFilter> {
|
pub fn filter_layer(&self) -> eyre::Result<EnvFilter> {
|
||||||
let filter_layer = match EnvFilter::try_from_default_env() {
|
let mut filter_layer = match EnvFilter::try_from_default_env() {
|
||||||
Ok(layer) => layer,
|
Ok(layer) => layer,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
// Catch a parse error and report it, ignore a missing env.
|
// Catch a parse error and report it, ignore a missing env.
|
||||||
|
@ -134,6 +141,11 @@ impl<'a> Instrumentation {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for directive in &self.log_directives {
|
||||||
|
let directive_clone = directive.clone();
|
||||||
|
filter_layer = filter_layer.add_directive(directive_clone);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(filter_layer)
|
Ok(filter_layer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ use crate::{
|
||||||
error::HasExpectedErrors,
|
error::HasExpectedErrors,
|
||||||
plan::RECEIPT_LOCATION,
|
plan::RECEIPT_LOCATION,
|
||||||
planner::Planner,
|
planner::Planner,
|
||||||
|
settings::CommonSettings,
|
||||||
BuiltinPlanner, InstallPlan,
|
BuiltinPlanner, InstallPlan,
|
||||||
};
|
};
|
||||||
use clap::{ArgAction, Parser};
|
use clap::{ArgAction, Parser};
|
||||||
|
@ -30,6 +31,9 @@ pub struct Install {
|
||||||
)]
|
)]
|
||||||
pub no_confirm: bool,
|
pub no_confirm: bool,
|
||||||
|
|
||||||
|
#[clap(flatten)]
|
||||||
|
pub settings: CommonSettings,
|
||||||
|
|
||||||
#[clap(
|
#[clap(
|
||||||
long,
|
long,
|
||||||
env = "HARMONIC_EXPLAIN",
|
env = "HARMONIC_EXPLAIN",
|
||||||
|
@ -47,12 +51,13 @@ pub struct Install {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl CommandExecute for Install {
|
impl CommandExecute for Install {
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields())]
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
async fn execute(self) -> eyre::Result<ExitCode> {
|
async fn execute(self) -> eyre::Result<ExitCode> {
|
||||||
let Self {
|
let Self {
|
||||||
no_confirm,
|
no_confirm,
|
||||||
plan,
|
plan,
|
||||||
planner,
|
planner,
|
||||||
|
settings,
|
||||||
explain,
|
explain,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
|
@ -97,7 +102,7 @@ impl CommandExecute for Install {
|
||||||
serde_json::from_str(&install_plan_string)?
|
serde_json::from_str(&install_plan_string)?
|
||||||
},
|
},
|
||||||
(None, None) => {
|
(None, None) => {
|
||||||
let builtin_planner = BuiltinPlanner::default()
|
let builtin_planner = BuiltinPlanner::from_common_settings(settings)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| eyre::eyre!(e))?;
|
.map_err(|e| eyre::eyre!(e))?;
|
||||||
let res = builtin_planner.plan().await;
|
let res = builtin_planner.plan().await;
|
||||||
|
|
|
@ -42,7 +42,7 @@ pub struct Uninstall {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl CommandExecute for Uninstall {
|
impl CommandExecute for Uninstall {
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields())]
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
async fn execute(self) -> eyre::Result<ExitCode> {
|
async fn execute(self) -> eyre::Result<ExitCode> {
|
||||||
let Self {
|
let Self {
|
||||||
no_confirm,
|
no_confirm,
|
||||||
|
|
|
@ -11,6 +11,7 @@ use crate::{
|
||||||
Action, BuiltinPlanner,
|
Action, BuiltinPlanner,
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, path::Path};
|
use std::{collections::HashMap, path::Path};
|
||||||
|
use tokio::process::Command;
|
||||||
|
|
||||||
/// A planner for Linux multi-user installs
|
/// A planner for Linux multi-user installs
|
||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
|
@ -37,7 +38,7 @@ impl Planner for LinuxMulti {
|
||||||
}
|
}
|
||||||
|
|
||||||
// For now, we don't try to repair the user's Nix install or anything special.
|
// For now, we don't try to repair the user's Nix install or anything special.
|
||||||
if let Ok(_) = tokio::process::Command::new("nix-env")
|
if let Ok(_) = Command::new("nix-env")
|
||||||
.arg("--version")
|
.arg("--version")
|
||||||
.stdin(std::process::Stdio::null())
|
.stdin(std::process::Stdio::null())
|
||||||
.status()
|
.status()
|
||||||
|
|
|
@ -101,6 +101,11 @@ impl Planner for SteamDeck {
|
||||||
|
|
||||||
async fn plan(&self) -> Result<Vec<StatefulAction<Box<dyn Action>>>, PlannerError> {
|
async fn plan(&self) -> Result<Vec<StatefulAction<Box<dyn Action>>>, PlannerError> {
|
||||||
let persistence = &self.persistence;
|
let persistence = &self.persistence;
|
||||||
|
if !persistence.is_absolute() {
|
||||||
|
return Err(PlannerError::Custom(Box::new(
|
||||||
|
SteamDeckError::AbsolutePathRequired(self.persistence.clone()),
|
||||||
|
)));
|
||||||
|
};
|
||||||
|
|
||||||
let nix_directory_buf = format!(
|
let nix_directory_buf = format!(
|
||||||
"\
|
"\
|
||||||
|
@ -247,3 +252,9 @@ impl Into<BuiltinPlanner> for SteamDeck {
|
||||||
BuiltinPlanner::SteamDeck(self)
|
BuiltinPlanner::SteamDeck(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
enum SteamDeckError {
|
||||||
|
#[error("`{0}` is not a path that can be canonicalized into an absolute path, bind mounts require an absolute path")]
|
||||||
|
AbsolutePathRequired(PathBuf),
|
||||||
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ use std::collections::HashMap;
|
||||||
use crate::{
|
use crate::{
|
||||||
action::{ActionError, StatefulAction},
|
action::{ActionError, StatefulAction},
|
||||||
error::HasExpectedErrors,
|
error::HasExpectedErrors,
|
||||||
settings::InstallSettingsError,
|
settings::{CommonSettings, InstallSettingsError},
|
||||||
Action, HarmonicError, InstallPlan,
|
Action, HarmonicError, InstallPlan,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -144,6 +144,16 @@ impl BuiltinPlanner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn from_common_settings(settings: CommonSettings) -> Result<Self, PlannerError> {
|
||||||
|
let mut built = Self::default().await?;
|
||||||
|
match &mut built {
|
||||||
|
BuiltinPlanner::LinuxMulti(inner) => inner.settings = settings,
|
||||||
|
BuiltinPlanner::DarwinMulti(inner) => inner.settings = settings,
|
||||||
|
BuiltinPlanner::SteamDeck(inner) => inner.settings = settings,
|
||||||
|
}
|
||||||
|
Ok(built)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn plan(self) -> Result<InstallPlan, HarmonicError> {
|
pub async fn plan(self) -> Result<InstallPlan, HarmonicError> {
|
||||||
match self {
|
match self {
|
||||||
BuiltinPlanner::LinuxMulti(planner) => InstallPlan::plan(planner).await,
|
BuiltinPlanner::LinuxMulti(planner) => InstallPlan::plan(planner).await,
|
||||||
|
|
|
@ -32,14 +32,16 @@ Settings which only apply to certain [`Planner`](crate::planner::Planner)s shoul
|
||||||
pub struct CommonSettings {
|
pub struct CommonSettings {
|
||||||
/// Channel(s) to add
|
/// Channel(s) to add
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "cli",clap(
|
feature = "cli",
|
||||||
|
clap(
|
||||||
long,
|
long,
|
||||||
value_parser,
|
value_parser,
|
||||||
name = "channel",
|
name = "channel",
|
||||||
action = clap::ArgAction::Append,
|
action = clap::ArgAction::Append,
|
||||||
env = "HARMONIC_CHANNEL",
|
env = "HARMONIC_CHANNELS",
|
||||||
default_value = "nixpkgs=https://nixos.org/channels/nixpkgs-unstable",
|
default_value = "nixpkgs=https://nixos.org/channels/nixpkgs-unstable",
|
||||||
))]
|
)
|
||||||
|
)]
|
||||||
pub(crate) channels: Vec<ChannelValue>,
|
pub(crate) channels: Vec<ChannelValue>,
|
||||||
|
|
||||||
/// Modify the user profile to automatically load nix
|
/// Modify the user profile to automatically load nix
|
||||||
|
@ -59,26 +61,44 @@ pub struct CommonSettings {
|
||||||
/// Number of build users to create
|
/// Number of build users to create
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "cli",
|
feature = "cli",
|
||||||
clap(long, default_value = "32", env = "HARMONIC_DAEMON_USER_COUNT")
|
clap(
|
||||||
|
long,
|
||||||
|
default_value = "32",
|
||||||
|
env = "HARMONIC_DAEMON_USER_COUNT",
|
||||||
|
global = true
|
||||||
|
)
|
||||||
)]
|
)]
|
||||||
pub(crate) daemon_user_count: usize,
|
pub(crate) daemon_user_count: usize,
|
||||||
|
|
||||||
/// The Nix build group name
|
/// The Nix build group name
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "cli",
|
feature = "cli",
|
||||||
clap(long, default_value = "nixbld", env = "HARMONIC_NIX_BUILD_GROUP_NAME")
|
clap(
|
||||||
|
long,
|
||||||
|
default_value = "nixbld",
|
||||||
|
env = "HARMONIC_NIX_BUILD_GROUP_NAME",
|
||||||
|
global = true
|
||||||
|
)
|
||||||
)]
|
)]
|
||||||
pub(crate) nix_build_group_name: String,
|
pub(crate) nix_build_group_name: String,
|
||||||
|
|
||||||
/// The Nix build group GID
|
/// The Nix build group GID
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "cli",
|
feature = "cli",
|
||||||
clap(long, default_value_t = 3000, env = "HARMONIC_NIX_BUILD_GROUP_ID")
|
clap(
|
||||||
|
long,
|
||||||
|
default_value_t = 3000,
|
||||||
|
env = "HARMONIC_NIX_BUILD_GROUP_ID",
|
||||||
|
global = true
|
||||||
|
)
|
||||||
)]
|
)]
|
||||||
pub(crate) nix_build_group_id: usize,
|
pub(crate) nix_build_group_id: usize,
|
||||||
|
|
||||||
/// The Nix build user prefix (user numbers will be postfixed)
|
/// The Nix build user prefix (user numbers will be postfixed)
|
||||||
#[cfg_attr(feature = "cli", clap(long, env = "HARMONIC_NIX_BUILD_USER_PREFIX"))]
|
#[cfg_attr(
|
||||||
|
feature = "cli",
|
||||||
|
clap(long, env = "HARMONIC_NIX_BUILD_USER_PREFIX", global = true)
|
||||||
|
)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
all(target_os = "macos", feature = "cli"),
|
all(target_os = "macos", feature = "cli"),
|
||||||
clap(default_value = "_nixbld")
|
clap(default_value = "_nixbld")
|
||||||
|
@ -90,7 +110,10 @@ pub struct CommonSettings {
|
||||||
pub(crate) nix_build_user_prefix: String,
|
pub(crate) nix_build_user_prefix: String,
|
||||||
|
|
||||||
/// The Nix build user base UID (ascending)
|
/// The Nix build user base UID (ascending)
|
||||||
#[cfg_attr(feature = "cli", clap(long, env = "HARMONIC_NIX_BUILD_USER_ID_BASE"))]
|
#[cfg_attr(
|
||||||
|
feature = "cli",
|
||||||
|
clap(long, env = "HARMONIC_NIX_BUILD_USER_ID_BASE", global = true)
|
||||||
|
)]
|
||||||
#[cfg_attr(all(target_os = "macos", feature = "cli"), clap(default_value_t = 300))]
|
#[cfg_attr(all(target_os = "macos", feature = "cli"), clap(default_value_t = 300))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
all(target_os = "linux", feature = "cli"),
|
all(target_os = "linux", feature = "cli"),
|
||||||
|
@ -99,7 +122,10 @@ pub struct CommonSettings {
|
||||||
pub(crate) nix_build_user_id_base: usize,
|
pub(crate) nix_build_user_id_base: usize,
|
||||||
|
|
||||||
/// The Nix package URL
|
/// The Nix package URL
|
||||||
#[cfg_attr(feature = "cli", clap(long, env = "HARMONIC_NIX_PACKAGE_URL"))]
|
#[cfg_attr(
|
||||||
|
feature = "cli",
|
||||||
|
clap(long, env = "HARMONIC_NIX_PACKAGE_URL", global = true)
|
||||||
|
)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
all(target_os = "macos", target_arch = "x86_64", feature = "cli"),
|
all(target_os = "macos", target_arch = "x86_64", feature = "cli"),
|
||||||
clap(
|
clap(
|
||||||
|
@ -127,7 +153,7 @@ pub struct CommonSettings {
|
||||||
pub(crate) nix_package_url: Url,
|
pub(crate) nix_package_url: Url,
|
||||||
|
|
||||||
/// Extra configuration lines for `/etc/nix.conf`
|
/// Extra configuration lines for `/etc/nix.conf`
|
||||||
#[cfg_attr(feature = "cli", clap(long, env = "HARMONIC_EXTRA_CONF"))]
|
#[cfg_attr(feature = "cli", clap(long, action = ArgAction::Set, num_args = 0.., value_delimiter = ',', env = "HARMONIC_EXTRA_CONF", global = true))]
|
||||||
pub extra_conf: Vec<String>,
|
pub extra_conf: Vec<String>,
|
||||||
|
|
||||||
/// If Harmonic should forcibly recreate files it finds existing
|
/// If Harmonic should forcibly recreate files it finds existing
|
||||||
|
|
Loading…
Reference in a new issue