docker: add option to prune all volumes when auto pruning (#508604)
This commit is contained in:
@@ -157,6 +157,14 @@ in
|
||||
Whether to periodically prune Docker resources. If enabled, a
|
||||
systemd timer will run `docker system prune -f`
|
||||
as specified by the `dates` option.
|
||||
|
||||
NOTE: by default this does not prune volumes. Anonymous volumes
|
||||
can be pruned by passing "--volumes" to [autoPrune.flags](#opt-virtualisation.docker.autoPrune.flags).
|
||||
|
||||
To prune all volumes (not just anonymous ones) [`autoPrune.allVolumes.enable`](#opt-virtualisation.docker.autoPrune.allVolumes.enable)
|
||||
must be used.
|
||||
|
||||
See [upstream documentation](https://docs.docker.com/reference/cli/docker/system/prune/#description) for further information.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -206,6 +214,28 @@ in
|
||||
system was powered down.
|
||||
'';
|
||||
};
|
||||
|
||||
allVolumes = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to periodically prune all Docker volumes when auto pruning other docker resources
|
||||
by running {command}`docker volume prune --force --all`
|
||||
|
||||
To prune only anonymous volumes, instead pass `--volumes` to `autoPrune.flags`
|
||||
'';
|
||||
};
|
||||
|
||||
flags = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "--filter=label=<label>" ];
|
||||
description = ''
|
||||
Any additional flags passed to {command}`docker volume prune --force --all`.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "docker" { };
|
||||
@@ -312,15 +342,29 @@ in
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = utils.escapeSystemdExecArgs (
|
||||
[
|
||||
(lib.getExe cfg.package)
|
||||
"system"
|
||||
"prune"
|
||||
"-f"
|
||||
]
|
||||
++ cfg.autoPrune.flags
|
||||
);
|
||||
ExecStart = [
|
||||
(utils.escapeSystemdExecArgs (
|
||||
[
|
||||
(lib.getExe cfg.package)
|
||||
"system"
|
||||
"prune"
|
||||
"-f"
|
||||
]
|
||||
++ cfg.autoPrune.flags
|
||||
))
|
||||
]
|
||||
++ (optionals cfg.autoPrune.allVolumes.enable [
|
||||
(utils.escapeSystemdExecArgs (
|
||||
[
|
||||
(lib.getExe cfg.package)
|
||||
"volume"
|
||||
"prune"
|
||||
"--force"
|
||||
"--all"
|
||||
]
|
||||
++ cfg.autoPrune.allVolumes.flags
|
||||
))
|
||||
]);
|
||||
};
|
||||
|
||||
startAt = optional cfg.autoPrune.enable cfg.autoPrune.dates;
|
||||
@@ -342,6 +386,10 @@ in
|
||||
-> config.hardware.graphics.enable32Bit or false;
|
||||
message = "Option enableNvidia on x86_64 requires 32-bit support libraries";
|
||||
}
|
||||
{
|
||||
assertion = cfg.autoPrune.allVolumes.enable -> cfg.autoPrune.enable;
|
||||
message = "Option autoPrune.allVolumes.enable requires autoPrune.enable";
|
||||
}
|
||||
];
|
||||
|
||||
virtualisation.docker.daemon.settings = {
|
||||
|
||||
@@ -467,6 +467,7 @@ in
|
||||
dnsdist = import ./dnsdist.nix { inherit pkgs runTest; };
|
||||
doas = runTest ./doas.nix;
|
||||
docker = runTestOn [ "aarch64-linux" "x86_64-linux" ] ./docker.nix;
|
||||
docker-autoprune = runTestOn [ "aarch64-linux" "x86_64-linux" ] ./docker-autoprune.nix;
|
||||
docker-registry = runTest ./docker-registry.nix;
|
||||
docker-rootless = runTestOn [ "aarch64-linux" "x86_64-linux" ] ./docker-rootless.nix;
|
||||
docker-tools = runTestOn [ "x86_64-linux" ] ./docker-tools.nix;
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
# This test validates the docker autoprune service, testing whether
|
||||
# the default configuration cleans up images, while leaving volumes intact
|
||||
# and whether the allVolumes option enables cleaning up volumes as well
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
name = "docker";
|
||||
|
||||
nodes = {
|
||||
prune =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
virtualisation.docker = {
|
||||
enable = true;
|
||||
package = pkgs.docker;
|
||||
autoPrune = {
|
||||
enable = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
prunevolumes =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
virtualisation.docker = {
|
||||
enable = true;
|
||||
package = pkgs.docker;
|
||||
autoPrune = {
|
||||
enable = true;
|
||||
allVolumes.enable = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
|
||||
with subtest("Check whether autoPrune works. Volumes should be left unpruned."):
|
||||
prune.wait_for_unit("sockets.target")
|
||||
prune.succeed("docker network create testnetwork")
|
||||
prune.succeed("docker network list --format json | grep testnetwork")
|
||||
prune.succeed("docker volume create testvolume")
|
||||
prune.succeed("docker volume list --format json | grep testvolume")
|
||||
|
||||
prune.succeed("systemctl start -v docker-prune")
|
||||
prune.fail("docker network list --format json | grep testnetwork")
|
||||
# the volume has been left alone
|
||||
prune.succeed("docker volume list --format json | grep testvolume")
|
||||
|
||||
with subtest("Check whether autoPrune including volumes works"):
|
||||
prunevolumes.wait_for_unit("sockets.target")
|
||||
prunevolumes.succeed("docker volume create testvolume")
|
||||
prunevolumes.succeed("docker volume list --format json | grep testvolume")
|
||||
|
||||
prunevolumes.succeed("systemctl start -v docker-prune")
|
||||
prunevolumes.fail("docker volume list --format json | grep testvolume")
|
||||
'';
|
||||
}
|
||||
Reference in New Issue
Block a user