Assertions, warnings, renames

This commit is contained in:
Robert Hensing 2019-10-03 21:30:14 +02:00
parent 6abcc26a76
commit c3a5f8c13f
14 changed files with 106 additions and 27 deletions

View file

@ -19,6 +19,7 @@ data-files: nix/*.nix
, nix/modules/composition/*.nix
, nix/modules/nixos/*.nix
, nix/modules/service/*.nix
, nix/modules/lib/*.nix
-- all data is verbatim from some sources
data-dir: src

View file

@ -11,7 +11,7 @@ let
eval = import (srcDir + "/nix/eval-composition.nix");
build = args@{...}:
let composition = eval args;
in composition.config.build.dockerComposeYaml;
in composition.config.out.dockerComposeYaml;
in
justStaticExecutables (overrideCabal arion-compose (o: {

View file

@ -51,7 +51,7 @@ evaluateComposition ea = do
, "--strict"
, "--json"
, "--attr"
, "config.build.dockerComposeYamlAttrs"
, "config.out.dockerComposeYamlAttrs"
]
args =
[ evalComposition ]
@ -99,7 +99,7 @@ buildComposition outLink ea = do
evalComposition <- getEvalCompositionFile
let commandArgs =
[ "--attr"
, "config.build.dockerComposeYaml"
, "config.out.dockerComposeYaml"
, "--out-link"
, outLink
]

View file

@ -34,7 +34,7 @@ let
};
in
# Typically you need composition.config.build.dockerComposeYaml
# Typically you need composition.config.out.dockerComposeYaml
composition // {
# throw in lib and pkgs for repl convenience
inherit lib;

View file

@ -34,7 +34,7 @@ in
config = {
arionBaseImage = "${name}:${tag}";
build.imagesToLoad = lib.mkIf (lib.any (s: s.service.useHostStore) (lib.attrValues config.docker-compose.services)) [
build.imagesToLoad = lib.mkIf (lib.any (s: s.service.useHostStore) (lib.attrValues config.services)) [
{ image = builtImage; imageName = name; imageTag = tag; }
];
};

View file

@ -3,10 +3,10 @@
This is a composition-level module.
It defines the low-level options that are read by arion, like
- build.dockerComposeYaml
- out.dockerComposeYaml
It declares options like
- docker-compose.services
- services
*/
compositionArgs@{ lib, config, options, pkgs, ... }:
@ -31,20 +31,24 @@ let
in
{
imports = [
../lib/assert.nix
(lib.mkRenamedOptionModule ["docker-compose" "services"] ["services"])
];
options = {
build.dockerComposeYaml = lib.mkOption {
out.dockerComposeYaml = lib.mkOption {
type = lib.types.package;
description = "A derivation that produces a docker-compose.yaml file for this composition.";
readOnly = true;
};
build.dockerComposeYamlText = lib.mkOption {
out.dockerComposeYamlText = lib.mkOption {
type = lib.types.str;
description = "The text of build.dockerComposeYaml.";
description = "The text of out.dockerComposeYaml.";
readOnly = true;
};
build.dockerComposeYamlAttrs = lib.mkOption {
out.dockerComposeYamlAttrs = lib.mkOption {
type = lib.types.attrsOf lib.types.unspecified;
description = "The text of build.dockerComposeYaml.";
description = "The text of out.dockerComposeYaml.";
readOnly = true;
};
docker-compose.raw = lib.mkOption {
@ -55,19 +59,19 @@ in
type = lib.types.attrs;
description = "Attribute set that will be turned into the x-arion section of the docker-compose.yaml file.";
};
docker-compose.services = lib.mkOption {
services = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule service);
description = "An attribute set of service configurations. A service specifies how to run an image as a container.";
};
};
config = {
build.dockerComposeYaml = pkgs.writeText "docker-compose.yaml" config.build.dockerComposeYamlText;
build.dockerComposeYamlText = builtins.toJSON (config.build.dockerComposeYamlAttrs);
build.dockerComposeYamlAttrs = config.docker-compose.raw;
out.dockerComposeYaml = pkgs.writeText "docker-compose.yaml" config.out.dockerComposeYamlText;
out.dockerComposeYamlText = builtins.toJSON (config.out.dockerComposeYamlAttrs);
out.dockerComposeYamlAttrs = config.assertWarn config.docker-compose.raw;
docker-compose.raw = {
version = "3.4";
services = lib.mapAttrs (k: c: c.build.service) config.docker-compose.services;
services = lib.mapAttrs (k: c: c.out.service) config.services;
x-arion = config.docker-compose.extended;
};
};

View file

@ -4,7 +4,7 @@ let
serviceImages =
lib.mapAttrs addDetails (
lib.filterAttrs filterFunction config.docker-compose.services
lib.filterAttrs filterFunction config.services
);
filterFunction = serviceName: service:
@ -14,7 +14,7 @@ let
addDetails = serviceName: service:
builtins.addErrorContext "while evaluating the image for service ${serviceName}"
(let
inherit (service.config) build;
inherit (service) build;
in {
image = build.image.outPath;
imageName = build.imageName or service.image.name;

View file

@ -7,7 +7,7 @@
let
serviceInfo =
lib.mapAttrs getInfo (
lib.filterAttrs filterFunction config.docker-compose.services
lib.filterAttrs filterFunction config.services
);
filterFunction = _serviceName: service:

View file

@ -0,0 +1,2 @@
`assertions.nix`: Nixpkgs
`assert.nix`: extracted from Nixpkgs, adapted

View file

@ -0,0 +1,32 @@
{ config, lib, pkgs, ... }:
# based on nixpkgs/nixos/modules/system/activation/top-level.nix
let
inherit (lib) filter concatStringsSep types mkOption;
# lib.showWarnings since 19.09
showWarnings = warnings: res: lib.fold (w: x: lib.warn w x) res warnings;
warn = msg: builtins.trace "warning: ${msg}";
# Handle assertions and warnings
failedAssertions = map (x: x.message) (filter (x: !x.assertion) config.assertions);
assertWarn = if failedAssertions != []
then throw "\nFailed assertions:\n${concatStringsSep "\n" (map (x: "- ${x}") failedAssertions)}"
else showWarnings config.warnings;
in
{
imports = [ ./assertions.nix ];
options.assertWarn = mkOption {
type = types.unspecified; # a function
# It's for the wrapping program to know about this. User need not care.
internal = true;
readOnly = true;
};
config = { inherit assertWarn; };
}

View file

@ -0,0 +1,34 @@
{ lib, ... }:
with lib;
{
options = {
assertions = mkOption {
type = types.listOf types.unspecified;
internal = true;
default = [];
example = [ { assertion = false; message = "you can't enable this for that reason"; } ];
description = ''
This option allows modules to express conditions that must
hold for the evaluation of the system configuration to
succeed, along with associated error messages for the user.
'';
};
warnings = mkOption {
internal = true;
default = [];
type = types.listOf types.str;
example = [ "The `foo' service is deprecated and will go away soon!" ];
description = ''
This option allows modules to show warnings to users during
the evaluation of the system configuration.
'';
};
};
# impl of assertions is in <nixpkgs/nixos/modules/system/activation/top-level.nix>
}

View file

@ -7,4 +7,5 @@
./image.nix
./nixos.nix
./nixos-init.nix
../lib/assert.nix
]

View file

@ -1,6 +1,6 @@
/*
This service-level module defines the build.service option, using
This service-level module defines the out.service option, using
the user-facing options service.image, service.volumes, etc.
*/
@ -25,8 +25,12 @@ let
in
{
imports = [
(lib.mkRenamedOptionModule ["build" "service"] ["out" "service"])
];
options = {
build.service = mkOption {
out.service = mkOption {
type = attrsOf types.unspecified;
description = ''
Raw input for the service in <code>docker-compose.yaml</code>.
@ -37,12 +41,13 @@ in
This option is user accessible because it may serve as an
escape hatch for some.
'';
apply = config.assertWarn;
};
service.name = mkOption {
type = str;
description = ''
The name of the service - <code>&lt;name></code> in the composition-level <code>docker-compose.services.&lt;name></code>
The name of the service - <code>&lt;name></code> in the composition-level <code>services.&lt;name></code>
'';
readOnly = true;
};
@ -209,7 +214,7 @@ in
};
};
config.build.service = {
config.out.service = {
inherit (config.service)
volumes
environment

View file

@ -30,9 +30,9 @@ in
virtualisation.pathsInNixDB = [
# Pre-build the image because we don't want to build the world
# in the vm.
(preEval [ ../../examples/minimal/arion-compose.nix ]).config.build.dockerComposeYaml
(preEval [ ../../examples/full-nixos/arion-compose.nix ]).config.build.dockerComposeYaml
(preEval [ ../../examples/nixos-unit/arion-compose.nix ]).config.build.dockerComposeYaml
(preEval [ ../../examples/minimal/arion-compose.nix ]).config.out.dockerComposeYaml
(preEval [ ../../examples/full-nixos/arion-compose.nix ]).config.out.dockerComposeYaml
(preEval [ ../../examples/nixos-unit/arion-compose.nix ]).config.out.dockerComposeYaml
pkgs.stdenv
];
};