Merge pull request #161 from hercules-ci/networks-and-networks.default.name
Networks and `networks.default.name`
This commit is contained in:
commit
c519be7211
19 changed files with 419 additions and 38 deletions
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -2,13 +2,23 @@
|
|||
|
||||
## Next
|
||||
|
||||
### Removed
|
||||
|
||||
- NixOS 20.09 support. Its docker-compose does not support the
|
||||
`networks.<name>.name` option, which is important in later versions.
|
||||
|
||||
### Changed
|
||||
|
||||
* Healthcheck-based dependencies in `service.depends_on`.
|
||||
* The `project.name` option is now mandatory.
|
||||
|
||||
### Added
|
||||
|
||||
* Support `service.healthcheck` for defining custom healthchecks.
|
||||
* Arion now declares a `networks.default` by default, with `name` set to
|
||||
`project.name`. This improves compatibility with container runtimes by
|
||||
copying pre-existing behavior. Most users will want to keep using this
|
||||
behavior, but it can be disabled with `enableDefaultNetwork`.
|
||||
|
||||
## 0.1.3.0 -- 2020-05-03
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -22,6 +22,30 @@ Attribute set that will be turned into the docker-compose.yaml file, using Nix's
|
|||
Type:: attribute set
|
||||
No Default:: {blank}
|
||||
|
||||
No Example:: {blank}
|
||||
|
||||
== enableDefaultNetwork
|
||||
|
||||
Whether to define the default network:
|
||||
|
||||
```nix
|
||||
networks.default = {
|
||||
name = config.project.name;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
[discrete]
|
||||
=== details
|
||||
|
||||
Type:: boolean
|
||||
Default::
|
||||
+
|
||||
----
|
||||
true
|
||||
----
|
||||
|
||||
|
||||
No Example:: {blank}
|
||||
|
||||
== host.nixStorePrefix
|
||||
|
@ -70,6 +94,164 @@ 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
|
||||
No Default:: {blank}
|
||||
|
||||
No Example:: {blank}
|
||||
|
||||
== networks.<name>.attachable
|
||||
|
||||
See link:https://docs.docker.com/compose/compose-file/#attachable[Docker Compose#attachable]
|
||||
|
||||
|
||||
[discrete]
|
||||
=== details
|
||||
|
||||
Type:: boolean
|
||||
No Default:: {blank}
|
||||
|
||||
Example::
|
||||
+
|
||||
----
|
||||
true
|
||||
----
|
||||
|
||||
|
||||
== networks.<name>.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.<name>.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.<name>.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.<name>.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.<name>.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.<name>.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.<name>.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>.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.
|
||||
|
@ -112,17 +294,14 @@ Name of the project.
|
|||
|
||||
See link:https://docs.docker.com/compose/reference/envvars/#compose_project_name[COMPOSE_PROJECT_NAME]
|
||||
|
||||
This is not optional, because getting the project name from a directory name tends to produce different results for different repo checkout location names.
|
||||
|
||||
|
||||
[discrete]
|
||||
=== details
|
||||
|
||||
Type:: null or string
|
||||
Default::
|
||||
+
|
||||
----
|
||||
null
|
||||
----
|
||||
|
||||
Type:: string
|
||||
No Default:: {blank}
|
||||
|
||||
No Example:: {blank}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
project.name = "full-nixos";
|
||||
services.webserver = { pkgs, lib, ... }: {
|
||||
nixos.useSystemd = true;
|
||||
nixos.configuration.boot.tmpOnTmpfs = true;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
|
||||
{
|
||||
project.name = "nixos-unit";
|
||||
services.webserver = { config, pkgs, ... }: {
|
||||
|
||||
nixos.configuration = {config, lib, options, pkgs, ...}: {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
*/
|
||||
{ lib, pkgs, ... }: {
|
||||
|
||||
config.project.name = "traefik";
|
||||
config.services = {
|
||||
traefik = {
|
||||
image.command = [
|
||||
|
|
|
@ -5,13 +5,6 @@ let
|
|||
in
|
||||
|
||||
dimension "Nixpkgs version" {
|
||||
# avoid bitrotting the docker support (as opposed to podman)
|
||||
"nixos-20_09" = {
|
||||
nixpkgsSource = "nixos-20.09";
|
||||
enableDoc = true;
|
||||
dockerSupportsSystemd = true;
|
||||
nixosHasPodmanDockerSocket = false;
|
||||
};
|
||||
"nixos-22_05" = {
|
||||
nixpkgsSource = "nixos-22.05";
|
||||
enableDoc = true;
|
||||
|
|
|
@ -49,6 +49,7 @@ in
|
|||
haskellPkgs.haskell-language-server
|
||||
super.docker-compose
|
||||
self.niv
|
||||
self.nixpkgs-fmt
|
||||
self.releaser
|
||||
];
|
||||
};
|
||||
|
|
|
@ -11,18 +11,6 @@
|
|||
"url": "https://github.com/nmattia/niv/archive/fad2a6cbfb2e7cdebb7cb0ad2f5cc91e2c9bc06b.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"nixos-20.09": {
|
||||
"branch": "nixos-20.09",
|
||||
"description": "Nix Packages collection",
|
||||
"homepage": null,
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0cfe5377e8993052f9b0dd56d058f8008af45bd9",
|
||||
"sha256": "0i3ybddi2mrlaz3di3svdpgy93zwmdglpywih4s9rd3wj865gzn1",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/0cfe5377e8993052f9b0dd56d058f8008af45bd9.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"nixos-22.05": {
|
||||
"branch": "nixos-22.05",
|
||||
"description": "Nix Packages collection",
|
||||
|
|
|
@ -79,9 +79,7 @@ let
|
|||
/* Function to derivation of the docker compose yaml file
|
||||
NOTE: The output will change: https://github.com/hercules-ci/arion/issues/82
|
||||
|
||||
This function is particularly useful on CI. On Nixpkgs >= 20.09 this will
|
||||
not store the image tarballs but executables to produce them reliably via
|
||||
streamLayeredImage.
|
||||
This function is particularly useful on CI.
|
||||
*/
|
||||
build = args@{...}:
|
||||
let composition = eval args;
|
||||
|
|
|
@ -60,7 +60,7 @@ parseOptions = do
|
|||
<> help "Use Nix expression EXPR to get the Nixpkgs attrset used for bootstrapping \
|
||||
\and evaluating the configuration." )
|
||||
showTrace <- flag False True (long "show-trace"
|
||||
<> help "Causes Nix to print out a stack trace in case of Nix expression evaluation errors.")
|
||||
<> help "Causes Nix to print out a stack trace in case of Nix expression evaluation errors. Specify before command.")
|
||||
-- TODO --option support (https://github.com/pcapriotti/optparse-applicative/issues/284)
|
||||
userNixArgs <- many (T.pack <$> strOption (long "nix-arg" <> metavar "ARG" <> help "Pass an extra argument to nix. Example: --nix-arg --option --nix-arg substitute --nix-arg false"))
|
||||
prebuiltComposeFile <- optional $ strOption
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"networks": {
|
||||
"default": {
|
||||
"name": "unit-test-data"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"webserver": {
|
||||
"command": [
|
||||
|
@ -37,7 +42,7 @@
|
|||
}
|
||||
],
|
||||
"project": {
|
||||
"name": null
|
||||
"name": "unit-test-data"
|
||||
},
|
||||
"serviceInfo": {
|
||||
"webserver": {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
project.name = "unit-test-data";
|
||||
services.webserver = { pkgs, ... }: {
|
||||
nixos.useSystemd = true;
|
||||
nixos.configuration.boot.tmpOnTmpfs = true;
|
||||
|
|
16
src/nix/lib.nix
Normal file
16
src/nix/lib.nix
Normal file
|
@ -0,0 +1,16 @@
|
|||
{ lib }:
|
||||
let
|
||||
|
||||
link = url: text:
|
||||
''link:${url}[${text}]'';
|
||||
|
||||
dockerComposeRef = fragment:
|
||||
''See ${link "https://docs.docker.com/compose/compose-file/#${fragment}" "Docker Compose#${fragment}"}'';
|
||||
|
||||
in
|
||||
{
|
||||
inherit
|
||||
dockerComposeRef
|
||||
link
|
||||
;
|
||||
}
|
|
@ -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
|
||||
]
|
|
@ -16,9 +16,10 @@ in
|
|||
Name of the project.
|
||||
|
||||
See ${link "https://docs.docker.com/compose/reference/envvars/#compose_project_name" "COMPOSE_PROJECT_NAME"}
|
||||
|
||||
This is not optional, because getting the project name from a directory name tends to produce different results for different repo checkout location names.
|
||||
'';
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
config = {
|
||||
|
|
53
src/nix/modules/composition/networks.nix
Normal file
53
src/nix/modules/composition/networks.nix
Normal file
|
@ -0,0 +1,53 @@
|
|||
{ 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"}
|
||||
'';
|
||||
};
|
||||
enableDefaultNetwork = mkOption {
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to define the default network:
|
||||
|
||||
```nix
|
||||
networks.default = {
|
||||
name = config.project.name;
|
||||
};
|
||||
```
|
||||
'';
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
config = {
|
||||
|
||||
networks = optionalAttrs config.enableDefaultNetwork {
|
||||
default = {
|
||||
name = config.project.name;
|
||||
};
|
||||
};
|
||||
|
||||
docker-compose.raw.networks =
|
||||
lib.mapAttrs (k: v: v.out) config.networks;
|
||||
|
||||
};
|
||||
}
|
131
src/nix/modules/networks/network.nix
Normal file
131
src/nix/modules/networks/network.nix
Normal file
|
@ -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
|
||||
;
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
|
@ -10,10 +10,11 @@ let
|
|||
inherit (lib) mkOption types;
|
||||
inherit (types) listOf nullOr attrsOf str either int bool submodule enum;
|
||||
|
||||
link = url: text:
|
||||
''link:${url}[${text}]'';
|
||||
dockerComposeRef = fragment:
|
||||
''See ${link "https://docs.docker.com/compose/compose-file/#${fragment}" "Docker Compose#${fragment}"}'';
|
||||
inherit (import ../../lib.nix { inherit lib; })
|
||||
link
|
||||
dockerComposeRef
|
||||
;
|
||||
|
||||
dockerComposeKitchenSink = ''
|
||||
Analogous to the `docker run` counterpart.
|
||||
|
||||
|
|
Loading…
Reference in a new issue