diff --git a/CHANGELOG.md b/CHANGELOG.md index c4c63d3..155cb7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Revision history for Arion +## Next + +### Changed + +* Healthcheck-based dependencies in `service.depends_on`. + +### Added + +* Support `service.healthcheck` for defining custom healthchecks. + ## 0.1.3.0 -- 2020-05-03 ### Changed diff --git a/docs/modules/ROOT/partials/NixOSOptions.adoc b/docs/modules/ROOT/partials/NixOSOptions.adoc index 3ba49a3..690b23b 100644 --- a/docs/modules/ROOT/partials/NixOSOptions.adoc +++ b/docs/modules/ROOT/partials/NixOSOptions.adoc @@ -514,7 +514,7 @@ See link:https://docs.docker.com/compose/compose-file/#depends_on[Docker Compose [discrete] === details -Type:: list of strings +Type:: list of strings or attribute set of submodules Default:: + ---- @@ -668,6 +668,123 @@ Default:: No Example:: {blank} +== services..service.healthcheck + +None + +[discrete] +=== details + +Type:: submodule +No Default:: {blank} + +No Example:: {blank} + +== services..service.healthcheck.interval + +See link:https://docs.docker.com/compose/compose-file/#healthcheck[Docker Compose#healthcheck] + +[discrete] +=== details + +Type:: string +Default:: ++ +---- +"30s" +---- + + +Example:: ++ +---- +"1m" +---- + + +== services..service.healthcheck.retries + +See link:https://docs.docker.com/compose/compose-file/#healthcheck[Docker Compose#healthcheck] + +[discrete] +=== details + +Type:: signed integer +Default:: ++ +---- +3 +---- + + +No Example:: {blank} + +== services..service.healthcheck.start_period + +See link:https://docs.docker.com/compose/compose-file/#healthcheck[Docker Compose#healthcheck] + +[discrete] +=== details + +Type:: string +Default:: ++ +---- +"0s" +---- + + +Example:: ++ +---- +"30s" +---- + + +== services..service.healthcheck.test + +See link:https://docs.docker.com/compose/compose-file/#healthcheck[Docker Compose#healthcheck] + +[discrete] +=== details + +Type:: null or list of strings +Default:: ++ +---- +null +---- + + +Example:: ++ +---- +["CMD","pg_isready"] +---- + + +== services..service.healthcheck.timeout + +See link:https://docs.docker.com/compose/compose-file/#healthcheck[Docker Compose#healthcheck] + +[discrete] +=== details + +Type:: string +Default:: ++ +---- +"30s" +---- + + +Example:: ++ +---- +"10s" +---- + + == services..service.hostStoreAsReadOnly Adds a ':ro' (read-only) access mode to the host nix store bind mount. diff --git a/src/nix/modules/service/docker-compose-service.nix b/src/nix/modules/service/docker-compose-service.nix index 385cff0..6b64e84 100644 --- a/src/nix/modules/service/docker-compose-service.nix +++ b/src/nix/modules/service/docker-compose-service.nix @@ -4,11 +4,11 @@ the user-facing options service.image, service.volumes, etc. */ -{ pkgs, lib, config, ... }: +{ pkgs, lib, config, options, ... }: let inherit (lib) mkOption types; - inherit (types) listOf nullOr attrsOf str either int bool; + inherit (types) listOf nullOr attrsOf str either int bool submodule enum; link = url: text: ''link:${url}[${text}]''; @@ -100,10 +100,61 @@ in default = null; description = dockerComposeRef "container_name"; }; - service.depends_on = mkOption { - type = listOf str; - default = []; - description = dockerComposeRef "depends_on"; + service.depends_on = + let conditionsModule = { + options = { + condition = mkOption { + type = enum ["service_started" "service_healthy" "service_completed_successfully"]; + description = dockerComposeRef "depends_on"; + default = "service_started"; + }; + }; + }; + in mkOption { + type = either (listOf str) (attrsOf (submodule conditionsModule)); + default = []; + description = dockerComposeRef "depends_on"; + }; + service.healthcheck = mkOption { + type = submodule ({ config, options, ...}: { + options = { + _out = mkOption { + internal = true; + default = lib.optionalAttrs (options.test.highestPrio < 1500) { + inherit (config) test interval timeout start_period retries; + }; + }; + test = mkOption { + type = nullOr (listOf str); + default = null; + example = [ "CMD" "pg_isready" ]; + description = dockerComposeRef "healthcheck"; + }; + interval = mkOption { + type = str; + default = "30s"; + example = "1m"; + description = dockerComposeRef "healthcheck"; + }; + timeout = mkOption { + type = str; + default = "30s"; + example = "10s"; + description = dockerComposeRef "healthcheck"; + }; + start_period = mkOption { + type = str; + default = "0s"; + example = "30s"; + description = dockerComposeRef "healthcheck"; + }; + retries = mkOption { + type = int; + default = 3; + description = dockerComposeRef "healthcheck"; + }; + }; + }); }; service.devices = mkOption { type = listOf str; @@ -250,6 +301,8 @@ in inherit (config.service) container_name; } // lib.optionalAttrs (config.service.depends_on != []) { inherit (config.service) depends_on; + } // lib.optionalAttrs (options.service.healthcheck.highestPrio < 1500) { + healthcheck = config.service.healthcheck._out; } // lib.optionalAttrs (config.service.devices != []) { inherit (config.service) devices; } // lib.optionalAttrs (config.service.entrypoint != null) {