Merge pull request #161 from hercules-ci/networks-and-networks.default.name

Networks and `networks.default.name`
This commit is contained in:
Robert Hensing 2022-06-09 01:59:39 +02:00 committed by GitHub
commit c519be7211
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 419 additions and 38 deletions

View file

@ -2,13 +2,23 @@
## Next ## Next
### Removed
- NixOS 20.09 support. Its docker-compose does not support the
`networks.<name>.name` option, which is important in later versions.
### Changed ### Changed
* Healthcheck-based dependencies in `service.depends_on`. * Healthcheck-based dependencies in `service.depends_on`.
* The `project.name` option is now mandatory.
### Added ### Added
* Support `service.healthcheck` for defining custom healthchecks. * 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 ## 0.1.3.0 -- 2020-05-03

View file

@ -17,6 +17,7 @@ extra-source-files: CHANGELOG.md, README.asciidoc,
src/haskell/testdata/**/*.json src/haskell/testdata/**/*.json
data-files: nix/*.nix data-files: nix/*.nix
, nix/modules/composition/*.nix , nix/modules/composition/*.nix
, nix/modules/networks/*.nix
, nix/modules/nixos/*.nix , nix/modules/nixos/*.nix
, nix/modules/service/*.nix , nix/modules/service/*.nix
, nix/modules/lib/*.nix , nix/modules/lib/*.nix

View file

@ -22,6 +22,30 @@ Attribute set that will be turned into the docker-compose.yaml file, using Nix's
Type:: attribute set Type:: attribute set
No Default:: {blank} 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} No Example:: {blank}
== host.nixStorePrefix == host.nixStorePrefix
@ -70,6 +94,164 @@ No Default:: {blank}
No Example:: {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 == out.dockerComposeYaml
A derivation that produces a docker-compose.yaml file for this composition. 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] 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] [discrete]
=== details === details
Type:: null or string Type:: string
Default:: No Default:: {blank}
+
----
null
----
No Example:: {blank} No Example:: {blank}

View file

@ -1,4 +1,5 @@
{ {
project.name = "full-nixos";
services.webserver = { pkgs, lib, ... }: { services.webserver = { pkgs, lib, ... }: {
nixos.useSystemd = true; nixos.useSystemd = true;
nixos.configuration.boot.tmpOnTmpfs = true; nixos.configuration.boot.tmpOnTmpfs = true;

View file

@ -17,6 +17,7 @@
*/ */
{ {
project.name = "nixos-unit";
services.webserver = { config, pkgs, ... }: { services.webserver = { config, pkgs, ... }: {
nixos.configuration = {config, lib, options, pkgs, ...}: { nixos.configuration = {config, lib, options, pkgs, ...}: {

View file

@ -9,7 +9,7 @@
*/ */
{ lib, pkgs, ... }: { { lib, pkgs, ... }: {
config.project.name = "traefik";
config.services = { config.services = {
traefik = { traefik = {
image.command = [ image.command = [

View file

@ -5,13 +5,6 @@ let
in in
dimension "Nixpkgs version" { 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" = { "nixos-22_05" = {
nixpkgsSource = "nixos-22.05"; nixpkgsSource = "nixos-22.05";
enableDoc = true; enableDoc = true;

View file

@ -49,6 +49,7 @@ in
haskellPkgs.haskell-language-server haskellPkgs.haskell-language-server
super.docker-compose super.docker-compose
self.niv self.niv
self.nixpkgs-fmt
self.releaser self.releaser
]; ];
}; };

View file

@ -11,18 +11,6 @@
"url": "https://github.com/nmattia/niv/archive/fad2a6cbfb2e7cdebb7cb0ad2f5cc91e2c9bc06b.tar.gz", "url": "https://github.com/nmattia/niv/archive/fad2a6cbfb2e7cdebb7cb0ad2f5cc91e2c9bc06b.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.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": { "nixos-22.05": {
"branch": "nixos-22.05", "branch": "nixos-22.05",
"description": "Nix Packages collection", "description": "Nix Packages collection",

View file

@ -79,9 +79,7 @@ let
/* Function to derivation of the docker compose yaml file /* Function to derivation of the docker compose yaml file
NOTE: The output will change: https://github.com/hercules-ci/arion/issues/82 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 This function is particularly useful on CI.
not store the image tarballs but executables to produce them reliably via
streamLayeredImage.
*/ */
build = args@{...}: build = args@{...}:
let composition = eval args; let composition = eval args;

View file

@ -60,7 +60,7 @@ parseOptions = do
<> help "Use Nix expression EXPR to get the Nixpkgs attrset used for bootstrapping \ <> help "Use Nix expression EXPR to get the Nixpkgs attrset used for bootstrapping \
\and evaluating the configuration." ) \and evaluating the configuration." )
showTrace <- flag False True (long "show-trace" 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) -- 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")) 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 prebuiltComposeFile <- optional $ strOption

View file

@ -1,4 +1,9 @@
{ {
"networks": {
"default": {
"name": "unit-test-data"
}
},
"services": { "services": {
"webserver": { "webserver": {
"command": [ "command": [
@ -37,7 +42,7 @@
} }
], ],
"project": { "project": {
"name": null "name": "unit-test-data"
}, },
"serviceInfo": { "serviceInfo": {
"webserver": { "webserver": {

View file

@ -1,4 +1,5 @@
{ {
project.name = "unit-test-data";
services.webserver = { pkgs, ... }: { services.webserver = { pkgs, ... }: {
nixos.useSystemd = true; nixos.useSystemd = true;
nixos.configuration.boot.tmpOnTmpfs = true; nixos.configuration.boot.tmpOnTmpfs = true;

16
src/nix/lib.nix Normal file
View 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
;
}

View file

@ -2,6 +2,7 @@
./modules/composition/docker-compose.nix ./modules/composition/docker-compose.nix
./modules/composition/host-environment.nix ./modules/composition/host-environment.nix
./modules/composition/images.nix ./modules/composition/images.nix
./modules/composition/networks.nix
./modules/composition/service-info.nix ./modules/composition/service-info.nix
./modules/composition/composition.nix ./modules/composition/composition.nix
] ]

View file

@ -16,9 +16,10 @@ in
Name of the project. Name of the project.
See ${link "https://docs.docker.com/compose/reference/envvars/#compose_project_name" "COMPOSE_PROJECT_NAME"} 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; type = types.str;
default = null;
}; };
}; };
config = { config = {

View 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;
};
}

View 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
;
}
);
};
}

View file

@ -10,10 +10,11 @@ let
inherit (lib) mkOption types; inherit (lib) mkOption types;
inherit (types) listOf nullOr attrsOf str either int bool submodule enum; inherit (types) listOf nullOr attrsOf str either int bool submodule enum;
link = url: text: inherit (import ../../lib.nix { inherit lib; })
''link:${url}[${text}]''; link
dockerComposeRef = fragment: dockerComposeRef
''See ${link "https://docs.docker.com/compose/compose-file/#${fragment}" "Docker Compose#${fragment}"}''; ;
dockerComposeKitchenSink = '' dockerComposeKitchenSink = ''
Analogous to the `docker run` counterpart. Analogous to the `docker run` counterpart.