Compare commits
59 commits
Author | SHA1 | Date | |
---|---|---|---|
ec4f2a836d | |||
|
90bc855327 | ||
|
16c4d4d8b8 | ||
|
236f9dd82d | ||
|
ab9bdaf08f | ||
|
555e7ba634 | ||
|
01777136c6 | ||
|
8f0549b434 | ||
|
c24c185e67 | ||
|
d917218d05 | ||
|
e9945eb6cd | ||
|
0449d31ffb | ||
|
7e7aa3dfc6 | ||
|
efa008e12f | ||
|
df306b74bc | ||
|
add0e67d2b | ||
|
c8c61a3c67 | ||
|
1886d25075 | ||
|
c2cc3dae34 | ||
|
d2d48c9ec3 | ||
|
c1597ef64b | ||
|
2b1fa9a8e9 | ||
|
4fb872dc07 | ||
|
39ee2bc7f7 | ||
|
245fec68a2 | ||
|
9e5caa2b48 | ||
|
5321799830 | ||
|
e92e133563 | ||
|
6ad33828e7 | ||
|
f295eabd25 | ||
|
a27295cbf5 | ||
|
b181b822f8 | ||
|
49bc39d860 | ||
|
91e67df844 | ||
|
da2141cd93 | ||
|
14b8d91ce0 | ||
|
2d546f6372 | ||
|
f68888200d | ||
|
39030b9566 | ||
|
493fa1e575 | ||
|
172e69d563 | ||
|
6881b440b6 | ||
|
28902d3488 | ||
|
57516c38fa | ||
|
e9ebb6f79f | ||
|
51ed7054c1 | ||
|
3588b01e13 | ||
|
638c4b8e55 | ||
|
a8d9725e6c | ||
|
f0436c8478 | ||
|
8868689d3f | ||
|
408841513b | ||
|
22ef4649d8 | ||
|
0e7dc62ccf | ||
|
9ba47f9fbb | ||
|
16f9888732 | ||
|
b175f45613 | ||
|
f8359746cc | ||
|
2ef502c912 |
25 changed files with 372 additions and 133 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -5,3 +5,5 @@ dist/
|
||||||
dist-newstyle/
|
dist-newstyle/
|
||||||
cabal.project.local
|
cabal.project.local
|
||||||
|
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
|
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -1,5 +1,18 @@
|
||||||
# Revision history for Arion
|
# Revision history for Arion
|
||||||
|
|
||||||
|
## 0.2.1.0 -- 2023-07-26
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* `service.networks` now supports attribute set values with various options, thanks to @pedorich-n.
|
||||||
|
* `docker-compose.volumes` can now be specified in multiple modules, thanks to @qaifshaikh.
|
||||||
|
* `image.fakeRootCommands` for making modifications to the image that aren't "add a link farm".
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
* Regular maintenance fixes, including one by olebedev
|
||||||
|
|
||||||
|
|
||||||
## 0.2.0.0 -- 2022-12-02
|
## 0.2.0.0 -- 2022-12-02
|
||||||
|
|
||||||
### BREAKING
|
### BREAKING
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
cabal-version: 2.4
|
cabal-version: 2.4
|
||||||
|
|
||||||
name: arion-compose
|
name: arion-compose
|
||||||
version: 0.2.0.0
|
version: 0.2.1.0
|
||||||
synopsis: Run docker-compose with help from Nix/NixOS
|
synopsis: Run docker-compose with help from Nix/NixOS
|
||||||
description: Arion is a tool for building and running applications that consist of multiple docker containers using NixOS modules. It has special support for docker images that are built with Nix, for a smooth development experience and improved performance.
|
description: Arion is a tool for building and running applications that consist of multiple docker containers using NixOS modules. It has special support for docker images that are built with Nix, for a smooth development experience and improved performance.
|
||||||
homepage: https://github.com/hercules-ci/arion#readme
|
homepage: https://github.com/hercules-ci/arion#readme
|
||||||
|
@ -30,7 +30,7 @@ source-repository head
|
||||||
location: https://github.com/hercules-ci/arion
|
location: https://github.com/hercules-ci/arion
|
||||||
|
|
||||||
common common
|
common common
|
||||||
build-depends: base >=4.12.0.0 && <4.17
|
build-depends: base >=4.12.0.0 && <4.99
|
||||||
, aeson >=2
|
, aeson >=2
|
||||||
, aeson-pretty
|
, aeson-pretty
|
||||||
, async
|
, async
|
||||||
|
|
|
@ -45,18 +45,21 @@ NOTE: This deployment method does NOT use an `arion-pkgs.nix` file, but reuses
|
||||||
# Pick one of:
|
# Pick one of:
|
||||||
# - niv
|
# - niv
|
||||||
((import ./nix/sources.nix).arion + "/nixos-module.nix")
|
((import ./nix/sources.nix).arion + "/nixos-module.nix")
|
||||||
# - flakes (where arion is a flake input)
|
# - or flakes (where arion is a flake input)
|
||||||
arion.nixosModules.arion
|
arion.nixosModules.arion
|
||||||
# - other
|
# - or other: copy commit hash of arion and replace HASH in:
|
||||||
arionPath + "/nixos-module.nix")
|
(builtins.fetchTarball "https://github.com/hercules-ci/arion/archive/HASH.tar.gz") + "/nixos-module.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
virtualisation.arion = {
|
virtualisation.arion = {
|
||||||
backend = "podman-socket"; # or "docker"
|
backend = "podman-socket"; # or "docker"
|
||||||
projects.example.settings = {
|
projects.example = {
|
||||||
# Specify you project here, or import it from a file.
|
serviceName = "example"; # optional systemd service name, defaults to arion-example in this case
|
||||||
# NOTE: This does NOT use ./arion-pkgs.nix, but defaults to NixOS' pkgs.
|
settings = {
|
||||||
imports = [ ./arion-compose.nix ];
|
# Specify you project here, or import it from a file.
|
||||||
|
# NOTE: This does NOT use ./arion-pkgs.nix, but defaults to NixOS' pkgs.
|
||||||
|
imports = [ ./arion-compose.nix ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,7 +148,7 @@ Describe containers using NixOS-style modules. There are a few options:
|
||||||
project.name = "full-nixos";
|
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.tmp.useTmpfs = true;
|
||||||
nixos.configuration.services.nginx.enable = true;
|
nixos.configuration.services.nginx.enable = true;
|
||||||
nixos.configuration.services.nginx.virtualHosts.localhost.root = "${pkgs.nix.doc}/share/doc/nix/manual";
|
nixos.configuration.services.nginx.virtualHosts.localhost.root = "${pkgs.nix.doc}/share/doc/nix/manual";
|
||||||
nixos.configuration.services.nscd.enable = false;
|
nixos.configuration.services.nscd.enable = false;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
project.name = "full-nixos";
|
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.tmp.useTmpfs = true;
|
||||||
nixos.configuration.networking.useDHCP = false;
|
nixos.configuration.networking.useDHCP = false;
|
||||||
nixos.configuration.services.nginx.enable = true;
|
nixos.configuration.services.nginx.enable = true;
|
||||||
nixos.configuration.services.nginx.virtualHosts.localhost.root = "${pkgs.nix.doc}/share/doc/nix/manual";
|
nixos.configuration.services.nginx.virtualHosts.localhost.root = "${pkgs.nix.doc}/share/doc/nix/manual";
|
||||||
|
|
|
@ -10,6 +10,17 @@
|
||||||
*/
|
*/
|
||||||
{ lib, pkgs, ... }: {
|
{ lib, pkgs, ... }: {
|
||||||
config.project.name = "traefik";
|
config.project.name = "traefik";
|
||||||
|
config.networks = {
|
||||||
|
traefik-custom = {
|
||||||
|
name = "traefik-custom";
|
||||||
|
ipam = {
|
||||||
|
config = [{
|
||||||
|
subnet = "172.32.0.0/16";
|
||||||
|
gateway = "172.32.0.1";
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
config.services = {
|
config.services = {
|
||||||
traefik = {
|
traefik = {
|
||||||
image.command = [
|
image.command = [
|
||||||
|
@ -24,6 +35,7 @@
|
||||||
stop_signal = "SIGINT";
|
stop_signal = "SIGINT";
|
||||||
ports = [ "80:80" "8080:8080" ];
|
ports = [ "80:80" "8080:8080" ];
|
||||||
volumes = [ "/var/run/docker.sock:/var/run/docker.sock:ro" ];
|
volumes = [ "/var/run/docker.sock:/var/run/docker.sock:ro" ];
|
||||||
|
networks = [ "traefik-custom" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,14 +46,17 @@
|
||||||
${pkgs.python3}/bin/python -m http.server
|
${pkgs.python3}/bin/python -m http.server
|
||||||
''}"];
|
''}"];
|
||||||
service.container_name = "simple-service";
|
service.container_name = "simple-service";
|
||||||
service.ports = [
|
|
||||||
"8000:8000" # host:container
|
|
||||||
];
|
|
||||||
service.stop_signal = "SIGINT";
|
service.stop_signal = "SIGINT";
|
||||||
service.labels = {
|
service.labels = {
|
||||||
"traefik.enable" = "true";
|
"traefik.enable" = "true";
|
||||||
"traefik.http.routers.nix-docs.rule" = "Host(`nix-docs.localhost`)";
|
"traefik.http.routers.nix-docs.rule" = "Host(`nix-docs.localhost`)";
|
||||||
"traefik.http.routers.nix-docs.entrypoints" = "web";
|
"traefik.http.routers.nix-docs.entrypoints" = "web";
|
||||||
|
"traefik.http.services.nix-docs.loadBalancer.server.port" = "8000";
|
||||||
|
};
|
||||||
|
service.networks = {
|
||||||
|
traefik-custom = {
|
||||||
|
ipv4_address = "172.32.0.5";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
54
flake.lock
54
flake.lock
|
@ -7,11 +7,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1675933616,
|
"lastModified": 1722555600,
|
||||||
"narHash": "sha256-/rczJkJHtx16IFxMmAWu5nNYcSXNg1YYXTHoGjLrLUA=",
|
"narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "47478a4a003e745402acf63be7f9a092d51b83d7",
|
"rev": "8471fe90ad337a8074e957b69ca4d0089218391d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -20,6 +20,26 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flake-parts_2": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": [
|
||||||
|
"hercules-ci-effects",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1712014858,
|
||||||
|
"narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "flake-parts",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
"haskell-flake": {
|
"haskell-flake": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1675296942,
|
"lastModified": 1675296942,
|
||||||
|
@ -36,13 +56,34 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"hercules-ci-effects": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": "flake-parts_2",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1719226092,
|
||||||
|
"narHash": "sha256-YNkUMcCUCpnULp40g+svYsaH1RbSEj6s4WdZY/SHe38=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "hercules-ci-effects",
|
||||||
|
"rev": "11e4b8dc112e2f485d7c97e1cee77f9958f498f5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "hercules-ci-effects",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1676300157,
|
"lastModified": 1722630782,
|
||||||
"narHash": "sha256-1HjRzfp6LOLfcj/HJHdVKWAkX9QRAouoh6AjzJiIerU=",
|
"narHash": "sha256-hMyG9/WlUi0Ho9VkRrrez7SeNlDzLxalm9FwY7n/Noo=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "545c7a31e5dedea4a6d372712a18e00ce097d462",
|
"rev": "d04953086551086b44b6f3c6b7eeb26294f207da",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -56,6 +97,7 @@
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts",
|
||||||
"haskell-flake": "haskell-flake",
|
"haskell-flake": "haskell-flake",
|
||||||
|
"hercules-ci-effects": "hercules-ci-effects",
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
32
flake.nix
32
flake.nix
|
@ -6,12 +6,15 @@
|
||||||
haskell-flake.url = "github:srid/haskell-flake/0.1.0";
|
haskell-flake.url = "github:srid/haskell-flake/0.1.0";
|
||||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs";
|
flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||||
|
hercules-ci-effects.url = "github:hercules-ci/hercules-ci-effects";
|
||||||
|
hercules-ci-effects.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = inputs@{ self, flake-parts, ... }:
|
outputs = inputs@{ self, flake-parts, ... }:
|
||||||
flake-parts.lib.mkFlake { inherit inputs; } ({ config, lib, extendModules, ... }: {
|
flake-parts.lib.mkFlake { inherit inputs; } ({ config, lib, extendModules, ... }: {
|
||||||
imports = [
|
imports = [
|
||||||
inputs.haskell-flake.flakeModule
|
inputs.haskell-flake.flakeModule
|
||||||
|
inputs.hercules-ci-effects.flakeModule
|
||||||
inputs.flake-parts.flakeModules.easyOverlay
|
inputs.flake-parts.flakeModules.easyOverlay
|
||||||
./docs/flake-module.nix
|
./docs/flake-module.nix
|
||||||
./tests/flake-module.nix
|
./tests/flake-module.nix
|
||||||
|
@ -63,15 +66,26 @@
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
hercules-ci.flake-update = {
|
||||||
|
enable = true;
|
||||||
|
autoMergeMethod = "merge";
|
||||||
|
when = {
|
||||||
|
hour = [ 2 ];
|
||||||
|
dayOfMonth = [ 5 ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
herculesCI.ciSystems = [
|
||||||
|
# "aarch64-darwin"
|
||||||
|
# "aarch64-linux"
|
||||||
|
"x86_64-darwin"
|
||||||
|
"x86_64-linux"
|
||||||
|
];
|
||||||
|
|
||||||
flake = {
|
flake = {
|
||||||
debug = { inherit inputs config lib; };
|
debug = { inherit inputs config lib; };
|
||||||
|
|
||||||
defaultPackage =
|
|
||||||
lib.mapAttrs
|
|
||||||
(ps: lib.warn "arion.defaultPackage has been removed in favor of arion.packages.\${system}.default"
|
|
||||||
ps.default)
|
|
||||||
config.flake.packages;
|
|
||||||
|
|
||||||
lib = {
|
lib = {
|
||||||
eval = import ./src/nix/eval-composition.nix;
|
eval = import ./src/nix/eval-composition.nix;
|
||||||
build = args@{ ... }:
|
build = args@{ ... }:
|
||||||
|
@ -79,12 +93,6 @@
|
||||||
in composition.config.out.dockerComposeYaml;
|
in composition.config.out.dockerComposeYaml;
|
||||||
};
|
};
|
||||||
nixosModules.arion = ./nixos-module.nix;
|
nixosModules.arion = ./nixos-module.nix;
|
||||||
herculesCI.ciSystems = [
|
|
||||||
# "aarch64-darwin"
|
|
||||||
# "aarch64-linux"
|
|
||||||
"x86_64-darwin"
|
|
||||||
"x86_64-linux"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,14 @@ let
|
||||||
visible = "shallow";
|
visible = "shallow";
|
||||||
};
|
};
|
||||||
_systemd = mkOption { internal = true; };
|
_systemd = mkOption { internal = true; };
|
||||||
|
serviceName = mkOption {
|
||||||
|
description = "The name of the Arion project's systemd service";
|
||||||
|
type = types.str;
|
||||||
|
default = "arion-${name}";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
_systemd.services."arion-${name}" = {
|
_systemd.services.${config.serviceName} = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "sockets.target" ];
|
after = [ "sockets.target" ];
|
||||||
|
|
||||||
|
|
|
@ -3,4 +3,4 @@
|
||||||
# For manual testing of a hacked arion built via Nix.
|
# For manual testing of a hacked arion built via Nix.
|
||||||
# Works when called from outside the project directory.
|
# Works when called from outside the project directory.
|
||||||
|
|
||||||
exec nix run -f "$(dirname ${BASH_SOURCE[0]})" arion -c arion "$@"
|
exec nix run -f "$(dirname ${BASH_SOURCE[0]})" arion "$@"
|
||||||
|
|
|
@ -13,19 +13,34 @@ import qualified Data.Text as T
|
||||||
import qualified Data.Text.IO as T
|
import qualified Data.Text.IO as T
|
||||||
|
|
||||||
spec :: Spec
|
spec :: Spec
|
||||||
spec = describe "evaluateComposition" $ it "matches an example" $ do
|
spec = describe "evaluateComposition" $ do
|
||||||
x <- Arion.Nix.evaluateComposition EvaluationArgs
|
it "matches an example" $ do
|
||||||
{ evalUid = 123
|
x <- Arion.Nix.evaluateComposition EvaluationArgs
|
||||||
, evalModules = NEL.fromList
|
{ evalUid = 123
|
||||||
["src/haskell/testdata/Arion/NixSpec/arion-compose.nix"]
|
, evalModules = NEL.fromList
|
||||||
, evalPkgs = "import <nixpkgs> { system = \"x86_64-linux\"; }"
|
["src/haskell/testdata/Arion/NixSpec/arion-compose.nix"]
|
||||||
, evalWorkDir = Nothing
|
, evalPkgs = "import <nixpkgs> { system = \"x86_64-linux\"; }"
|
||||||
, evalMode = ReadOnly
|
, evalWorkDir = Nothing
|
||||||
, evalUserArgs = ["--show-trace"]
|
, evalMode = ReadOnly
|
||||||
}
|
, evalUserArgs = ["--show-trace"]
|
||||||
let actual = pretty x
|
}
|
||||||
expected <- T.readFile "src/haskell/testdata/Arion/NixSpec/arion-compose.json"
|
let actual = pretty x
|
||||||
censorPaths actual `shouldBe` censorPaths expected
|
expected <- T.readFile "src/haskell/testdata/Arion/NixSpec/arion-compose.json"
|
||||||
|
censorPaths actual `shouldBe` censorPaths expected
|
||||||
|
|
||||||
|
it "matches an build.context example" $ do
|
||||||
|
x <- Arion.Nix.evaluateComposition EvaluationArgs
|
||||||
|
{ evalUid = 1234
|
||||||
|
, evalModules = NEL.fromList
|
||||||
|
["src/haskell/testdata/Arion/NixSpec/arion-context-compose.nix"]
|
||||||
|
, evalPkgs = "import <nixpkgs> { system = \"x86_64-linux\"; }"
|
||||||
|
, evalWorkDir = Nothing
|
||||||
|
, evalMode = ReadOnly
|
||||||
|
, evalUserArgs = ["--show-trace"]
|
||||||
|
}
|
||||||
|
let actual = pretty x
|
||||||
|
expected <- T.readFile "src/haskell/testdata/Arion/NixSpec/arion-context-compose.json"
|
||||||
|
censorPaths actual `shouldBe` censorPaths expected
|
||||||
|
|
||||||
censorPaths :: Text -> Text
|
censorPaths :: Text -> Text
|
||||||
censorPaths = censorImages . censorStorePaths
|
censorPaths = censorImages . censorStorePaths
|
||||||
|
|
|
@ -9,3 +9,4 @@ import qualified Arion.NixSpec
|
||||||
spec :: Spec
|
spec :: Spec
|
||||||
spec = do
|
spec = do
|
||||||
describe "Arion.Nix" Arion.NixSpec.spec
|
describe "Arion.Nix" Arion.NixSpec.spec
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
project.name = "unit-test-data";
|
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.tmp.useTmpfs = true;
|
||||||
nixos.configuration.services.nginx.enable = true;
|
nixos.configuration.services.nginx.enable = true;
|
||||||
nixos.configuration.services.nginx.virtualHosts.localhost.root = "${pkgs.nix.doc}/share/doc/nix/manual";
|
nixos.configuration.services.nginx.virtualHosts.localhost.root = "${pkgs.nix.doc}/share/doc/nix/manual";
|
||||||
service.useHostStore = true;
|
service.useHostStore = true;
|
||||||
|
|
41
src/haskell/testdata/Arion/NixSpec/arion-context-compose.json
vendored
Normal file
41
src/haskell/testdata/Arion/NixSpec/arion-context-compose.json
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"networks": {
|
||||||
|
"default": {
|
||||||
|
"name": "unit-test-data"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"webserver": {
|
||||||
|
"build": {
|
||||||
|
"context": "<STOREPATH>"
|
||||||
|
},
|
||||||
|
"environment": {},
|
||||||
|
"ports": [
|
||||||
|
"8080:80"
|
||||||
|
],
|
||||||
|
"sysctls": {},
|
||||||
|
"volumes": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"version": "3.4",
|
||||||
|
"volumes": {},
|
||||||
|
"x-arion": {
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"imageExe": "<STOREPATH>",
|
||||||
|
"imageName": "localhost/webserver",
|
||||||
|
"imageTag": "<HASH>"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"project": {
|
||||||
|
"name": "unit-test-data"
|
||||||
|
},
|
||||||
|
"serviceInfo": {
|
||||||
|
"webserver": {
|
||||||
|
"defaultExec": [
|
||||||
|
"/bin/sh"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
src/haskell/testdata/Arion/NixSpec/arion-context-compose.nix
vendored
Normal file
9
src/haskell/testdata/Arion/NixSpec/arion-context-compose.nix
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
project.name = "unit-test-data";
|
||||||
|
services.webserver.service = {
|
||||||
|
build.context = "${./build-context}";
|
||||||
|
ports = [
|
||||||
|
"8080:80"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
4
src/haskell/testdata/Arion/NixSpec/build-context/Dockerfile
vendored
Normal file
4
src/haskell/testdata/Arion/NixSpec/build-context/Dockerfile
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
FROM nginx
|
||||||
|
|
||||||
|
RUN echo this is a dockerfile to be built
|
||||||
|
|
|
@ -3,13 +3,19 @@ let
|
||||||
|
|
||||||
link = url: text: ''[${text}](${url})'';
|
link = url: text: ''[${text}](${url})'';
|
||||||
|
|
||||||
dockerComposeRef = fragment:
|
composeSpecRev = "55b450aee50799a2f33cc99e1d714518babe305e";
|
||||||
''See ${link "https://docs.docker.com/compose/compose-file/#${fragment}" "Docker Compose#${fragment}"}'';
|
|
||||||
|
serviceRef = fragment:
|
||||||
|
''See ${link "https://github.com/compose-spec/compose-spec/blob/${composeSpecRev}/05-services.md#${fragment}" "Compose Spec Services #${fragment}"}'';
|
||||||
|
|
||||||
|
networkRef = fragment:
|
||||||
|
''See ${link "https://github.com/compose-spec/compose-spec/blob/${composeSpecRev}/06-networks.md#${fragment}" "Compose Spec Networks #${fragment}"}'';
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
inherit
|
inherit
|
||||||
dockerComposeRef
|
|
||||||
link
|
link
|
||||||
|
networkRef
|
||||||
|
serviceRef
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ let
|
||||||
types
|
types
|
||||||
;
|
;
|
||||||
inherit (import ../../lib.nix { inherit lib; })
|
inherit (import ../../lib.nix { inherit lib; })
|
||||||
dockerComposeRef
|
link
|
||||||
;
|
;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,7 @@ in
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
description = ''
|
description = ''
|
||||||
${dockerComposeRef "networks-top-level-element"}
|
See ${link "https://docs.docker.com/compose/compose-file/06-networks/" "Docker Compose Networks"}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
enableDefaultNetwork = mkOption {
|
enableDefaultNetwork = mkOption {
|
||||||
|
|
|
@ -7,7 +7,7 @@ let
|
||||||
types
|
types
|
||||||
;
|
;
|
||||||
inherit (import ../../lib.nix { inherit lib; })
|
inherit (import ../../lib.nix { inherit lib; })
|
||||||
dockerComposeRef
|
networkRef
|
||||||
;
|
;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@ -15,21 +15,21 @@ in
|
||||||
driver = mkOption {
|
driver = mkOption {
|
||||||
description = ''
|
description = ''
|
||||||
`"none"`, `"host"`, or a platform-specific value.
|
`"none"`, `"host"`, or a platform-specific value.
|
||||||
${dockerComposeRef "driver"}
|
${networkRef "driver"}
|
||||||
'';
|
'';
|
||||||
type = types.str;
|
type = types.str;
|
||||||
};
|
};
|
||||||
|
|
||||||
driver_opts = mkOption {
|
driver_opts = mkOption {
|
||||||
description = ''
|
description = ''
|
||||||
${dockerComposeRef "driver_opts"}
|
${networkRef "driver_opts"}
|
||||||
'';
|
'';
|
||||||
type = types.lazyAttrsOf types.raw or types.unspecified;
|
type = types.lazyAttrsOf types.raw or types.unspecified;
|
||||||
};
|
};
|
||||||
|
|
||||||
attachable = mkOption {
|
attachable = mkOption {
|
||||||
description = ''
|
description = ''
|
||||||
${dockerComposeRef "attachable"}
|
${networkRef "attachable"}
|
||||||
'';
|
'';
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
example = true;
|
example = true;
|
||||||
|
@ -39,7 +39,7 @@ in
|
||||||
description = ''
|
description = ''
|
||||||
Whether we've entered the 21st century yet.
|
Whether we've entered the 21st century yet.
|
||||||
|
|
||||||
${dockerComposeRef "enable_ipv6"}
|
${networkRef "enable_ipv6"}
|
||||||
'';
|
'';
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
};
|
};
|
||||||
|
@ -49,7 +49,7 @@ in
|
||||||
description = ''
|
description = ''
|
||||||
Manage IP addresses.
|
Manage IP addresses.
|
||||||
|
|
||||||
${dockerComposeRef "ipam"}
|
${networkRef "ipam"}
|
||||||
'';
|
'';
|
||||||
type = types.raw or types.unspecified;
|
type = types.raw or types.unspecified;
|
||||||
};
|
};
|
||||||
|
@ -58,7 +58,7 @@ in
|
||||||
description = ''
|
description = ''
|
||||||
Achieves "external isolation".
|
Achieves "external isolation".
|
||||||
|
|
||||||
${dockerComposeRef "internal"}
|
${networkRef "internal"}
|
||||||
'';
|
'';
|
||||||
defaultText = false;
|
defaultText = false;
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
|
@ -68,7 +68,7 @@ in
|
||||||
description = ''
|
description = ''
|
||||||
Metadata.
|
Metadata.
|
||||||
|
|
||||||
${dockerComposeRef "labels"}
|
${networkRef "labels"}
|
||||||
'';
|
'';
|
||||||
# no list support, because less expressive wrt overriding
|
# no list support, because less expressive wrt overriding
|
||||||
type = types.attrsOf types.str;
|
type = types.attrsOf types.str;
|
||||||
|
@ -79,7 +79,7 @@ in
|
||||||
When `true`, don't create or destroy the network, but assume that it
|
When `true`, don't create or destroy the network, but assume that it
|
||||||
exists.
|
exists.
|
||||||
|
|
||||||
${dockerComposeRef "external"}
|
${networkRef "external"}
|
||||||
'';
|
'';
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
};
|
};
|
||||||
|
@ -92,7 +92,7 @@ in
|
||||||
|
|
||||||
Note the `default` network's default `name` is set to `project.name` by Arion.
|
Note the `default` network's default `name` is set to `project.name` by Arion.
|
||||||
|
|
||||||
${dockerComposeRef "name"}
|
${networkRef "name"}
|
||||||
'';
|
'';
|
||||||
type = types.str;
|
type = types.str;
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,15 +12,9 @@ let
|
||||||
|
|
||||||
inherit (import ../../lib.nix { inherit lib; })
|
inherit (import ../../lib.nix { inherit lib; })
|
||||||
link
|
link
|
||||||
dockerComposeRef
|
serviceRef
|
||||||
;
|
;
|
||||||
|
|
||||||
dockerComposeKitchenSink = ''
|
|
||||||
Analogous to the `docker run` counterpart.
|
|
||||||
|
|
||||||
${dockerComposeRef "domainname-hostname-ipc-mac_address-privileged-read_only-shm_size-stdin_open-tty-user-working_dir"}
|
|
||||||
'';
|
|
||||||
|
|
||||||
cap_add = lib.attrNames (lib.filterAttrs (name: value: value == true) config.service.capabilities);
|
cap_add = lib.attrNames (lib.filterAttrs (name: value: value == true) config.service.capabilities);
|
||||||
cap_drop = lib.attrNames (lib.filterAttrs (name: value: value == false) config.service.capabilities);
|
cap_drop = lib.attrNames (lib.filterAttrs (name: value: value == false) config.service.capabilities);
|
||||||
|
|
||||||
|
@ -56,12 +50,12 @@ in
|
||||||
service.volumes = mkOption {
|
service.volumes = mkOption {
|
||||||
type = listOf types.unspecified;
|
type = listOf types.unspecified;
|
||||||
default = [];
|
default = [];
|
||||||
description = dockerComposeRef "volumes";
|
description = serviceRef "volumes";
|
||||||
};
|
};
|
||||||
service.tmpfs = mkOption {
|
service.tmpfs = mkOption {
|
||||||
type = listOf types.str;
|
type = listOf types.str;
|
||||||
default = [];
|
default = [];
|
||||||
description = dockerComposeRef "tmpfs";
|
description = serviceRef "tmpfs";
|
||||||
};
|
};
|
||||||
service.build.context = mkOption {
|
service.build.context = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
|
@ -69,44 +63,65 @@ in
|
||||||
description = ''
|
description = ''
|
||||||
Locates a Dockerfile to use for creating an image to use in this service.
|
Locates a Dockerfile to use for creating an image to use in this service.
|
||||||
|
|
||||||
${dockerComposeRef "context"}
|
https://docs.docker.com/compose/compose-file/build/#context
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
service.build.dockerfile = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Sets an alternate Dockerfile. A relative path is resolved from the build context.
|
||||||
|
https://docs.docker.com/compose/compose-file/build/#dockerfile
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
service.build.target = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Defines the stage to build as defined inside a multi-stage Dockerfile.
|
||||||
|
https://docs.docker.com/compose/compose-file/build/#target
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
service.hostname = mkOption {
|
service.hostname = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
default = null;
|
default = null;
|
||||||
description = dockerComposeKitchenSink;
|
description = ''
|
||||||
|
${serviceRef "hostname"}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
service.tty = mkOption {
|
service.tty = mkOption {
|
||||||
type = nullOr bool;
|
type = nullOr bool;
|
||||||
default = null;
|
default = null;
|
||||||
description = dockerComposeKitchenSink;
|
description = ''
|
||||||
|
${serviceRef "tty"}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
service.environment = mkOption {
|
service.environment = mkOption {
|
||||||
type = attrsOf (either str int);
|
type = attrsOf (either str int);
|
||||||
default = {};
|
default = {};
|
||||||
description = dockerComposeRef "environment";
|
description = serviceRef "environment";
|
||||||
};
|
};
|
||||||
service.image = mkOption {
|
service.image = mkOption {
|
||||||
type = str;
|
type = nullOr str;
|
||||||
description = dockerComposeRef "image";
|
default = null;
|
||||||
|
description = serviceRef "image";
|
||||||
};
|
};
|
||||||
service.command = mkOption {
|
service.command = mkOption {
|
||||||
type = nullOr types.unspecified;
|
type = nullOr types.unspecified;
|
||||||
default = null;
|
default = null;
|
||||||
description = dockerComposeRef "command";
|
description = serviceRef "command";
|
||||||
};
|
};
|
||||||
service.container_name = mkOption {
|
service.container_name = mkOption {
|
||||||
type = nullOr types.str;
|
type = nullOr types.str;
|
||||||
default = null;
|
default = null;
|
||||||
description = dockerComposeRef "container_name";
|
description = serviceRef "container_name";
|
||||||
};
|
};
|
||||||
service.depends_on =
|
service.depends_on =
|
||||||
let conditionsModule = {
|
let conditionsModule = {
|
||||||
options = {
|
options = {
|
||||||
condition = mkOption {
|
condition = mkOption {
|
||||||
type = enum ["service_started" "service_healthy" "service_completed_successfully"];
|
type = enum ["service_started" "service_healthy" "service_completed_successfully"];
|
||||||
description = dockerComposeRef "depends_on";
|
description = serviceRef "depends_on";
|
||||||
default = "service_started";
|
default = "service_started";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -114,10 +129,10 @@ in
|
||||||
in mkOption {
|
in mkOption {
|
||||||
type = either (listOf str) (attrsOf (submodule conditionsModule));
|
type = either (listOf str) (attrsOf (submodule conditionsModule));
|
||||||
default = [];
|
default = [];
|
||||||
description = dockerComposeRef "depends_on";
|
description = serviceRef "depends_on";
|
||||||
};
|
};
|
||||||
service.healthcheck = mkOption {
|
service.healthcheck = mkOption {
|
||||||
description = dockerComposeRef "healthcheck";
|
description = serviceRef "healthcheck";
|
||||||
type = submodule ({ config, options, ...}: {
|
type = submodule ({ config, options, ...}: {
|
||||||
options = {
|
options = {
|
||||||
_out = mkOption {
|
_out = mkOption {
|
||||||
|
@ -130,30 +145,30 @@ in
|
||||||
type = nullOr (listOf str);
|
type = nullOr (listOf str);
|
||||||
default = null;
|
default = null;
|
||||||
example = [ "CMD" "pg_isready" ];
|
example = [ "CMD" "pg_isready" ];
|
||||||
description = dockerComposeRef "healthcheck";
|
description = serviceRef "healthcheck";
|
||||||
};
|
};
|
||||||
interval = mkOption {
|
interval = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
default = "30s";
|
default = "30s";
|
||||||
example = "1m";
|
example = "1m";
|
||||||
description = dockerComposeRef "healthcheck";
|
description = serviceRef "healthcheck";
|
||||||
};
|
};
|
||||||
timeout = mkOption {
|
timeout = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
default = "30s";
|
default = "30s";
|
||||||
example = "10s";
|
example = "10s";
|
||||||
description = dockerComposeRef "healthcheck";
|
description = serviceRef "healthcheck";
|
||||||
};
|
};
|
||||||
start_period = mkOption {
|
start_period = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
default = "0s";
|
default = "0s";
|
||||||
example = "30s";
|
example = "30s";
|
||||||
description = dockerComposeRef "healthcheck";
|
description = serviceRef "healthcheck";
|
||||||
};
|
};
|
||||||
retries = mkOption {
|
retries = mkOption {
|
||||||
type = int;
|
type = int;
|
||||||
default = 3;
|
default = 3;
|
||||||
description = dockerComposeRef "healthcheck";
|
description = serviceRef "healthcheck";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -165,14 +180,14 @@ in
|
||||||
See ${link "https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities"
|
See ${link "https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities"
|
||||||
"`docker run --device` documentation"}
|
"`docker run --device` documentation"}
|
||||||
|
|
||||||
${dockerComposeRef "devices"}
|
${serviceRef "devices"}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
service.dns = mkOption {
|
service.dns = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
default = [];
|
default = [];
|
||||||
example = [ "8.8.8.8" "8.8.4.4" ];
|
example = [ "8.8.8.8" "8.8.4.4" ];
|
||||||
description = dockerComposeRef "dns";
|
description = serviceRef "dns";
|
||||||
};
|
};
|
||||||
service.labels = mkOption {
|
service.labels = mkOption {
|
||||||
type = attrsOf str;
|
type = attrsOf str;
|
||||||
|
@ -183,47 +198,58 @@ in
|
||||||
"traefik.http.routers.my-service.rule" = "Host(`my-service.localhost`)";
|
"traefik.http.routers.my-service.rule" = "Host(`my-service.localhost`)";
|
||||||
"traefik.http.routers.my-service.entrypoints" = "web";
|
"traefik.http.routers.my-service.entrypoints" = "web";
|
||||||
};
|
};
|
||||||
description = dockerComposeRef "labels";
|
description = serviceRef "labels";
|
||||||
};
|
};
|
||||||
service.links = mkOption {
|
service.links = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
default = [];
|
default = [];
|
||||||
description = dockerComposeRef "links";
|
description = serviceRef "links";
|
||||||
};
|
};
|
||||||
service.external_links = mkOption {
|
service.external_links = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
default = [];
|
default = [];
|
||||||
description = dockerComposeRef "external_links";
|
description = serviceRef "external_links";
|
||||||
|
};
|
||||||
|
service.profiles = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
default = [];
|
||||||
|
description = serviceRef "profiles";
|
||||||
};
|
};
|
||||||
service.extra_hosts = mkOption {
|
service.extra_hosts = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
default = [];
|
default = [];
|
||||||
description = dockerComposeRef "extra_hosts";
|
description = serviceRef "extra_hosts";
|
||||||
};
|
};
|
||||||
service.working_dir = mkOption {
|
service.working_dir = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
default = null;
|
default = null;
|
||||||
description = dockerComposeKitchenSink;
|
description = ''
|
||||||
|
${serviceRef "working_dir"}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
service.privileged = mkOption {
|
service.privileged = mkOption {
|
||||||
type = nullOr bool;
|
type = nullOr bool;
|
||||||
default = null;
|
default = null;
|
||||||
description = dockerComposeKitchenSink;
|
description = ''
|
||||||
|
${serviceRef "privileged"}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
service.entrypoint = mkOption {
|
service.entrypoint = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
default = null;
|
default = null;
|
||||||
description = dockerComposeRef "entrypoint";
|
description = serviceRef "entrypoint";
|
||||||
};
|
};
|
||||||
service.restart = mkOption {
|
service.restart = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
default = null;
|
default = null;
|
||||||
description = dockerComposeRef "restart";
|
description = serviceRef "restart";
|
||||||
};
|
};
|
||||||
service.user = mkOption {
|
service.user = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
default = null;
|
default = null;
|
||||||
description = dockerComposeKitchenSink;
|
description = ''
|
||||||
|
${serviceRef "user"}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
service.ports = mkOption {
|
service.ports = mkOption {
|
||||||
type = listOf types.unspecified;
|
type = listOf types.unspecified;
|
||||||
|
@ -231,38 +257,76 @@ in
|
||||||
description = ''
|
description = ''
|
||||||
Expose ports on host. "host:container" or structured.
|
Expose ports on host. "host:container" or structured.
|
||||||
|
|
||||||
${dockerComposeRef "ports"}
|
${serviceRef "ports"}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
service.expose = mkOption {
|
service.expose = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
default = [];
|
default = [];
|
||||||
description = dockerComposeRef "expose";
|
description = serviceRef "expose";
|
||||||
};
|
};
|
||||||
service.env_file = mkOption {
|
service.env_file = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
default = [];
|
default = [];
|
||||||
description = dockerComposeRef "env_file";
|
description = serviceRef "env_file";
|
||||||
};
|
};
|
||||||
service.network_mode = mkOption {
|
service.network_mode = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
default = null;
|
default = null;
|
||||||
description = dockerComposeRef "network_mode";
|
description = serviceRef "network_mode";
|
||||||
};
|
|
||||||
service.networks = mkOption {
|
|
||||||
type = nullOr (listOf types.str);
|
|
||||||
default = null;
|
|
||||||
description = dockerComposeRef "networks";
|
|
||||||
};
|
};
|
||||||
|
service.networks =
|
||||||
|
let
|
||||||
|
networksModule = submodule ({ config, options, ...}: {
|
||||||
|
options = {
|
||||||
|
_out = mkOption {
|
||||||
|
internal = true;
|
||||||
|
readOnly = true;
|
||||||
|
default = lib.mapAttrs (k: opt: opt.value) (lib.filterAttrs (_: opt: opt.isDefined) { inherit (options) aliases ipv4_address ipv6_address link_local_ips priority; });
|
||||||
|
};
|
||||||
|
aliases = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
description = serviceRef "aliases";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
ipv4_address = mkOption {
|
||||||
|
type = str;
|
||||||
|
description = serviceRef "ipv4_address-ipv6_address";
|
||||||
|
};
|
||||||
|
ipv6_address = mkOption {
|
||||||
|
type = str;
|
||||||
|
description = serviceRef "ipv4_address-ipv6_address";
|
||||||
|
};
|
||||||
|
link_local_ips = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
description = serviceRef "link_local_ips";
|
||||||
|
};
|
||||||
|
priority = mkOption {
|
||||||
|
type = int;
|
||||||
|
description = serviceRef "priority";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
in
|
||||||
|
mkOption {
|
||||||
|
type = either (listOf str) (attrsOf networksModule);
|
||||||
|
default = [];
|
||||||
|
description = serviceRef "networks";
|
||||||
|
};
|
||||||
service.stop_signal = mkOption {
|
service.stop_signal = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
default = null;
|
default = null;
|
||||||
description = dockerComposeRef "stop_signal";
|
description = serviceRef "stop_signal";
|
||||||
|
};
|
||||||
|
service.stop_grace_period = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = null;
|
||||||
|
description = serviceRef "stop_grace_period";
|
||||||
};
|
};
|
||||||
service.sysctls = mkOption {
|
service.sysctls = mkOption {
|
||||||
type = attrsOf (either str int);
|
type = attrsOf (either str int);
|
||||||
default = {};
|
default = {};
|
||||||
description = dockerComposeRef "sysctls";
|
description = serviceRef "sysctls";
|
||||||
};
|
};
|
||||||
service.capabilities = mkOption {
|
service.capabilities = mkOption {
|
||||||
type = attrsOf (nullOr bool);
|
type = attrsOf (nullOr bool);
|
||||||
|
@ -273,13 +337,15 @@ in
|
||||||
|
|
||||||
Setting a capability to `true` means that it will be
|
Setting a capability to `true` means that it will be
|
||||||
"added". Setting it to `false` means that it will be "dropped".
|
"added". Setting it to `false` means that it will be "dropped".
|
||||||
${dockerComposeRef "cap_add-cap_drop"}
|
|
||||||
|
|
||||||
Omitted and `null` capabilities will therefore be set
|
Omitted and `null` capabilities will therefore be set
|
||||||
according to Docker's ${
|
according to Docker's ${
|
||||||
link "https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities"
|
link "https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities"
|
||||||
"default list of capabilities."
|
"default list of capabilities."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
${serviceRef "cap_add"}
|
||||||
|
${serviceRef "cap_drop"}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -289,10 +355,11 @@ in
|
||||||
volumes
|
volumes
|
||||||
environment
|
environment
|
||||||
sysctls
|
sysctls
|
||||||
image
|
|
||||||
;
|
;
|
||||||
} // lib.optionalAttrs (config.service.build.context != null) {
|
} // lib.optionalAttrs (config.service.image != null) {
|
||||||
inherit (config.service) build;
|
inherit (config.service) image;
|
||||||
|
} // lib.optionalAttrs (config.service.build.context != null ) {
|
||||||
|
build = lib.filterAttrs (n: v: v != null) config.service.build;
|
||||||
} // lib.optionalAttrs (cap_add != []) {
|
} // lib.optionalAttrs (cap_add != []) {
|
||||||
inherit cap_add;
|
inherit cap_add;
|
||||||
} // lib.optionalAttrs (cap_drop != []) {
|
} // lib.optionalAttrs (cap_drop != []) {
|
||||||
|
@ -331,12 +398,16 @@ in
|
||||||
inherit (config.service) privileged;
|
inherit (config.service) privileged;
|
||||||
} // lib.optionalAttrs (config.service.network_mode != null) {
|
} // lib.optionalAttrs (config.service.network_mode != null) {
|
||||||
inherit (config.service) network_mode;
|
inherit (config.service) network_mode;
|
||||||
} // lib.optionalAttrs (config.service.networks != null) {
|
} // lib.optionalAttrs (config.service.networks != [] && config.service.networks != {}) {
|
||||||
inherit (config.service) networks;
|
networks =
|
||||||
|
if (builtins.isAttrs config.service.networks) then builtins.mapAttrs (_: v: v._out) config.service.networks
|
||||||
|
else config.service.networks;
|
||||||
} // lib.optionalAttrs (config.service.restart != null) {
|
} // lib.optionalAttrs (config.service.restart != null) {
|
||||||
inherit (config.service) restart;
|
inherit (config.service) restart;
|
||||||
} // lib.optionalAttrs (config.service.stop_signal != null) {
|
} // lib.optionalAttrs (config.service.stop_signal != null) {
|
||||||
inherit (config.service) stop_signal;
|
inherit (config.service) stop_signal;
|
||||||
|
} // lib.optionalAttrs (config.service.stop_grace_period != null) {
|
||||||
|
inherit (config.service) stop_grace_period;
|
||||||
} // lib.optionalAttrs (config.service.tmpfs != []) {
|
} // lib.optionalAttrs (config.service.tmpfs != []) {
|
||||||
inherit (config.service) tmpfs;
|
inherit (config.service) tmpfs;
|
||||||
} // lib.optionalAttrs (config.service.tty != null) {
|
} // lib.optionalAttrs (config.service.tty != null) {
|
||||||
|
@ -345,5 +416,7 @@ in
|
||||||
inherit (config.service) working_dir;
|
inherit (config.service) working_dir;
|
||||||
} // lib.optionalAttrs (config.service.user != null) {
|
} // lib.optionalAttrs (config.service.user != null) {
|
||||||
inherit (config.service) user;
|
inherit (config.service) user;
|
||||||
|
} // lib.optionalAttrs (config.service.profiles != []) {
|
||||||
|
inherit (config.service) profiles;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,17 +163,19 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = {
|
config = lib.mkMerge [{
|
||||||
build.image = builtImage;
|
build.image = builtImage;
|
||||||
build.imageName = config.build.image.imageName;
|
build.imageName = config.build.image.imageName;
|
||||||
build.imageTag =
|
build.imageTag =
|
||||||
if config.build.image.imageTag != ""
|
if config.build.image.imageTag != ""
|
||||||
then config.build.image.imageTag
|
then config.build.image.imageTag
|
||||||
else lib.head (lib.strings.splitString "-" (baseNameOf config.build.image.outPath));
|
else lib.head (lib.strings.splitString "-" (baseNameOf config.build.image.outPath));
|
||||||
|
image.rawConfig.Cmd = config.image.command;
|
||||||
service.image = lib.mkDefault "${config.build.imageName}:${config.build.imageTag}";
|
image.nixBuild = lib.mkDefault (priorityIsDefault options.service.image);
|
||||||
image.rawConfig.Cmd = config.image.command;
|
}
|
||||||
|
( lib.mkIf (config.service.build.context == null)
|
||||||
image.nixBuild = lib.mkDefault (priorityIsDefault options.service.image);
|
{
|
||||||
};
|
service.image = lib.mkDefault "${config.build.imageName}:${config.build.imageTag}";
|
||||||
|
})
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ in
|
||||||
service.tmpfs = [
|
service.tmpfs = [
|
||||||
"/run" # noexec is fine because exes should be symlinked from elsewhere anyway
|
"/run" # noexec is fine because exes should be symlinked from elsewhere anyway
|
||||||
"/run/wrappers" # noexec breaks this intentionally
|
"/run/wrappers" # noexec breaks this intentionally
|
||||||
] ++ lib.optional (config.nixos.evaluatedConfig.boot.tmpOnTmpfs) "/tmp:exec,mode=777";
|
] ++ lib.optional (config.nixos.evaluatedConfig.boot.tmp.useTmpfs) "/tmp:exec,mode=777";
|
||||||
|
|
||||||
service.stop_signal = "SIGRTMIN+3";
|
service.stop_signal = "SIGRTMIN+3";
|
||||||
service.tty = true;
|
service.tty = true;
|
||||||
|
|
|
@ -29,7 +29,7 @@ in
|
||||||
enable = true;
|
enable = true;
|
||||||
dockerSocket.enable = true;
|
dockerSocket.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# no caches, because no internet
|
# no caches, because no internet
|
||||||
nix.settings.substituters = lib.mkForce [];
|
nix.settings.substituters = lib.mkForce [];
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ in
|
||||||
pkgs.stdenv
|
pkgs.stdenv
|
||||||
];
|
];
|
||||||
|
|
||||||
virtualisation.memorySize = 1024;
|
virtualisation.memorySize = 2048;
|
||||||
virtualisation.diskSize = 8000;
|
virtualisation.diskSize = 8000;
|
||||||
};
|
};
|
||||||
testScript = ''
|
testScript = ''
|
||||||
|
|
|
@ -4,7 +4,7 @@ pkgs.nixosTest {
|
||||||
name = "test-basic-arion-kafka";
|
name = "test-basic-arion-kafka";
|
||||||
nodes = {
|
nodes = {
|
||||||
machine = { ... }: {
|
machine = { ... }: {
|
||||||
virtualisation.memorySize = 3000;
|
virtualisation.memorySize = 4096;
|
||||||
virtualisation.diskSize = 10000;
|
virtualisation.diskSize = 10000;
|
||||||
imports = [
|
imports = [
|
||||||
../../nixos-module.nix
|
../../nixos-module.nix
|
||||||
|
|
Loading…
Reference in a new issue