Merge pull request #8351 from obsidiansystems/delete-profiles-tests-docs
Expanding tests and docs relating to deleting profiles
This commit is contained in:
commit
946cd9e3f9
|
@ -1,6 +1,6 @@
|
||||||
# Name
|
# Name
|
||||||
|
|
||||||
`nix-collect-garbage` - delete unreachable store paths
|
`nix-collect-garbage` - delete unreachable [store objects]
|
||||||
|
|
||||||
# Synopsis
|
# Synopsis
|
||||||
|
|
||||||
|
@ -8,17 +8,57 @@
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
The command `nix-collect-garbage` is mostly an alias of [`nix-store
|
The command `nix-collect-garbage` is mostly an alias of [`nix-store --gc`](@docroot@/command-ref/nix-store/gc.md).
|
||||||
--gc`](@docroot@/command-ref/nix-store/gc.md), that is, it deletes all
|
That is, it deletes all unreachable [store objects] in the Nix store to clean up your system.
|
||||||
unreachable paths in the Nix store to clean up your system. However,
|
|
||||||
it provides two additional options: `-d` (`--delete-old`), which
|
However, it provides two additional options,
|
||||||
deletes all old generations of all profiles in `/nix/var/nix/profiles`
|
[`--delete-old`](#opt-delete-old) and [`--delete-older-than`](#opt-delete-older-than),
|
||||||
by invoking `nix-env --delete-generations old` on all profiles (of
|
which also delete old [profiles], allowing potentially more [store objects] to be deleted because profiles are also garbage collection roots.
|
||||||
course, this makes rollbacks to previous configurations impossible);
|
These options are the equivalent of running
|
||||||
and `--delete-older-than` *period*, where period is a value such as
|
[`nix-env --delete-generations`](@docroot@/command-ref/nix-env/delete-generations.md)
|
||||||
`30d`, which deletes all generations older than the specified number
|
with various augments on multiple profiles,
|
||||||
of days in all profiles in `/nix/var/nix/profiles` (except for the
|
prior to running `nix-collect-garbage` (or just `nix-store --gc`) without any flags.
|
||||||
generations that were active at that point in time).
|
|
||||||
|
> **Note**
|
||||||
|
>
|
||||||
|
> Deleting previous configurations makes rollbacks to them impossible.
|
||||||
|
|
||||||
|
These flags should be used with care, because they potentially delete generations of profiles used by other users on the system.
|
||||||
|
|
||||||
|
## Locations searched for profiles
|
||||||
|
|
||||||
|
`nix-collect-garbage` cannot know about all profiles; that information doesn't exist.
|
||||||
|
Instead, it looks in a few locations, and acts on all profiles it finds there:
|
||||||
|
|
||||||
|
1. The default profile locations as specified in the [profiles] section of the manual.
|
||||||
|
|
||||||
|
2. > **NOTE**
|
||||||
|
>
|
||||||
|
> Not stable; subject to change
|
||||||
|
>
|
||||||
|
> Do not rely on this functionality; it just exists for migration purposes and is may change in the future.
|
||||||
|
> These deprecated paths remain a private implementation detail of Nix.
|
||||||
|
|
||||||
|
`$NIX_STATE_DIR/profiles` and `$NIX_STATE_DIR/profiles/per-user`.
|
||||||
|
|
||||||
|
With the exception of `$NIX_STATE_DIR/profiles/per-user/root` and `$NIX_STATE_DIR/profiles/default`, these directories are no longer used by other commands.
|
||||||
|
`nix-collect-garbage` looks there anyways in order to clean up profiles from older versions of Nix.
|
||||||
|
|
||||||
|
# Options
|
||||||
|
|
||||||
|
These options are for deleting old [profiles] prior to deleting unreachable [store objects].
|
||||||
|
|
||||||
|
- <span id="opt-delete-old">[`--delete-old`](#opt-delete-old)</span> / `-d`\
|
||||||
|
Delete all old generations of profiles.
|
||||||
|
|
||||||
|
This is the equivalent of invoking `nix-env --delete-generations old` on each found profile.
|
||||||
|
|
||||||
|
- <span id="opt-delete-older-than">[`--delete-older-than`](#opt-delete-older-than)</span> *period*\
|
||||||
|
Delete all generations of profiles older than the specified amount (except for the generations that were active at that point in time).
|
||||||
|
*period* is a value such as `30d`, which would mean 30 days.
|
||||||
|
|
||||||
|
This is the equivalent of invoking [`nix-env --delete-generations <period>`](@docroot@/command-ref/nix-env/delete-generations.md#generations-days) on each found profile.
|
||||||
|
See the documentation of that command for additional information about the *period* argument.
|
||||||
|
|
||||||
{{#include ./opt-common.md}}
|
{{#include ./opt-common.md}}
|
||||||
|
|
||||||
|
@ -32,3 +72,6 @@ generations of each profile, do
|
||||||
```console
|
```console
|
||||||
$ nix-collect-garbage -d
|
$ nix-collect-garbage -d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[profiles]: @docroot@/command-ref/files/profiles.md
|
||||||
|
[store objects]: @docroot@/glossary.md#gloss-store-object
|
||||||
|
|
|
@ -9,14 +9,39 @@
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
This operation deletes the specified generations of the current profile.
|
This operation deletes the specified generations of the current profile.
|
||||||
The generations can be a list of generation numbers, the special value
|
|
||||||
`old` to delete all non-current generations, a value such as `30d` to
|
*generations* can be a one of the following:
|
||||||
delete all generations older than the specified number of days (except
|
|
||||||
for the generation that was active at that point in time), or a value
|
- <span id="generations-list">`<number>...`</span>:\
|
||||||
such as `+5` to keep the last `5` generations ignoring any newer than
|
A list of generation numbers, each one a separate command-line argument.
|
||||||
current, e.g., if `30` is the current generation `+5` will delete
|
|
||||||
generation `25` and all older generations. Periodically deleting old
|
Delete exactly the profile generations given by their generation number.
|
||||||
generations is important to make garbage collection effective.
|
Deleting the current generation is not allowed.
|
||||||
|
|
||||||
|
- The special value <span id="generations-old">`old`</span>
|
||||||
|
|
||||||
|
Delete all generations older than the current one.
|
||||||
|
|
||||||
|
- <span id="generations-days">`<days>d`</span>:\
|
||||||
|
The last *days* days
|
||||||
|
|
||||||
|
*Example*: `30d`
|
||||||
|
|
||||||
|
Delete all generations older than *days* days.
|
||||||
|
The generation that was active at that point in time is excluded, and will not be deleted.
|
||||||
|
|
||||||
|
- <span id="generations-count">`+<count>`</span>:\
|
||||||
|
The last *count* generations up to the present
|
||||||
|
|
||||||
|
*Example*: `+5`
|
||||||
|
|
||||||
|
Keep the last *count* generations, along with any newer than current.
|
||||||
|
|
||||||
|
Periodically deleting old generations is important to make garbage collection
|
||||||
|
effective.
|
||||||
|
The is because profiles are also garbage collection roots — any [store object] reachable from a profile is "alive" and ineligible for deletion.
|
||||||
|
|
||||||
|
[store object]: @docroot@/glossary.md#gloss-store-object
|
||||||
|
|
||||||
{{#include ./opt-common.md}}
|
{{#include ./opt-common.md}}
|
||||||
|
|
||||||
|
@ -28,19 +53,35 @@ generations is important to make garbage collection effective.
|
||||||
|
|
||||||
# Examples
|
# Examples
|
||||||
|
|
||||||
|
## Delete explicit generation numbers
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ nix-env --delete-generations 3 4 8
|
$ nix-env --delete-generations 3 4 8
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Delete the generations numbered 3, 4, and 8, so long as the current active generation is not any of those.
|
||||||
|
|
||||||
|
## Keep most-recent by count count
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ nix-env --delete-generations +5
|
$ nix-env --delete-generations +5
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Suppose `30` is the current generation, and we currently have generations numbered `20` through `32`.
|
||||||
|
|
||||||
|
Then this command will delete generations `20` through `25` (`<= 30 - 5`),
|
||||||
|
and keep generations `26` through `31` (`> 30 - 5`).
|
||||||
|
|
||||||
|
## Keep most-recent in days
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ nix-env --delete-generations 30d
|
$ nix-env --delete-generations 30d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This command will delete all generations older than 30 days, except for the generation that was active 30 days ago (if it currently exists).
|
||||||
|
|
||||||
|
## Delete all older
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ nix-env --profile other_profile --delete-generations old
|
$ nix-env --profile other_profile --delete-generations old
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
28
tests/gc.sh
28
tests/gc.sh
|
@ -50,31 +50,3 @@ if test -e $outPath/foobar; then false; fi
|
||||||
# Check that the store is empty.
|
# Check that the store is empty.
|
||||||
rmdir $NIX_STORE_DIR/.links
|
rmdir $NIX_STORE_DIR/.links
|
||||||
rmdir $NIX_STORE_DIR
|
rmdir $NIX_STORE_DIR
|
||||||
|
|
||||||
## Test `nix-collect-garbage -d`
|
|
||||||
testCollectGarbageD () {
|
|
||||||
clearProfiles
|
|
||||||
# Run two `nix-env` commands, should create two generations of
|
|
||||||
# the profile
|
|
||||||
nix-env -f ./user-envs.nix -i foo-1.0
|
|
||||||
nix-env -f ./user-envs.nix -i foo-2.0pre1
|
|
||||||
[[ $(nix-env --list-generations | wc -l) -eq 2 ]]
|
|
||||||
|
|
||||||
# Clear the profile history. There should be only one generation
|
|
||||||
# left
|
|
||||||
nix-collect-garbage -d
|
|
||||||
[[ $(nix-env --list-generations | wc -l) -eq 1 ]]
|
|
||||||
}
|
|
||||||
# `nix-env` doesn't work with CA derivations, so let's ignore that bit if we're
|
|
||||||
# using them
|
|
||||||
if [[ -z "${NIX_TESTS_CA_BY_DEFAULT:-}" ]]; then
|
|
||||||
testCollectGarbageD
|
|
||||||
|
|
||||||
# Run the same test, but forcing the profiles at their legacy location under
|
|
||||||
# /nix/var/nix.
|
|
||||||
#
|
|
||||||
# Regression test for #8294
|
|
||||||
rm ~/.nix-profile
|
|
||||||
ln -s $NIX_STATE_DIR/profiles/per-user/me ~/.nix-profile
|
|
||||||
testCollectGarbageD
|
|
||||||
fi
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ nix_tests = \
|
||||||
flakes/flake-in-submodule.sh \
|
flakes/flake-in-submodule.sh \
|
||||||
ca/gc.sh \
|
ca/gc.sh \
|
||||||
gc.sh \
|
gc.sh \
|
||||||
|
nix-collect-garbage-d.sh \
|
||||||
remote-store.sh \
|
remote-store.sh \
|
||||||
legacy-ssh-store.sh \
|
legacy-ssh-store.sh \
|
||||||
lang.sh \
|
lang.sh \
|
||||||
|
|
40
tests/nix-collect-garbage-d.sh
Normal file
40
tests/nix-collect-garbage-d.sh
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
source common.sh
|
||||||
|
|
||||||
|
clearStore
|
||||||
|
|
||||||
|
## Test `nix-collect-garbage -d`
|
||||||
|
|
||||||
|
# TODO make `nix-env` doesn't work with CA derivations, and make
|
||||||
|
# `ca/nix-collect-garbage-d.sh` wrapper.
|
||||||
|
|
||||||
|
testCollectGarbageD () {
|
||||||
|
clearProfiles
|
||||||
|
# Run two `nix-env` commands, should create two generations of
|
||||||
|
# the profile
|
||||||
|
nix-env -f ./user-envs.nix -i foo-1.0 "$@"
|
||||||
|
nix-env -f ./user-envs.nix -i foo-2.0pre1 "$@"
|
||||||
|
[[ $(nix-env --list-generations "$@" | wc -l) -eq 2 ]]
|
||||||
|
|
||||||
|
# Clear the profile history. There should be only one generation
|
||||||
|
# left
|
||||||
|
nix-collect-garbage -d
|
||||||
|
[[ $(nix-env --list-generations "$@" | wc -l) -eq 1 ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
testCollectGarbageD
|
||||||
|
|
||||||
|
# Run the same test, but forcing the profiles an arbitrary location.
|
||||||
|
rm ~/.nix-profile
|
||||||
|
ln -s $TEST_ROOT/blah ~/.nix-profile
|
||||||
|
testCollectGarbageD
|
||||||
|
|
||||||
|
# Run the same test, but forcing the profiles at their legacy location under
|
||||||
|
# /nix/var/nix.
|
||||||
|
#
|
||||||
|
# Note that we *don't* use the default profile; `nix-collect-garbage` will
|
||||||
|
# need to check the legacy conditional unconditionally not just follow
|
||||||
|
# `~/.nix-profile` to pass this test.
|
||||||
|
#
|
||||||
|
# Regression test for #8294
|
||||||
|
rm ~/.nix-profile
|
||||||
|
testCollectGarbageD --profile "$NIX_STATE_DIR/profiles/per-user/me"
|
Loading…
Reference in a new issue