From ec8ef96d52a72d05b9ed8d7565416946093daa94 Mon Sep 17 00:00:00 2001 From: t4ccer Date: Tue, 26 Apr 2022 18:19:56 -0600 Subject: [PATCH 1/4] Add service.healthcheck and extend service.depends_on --- CHANGELOG.md | 10 +++ docs/modules/ROOT/partials/NixOSOptions.adoc | 85 ++++++++++++++++++- .../service/docker-compose-service.nix | 27 +++++- 3 files changed, 120 insertions(+), 2 deletions(-) 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..a12edb3 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 attribute set of stringss Default:: + ---- @@ -668,6 +668,89 @@ Default:: 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.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..039e8d7 100644 --- a/src/nix/modules/service/docker-compose-service.nix +++ b/src/nix/modules/service/docker-compose-service.nix @@ -101,10 +101,33 @@ in description = dockerComposeRef "container_name"; }; service.depends_on = mkOption { - type = listOf str; + type = either (listOf str) (attrsOf (attrsOf str)); default = []; description = dockerComposeRef "depends_on"; }; + service.healthcheck.test = mkOption { + type = nullOr (listOf str); + default = null; + example = [ "CMD" "pg_isready" ]; + description = dockerComposeRef "healthcheck"; + }; + service.healthcheck.interval = mkOption { + type = str; + default = "30s"; + example = "1m"; + description = dockerComposeRef "healthcheck"; + }; + service.healthcheck.timeout = mkOption { + type = str; + default = "30s"; + example = "10s"; + description = dockerComposeRef "healthcheck"; + }; + service.healthcheck.retries = mkOption { + type = int; + default = 3; + description = dockerComposeRef "healthcheck"; + }; service.devices = mkOption { type = listOf str; default = []; @@ -250,6 +273,8 @@ in inherit (config.service) container_name; } // lib.optionalAttrs (config.service.depends_on != []) { inherit (config.service) depends_on; + } // lib.optionalAttrs (config.service.healthcheck.test != null) { + inherit (config.service) healthcheck; } // lib.optionalAttrs (config.service.devices != []) { inherit (config.service) devices; } // lib.optionalAttrs (config.service.entrypoint != null) { From cf20442a7a8294701e082a629c9eab0d35a8148c Mon Sep 17 00:00:00 2001 From: t4ccer Date: Wed, 27 Apr 2022 12:53:06 -0600 Subject: [PATCH 2/4] Add `service.healthcheck.start_period` option --- docs/modules/ROOT/partials/NixOSOptions.adoc | 22 +++++++++++++++++++ .../service/docker-compose-service.nix | 6 +++++ 2 files changed, 28 insertions(+) diff --git a/docs/modules/ROOT/partials/NixOSOptions.adoc b/docs/modules/ROOT/partials/NixOSOptions.adoc index a12edb3..8e22a6a 100644 --- a/docs/modules/ROOT/partials/NixOSOptions.adoc +++ b/docs/modules/ROOT/partials/NixOSOptions.adoc @@ -707,6 +707,28 @@ Default:: 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] diff --git a/src/nix/modules/service/docker-compose-service.nix b/src/nix/modules/service/docker-compose-service.nix index 039e8d7..0b307af 100644 --- a/src/nix/modules/service/docker-compose-service.nix +++ b/src/nix/modules/service/docker-compose-service.nix @@ -123,6 +123,12 @@ in example = "10s"; description = dockerComposeRef "healthcheck"; }; + service.healthcheck.start_period = mkOption { + type = str; + default = "0s"; + example = "30s"; + description = dockerComposeRef "healthcheck"; + }; service.healthcheck.retries = mkOption { type = int; default = 3; From 69b9109dea2b4d48f35c614456463bd0234e2e80 Mon Sep 17 00:00:00 2001 From: t4ccer Date: Wed, 27 Apr 2022 14:23:25 -0600 Subject: [PATCH 3/4] Define module for detailed `depends_on` options --- docs/modules/ROOT/partials/NixOSOptions.adoc | 2 +- .../service/docker-compose-service.nix | 20 ++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/docs/modules/ROOT/partials/NixOSOptions.adoc b/docs/modules/ROOT/partials/NixOSOptions.adoc index 8e22a6a..2565739 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 or attribute set of attribute set of stringss +Type:: list of strings or attribute set of submodules Default:: + ---- diff --git a/src/nix/modules/service/docker-compose-service.nix b/src/nix/modules/service/docker-compose-service.nix index 0b307af..edfeada 100644 --- a/src/nix/modules/service/docker-compose-service.nix +++ b/src/nix/modules/service/docker-compose-service.nix @@ -8,7 +8,7 @@ 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,20 @@ in default = null; description = dockerComposeRef "container_name"; }; - service.depends_on = mkOption { - type = either (listOf str) (attrsOf (attrsOf 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.test = mkOption { type = nullOr (listOf str); From fb5ab7b76fdb035bd3106d22b1c3eba353121d24 Mon Sep 17 00:00:00 2001 From: t4ccer Date: Wed, 27 Apr 2022 19:43:16 -0600 Subject: [PATCH 4/4] Move healthcheck options to `healthcheck` submodule --- docs/modules/ROOT/partials/NixOSOptions.adoc | 12 +++ .../service/docker-compose-service.nix | 76 +++++++++++-------- 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/docs/modules/ROOT/partials/NixOSOptions.adoc b/docs/modules/ROOT/partials/NixOSOptions.adoc index 2565739..690b23b 100644 --- a/docs/modules/ROOT/partials/NixOSOptions.adoc +++ b/docs/modules/ROOT/partials/NixOSOptions.adoc @@ -666,6 +666,18 @@ Default:: ---- +No Example:: {blank} + +== services..service.healthcheck + +None + +[discrete] +=== details + +Type:: submodule +No Default:: {blank} + No Example:: {blank} == services..service.healthcheck.interval diff --git a/src/nix/modules/service/docker-compose-service.nix b/src/nix/modules/service/docker-compose-service.nix index edfeada..6b64e84 100644 --- a/src/nix/modules/service/docker-compose-service.nix +++ b/src/nix/modules/service/docker-compose-service.nix @@ -4,7 +4,7 @@ the user-facing options service.image, service.volumes, etc. */ -{ pkgs, lib, config, ... }: +{ pkgs, lib, config, options, ... }: let inherit (lib) mkOption types; @@ -114,35 +114,47 @@ in type = either (listOf str) (attrsOf (submodule conditionsModule)); default = []; description = dockerComposeRef "depends_on"; - }; - service.healthcheck.test = mkOption { - type = nullOr (listOf str); - default = null; - example = [ "CMD" "pg_isready" ]; - description = dockerComposeRef "healthcheck"; - }; - service.healthcheck.interval = mkOption { - type = str; - default = "30s"; - example = "1m"; - description = dockerComposeRef "healthcheck"; - }; - service.healthcheck.timeout = mkOption { - type = str; - default = "30s"; - example = "10s"; - description = dockerComposeRef "healthcheck"; - }; - service.healthcheck.start_period = mkOption { - type = str; - default = "0s"; - example = "30s"; - description = dockerComposeRef "healthcheck"; - }; - service.healthcheck.retries = mkOption { - type = int; - default = 3; - description = dockerComposeRef "healthcheck"; + }; + 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; @@ -289,8 +301,8 @@ in inherit (config.service) container_name; } // lib.optionalAttrs (config.service.depends_on != []) { inherit (config.service) depends_on; - } // lib.optionalAttrs (config.service.healthcheck.test != null) { - inherit (config.service) healthcheck; + } // 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) {