diff --git a/arion-compose.cabal b/arion-compose.cabal index 3aa58b0..6b0c14b 100644 --- a/arion-compose.cabal +++ b/arion-compose.cabal @@ -17,6 +17,7 @@ extra-source-files: CHANGELOG.md, README.asciidoc, src/haskell/testdata/**/*.json data-files: nix/*.nix , nix/modules/composition/*.nix + , nix/modules/networks/*.nix , nix/modules/nixos/*.nix , nix/modules/service/*.nix , nix/modules/lib/*.nix diff --git a/docs/modules/ROOT/partials/NixOSOptions.adoc b/docs/modules/ROOT/partials/NixOSOptions.adoc index eb34a3d..76ad2a4 100644 --- a/docs/modules/ROOT/partials/NixOSOptions.adoc +++ b/docs/modules/ROOT/partials/NixOSOptions.adoc @@ -70,6 +70,169 @@ No Default:: {blank} No Example:: {blank} +== networks + +See link:https://docs.docker.com/compose/compose-file/#networks-top-level-element[Docker Compose#networks-top-level-element] + + +[discrete] +=== details + +Type:: lazy attribute set of submodules +Default:: ++ +---- +{} +---- + + +No Example:: {blank} + +== networks..attachable + +See link:https://docs.docker.com/compose/compose-file/#attachable[Docker Compose#attachable] + + +[discrete] +=== details + +Type:: boolean +No Default:: {blank} + +Example:: ++ +---- +true +---- + + +== networks..driver + +`"none"`, `"host"`, or a platform-specific value. +See link:https://docs.docker.com/compose/compose-file/#driver[Docker Compose#driver] + + +[discrete] +=== details + +Type:: string +No Default:: {blank} + +No Example:: {blank} + +== networks..driver_opts + +See link:https://docs.docker.com/compose/compose-file/#driver_opts[Docker Compose#driver_opts] + + +[discrete] +=== details + +Type:: lazy attribute set of raw values +No Default:: {blank} + +No Example:: {blank} + +== networks..enable_ipv6 + +Whether we've entered the 21st century yet. + +See link:https://docs.docker.com/compose/compose-file/#enable_ipv6[Docker Compose#enable_ipv6] + + +[discrete] +=== details + +Type:: boolean +No Default:: {blank} + +No Example:: {blank} + +== networks..external + +When `true`, don't create or destroy the network, but assume that it +exists. + +See link:https://docs.docker.com/compose/compose-file/#external[Docker Compose#external] + + +[discrete] +=== details + +Type:: boolean +No Default:: {blank} + +No Example:: {blank} + +== networks..internal + +Achieves "external isolation". + +See link:https://docs.docker.com/compose/compose-file/#internal[Docker Compose#internal] + + +[discrete] +=== details + +Type:: boolean +Default:: ++ +---- +false +---- + + +No Example:: {blank} + +== networks..ipam + +Manage IP addresses. + +See link:https://docs.docker.com/compose/compose-file/#ipam[Docker Compose#ipam] + + +[discrete] +=== details + +Type:: raw value +No Default:: {blank} + +No Example:: {blank} + +== networks..labels + +Metadata. + +See link:https://docs.docker.com/compose/compose-file/#labels[Docker Compose#labels] + + +[discrete] +=== details + +Type:: attribute set of strings +No Default:: {blank} + +No Example:: {blank} + +== networks..name + +Set a custom name for the network. + +It shares a namespace with other projects' networks. `name` is used as-is. + +Note the `default` network's default `name` is set to `project.name` by Arion. + +See link:https://docs.docker.com/compose/compose-file/#name[Docker Compose#name] + + +[discrete] +=== details + +Type:: string +No Default:: {blank} + +No Example:: {blank} + == out.dockerComposeYaml A derivation that produces a docker-compose.yaml file for this composition. diff --git a/src/haskell/testdata/Arion/NixSpec/arion-compose.json b/src/haskell/testdata/Arion/NixSpec/arion-compose.json index c26d994..54e4c24 100644 --- a/src/haskell/testdata/Arion/NixSpec/arion-compose.json +++ b/src/haskell/testdata/Arion/NixSpec/arion-compose.json @@ -1,4 +1,5 @@ { + "networks": {}, "services": { "webserver": { "command": [ diff --git a/src/nix/modules.nix b/src/nix/modules.nix index ecc73c1..8c3251a 100644 --- a/src/nix/modules.nix +++ b/src/nix/modules.nix @@ -2,6 +2,7 @@ ./modules/composition/docker-compose.nix ./modules/composition/host-environment.nix ./modules/composition/images.nix + ./modules/composition/networks.nix ./modules/composition/service-info.nix ./modules/composition/composition.nix ] \ No newline at end of file diff --git a/src/nix/modules/composition/networks.nix b/src/nix/modules/composition/networks.nix new file mode 100644 index 0000000..6bbb181 --- /dev/null +++ b/src/nix/modules/composition/networks.nix @@ -0,0 +1,35 @@ +{ config, lib, ... }: + +let + inherit (lib) + mkOption + optionalAttrs + types + ; + inherit (import ../../lib.nix { inherit lib; }) + dockerComposeRef + ; +in +{ + options = { + networks = mkOption { + type = types.lazyAttrsOf (types.submoduleWith { + modules = [ + ../networks/network.nix + ]; + }); + description = '' + ${dockerComposeRef "networks-top-level-element"} + ''; + default = {}; + }; + }; + + + config = { + + docker-compose.raw.networks = + lib.mapAttrs (k: v: v.out) config.networks; + + }; +} diff --git a/src/nix/modules/networks/network.nix b/src/nix/modules/networks/network.nix new file mode 100644 index 0000000..16083b8 --- /dev/null +++ b/src/nix/modules/networks/network.nix @@ -0,0 +1,131 @@ +{ config, lib, options, ... }: + +let + inherit (lib) + mkOption + optionalAttrs + types + ; + inherit (import ../../lib.nix { inherit lib; }) + dockerComposeRef + ; +in +{ + options = { + driver = mkOption { + description = '' + `"none"`, `"host"`, or a platform-specific value. + ${dockerComposeRef "driver"} + ''; + type = types.str; + }; + + driver_opts = mkOption { + description = '' + ${dockerComposeRef "driver_opts"} + ''; + type = types.lazyAttrsOf types.raw or types.unspecified; + }; + + attachable = mkOption { + description = '' + ${dockerComposeRef "attachable"} + ''; + type = types.bool; + example = true; + }; + + enable_ipv6 = mkOption { + description = '' + Whether we've entered the 21st century yet. + + ${dockerComposeRef "enable_ipv6"} + ''; + type = types.bool; + }; + + ipam = mkOption { + # TODO model sub-options + description = '' + Manage IP addresses. + + ${dockerComposeRef "ipam"} + ''; + type = types.raw or types.unspecified; + }; + + internal = mkOption { + description = '' + Achieves "external isolation". + + ${dockerComposeRef "internal"} + ''; + defaultText = false; + type = types.bool; + }; + + labels = mkOption { + description = '' + Metadata. + + ${dockerComposeRef "labels"} + ''; + # no list support, because less expressive wrt overriding + type = types.attrsOf types.str; + }; + + external = mkOption { + description = '' + When `true`, don't create or destroy the network, but assume that it + exists. + + ${dockerComposeRef "external"} + ''; + type = types.bool; + }; + + name = mkOption { + description = '' + Set a custom name for the network. + + It shares a namespace with other projects' networks. `name` is used as-is. + + Note the `default` network's default `name` is set to `project.name` by Arion. + + ${dockerComposeRef "name"} + ''; + type = types.str; + }; + + out = mkOption { + internal = true; + description = '' + This network's contribution to the docker compose yaml file + under the `networks.''${name}` key. + ''; + type = lib.types.attrsOf lib.types.raw or lib.types.unspecified; + }; + }; + + config = { + out = + lib.mapAttrs + (k: opt: opt.value) + (lib.filterAttrs + (k: opt: builtins.trace k builtins.trace opt builtins.trace "" opt.isDefined) + { + inherit (options) + driver + driver_opts + attachable + enable_ipv6 + ipam + internal + labels + external + name + ; + } + ); + }; +}