diff --git a/src/nix/modules.nix b/src/nix/modules.nix index b176b2e..ecc73c1 100644 --- a/src/nix/modules.nix +++ b/src/nix/modules.nix @@ -3,6 +3,5 @@ ./modules/composition/host-environment.nix ./modules/composition/images.nix ./modules/composition/service-info.nix - ./modules/composition/arion-base-image.nix ./modules/composition/composition.nix ] \ No newline at end of file diff --git a/src/nix/modules/composition/arion-base-image.nix b/src/nix/modules/composition/arion-base-image.nix deleted file mode 100644 index b471313..0000000 --- a/src/nix/modules/composition/arion-base-image.nix +++ /dev/null @@ -1,40 +0,0 @@ - - -# This module is subject to change. -# In particular, arion-base should use a generic non-service image building system - -{ config, lib, pkgs, ... }: - -let - name = "arion-base"; - - imageExe = pkgs.dockerTools.streamLayeredImage { - inherit name; - contents = pkgs.runCommand "minimal-contents" {} '' - mkdir -p $out/bin $out/usr/bin - ln -s /run/system/bin/sh $out/bin/sh - ln -s /run/system/usr/bin/env $out/usr/bin/env - ''; - config = {}; - }; - inherit (imageExe) imageTag; - -in - -{ - - options = { - arionBaseImage = lib.mkOption { - type = lib.types.str; - description = "Image to use when using useHostStore. Don't use this option yourself. It's going away."; - internal = true; - }; - }; - - config = { - arionBaseImage = "${name}:${imageTag}"; - build.imagesToLoad = lib.mkIf (lib.any (s: s.service.useHostStore) (lib.attrValues config.services)) [ - { imageExe = imageExe; imageName = name; inherit imageTag; } - ]; - }; -} \ No newline at end of file diff --git a/src/nix/modules/service/host-store.nix b/src/nix/modules/service/host-store.nix index 3167608..f50c509 100644 --- a/src/nix/modules/service/host-store.nix +++ b/src/nix/modules/service/host-store.nix @@ -29,12 +29,10 @@ in }; }; config = mkIf config.service.useHostStore { - image.nixBuild = false; # no need to build and load - service.image = config.composition.arionBaseImage; + image.includeStorePaths = false; service.environment.NIX_REMOTE = lib.optionalString config.service.useHostNixDaemon "daemon"; service.volumes = [ "${config.host.nixStorePrefix}/nix/store:/nix/store${lib.optionalString config.service.hostStoreAsReadOnly ":ro"}" - "${config.host.nixStorePrefix}${pkgs.buildEnv { name = "container-system-env"; paths = [ pkgs.bashInteractive pkgs.coreutils ]; }}:/run/system${lib.optionalString config.service.hostStoreAsReadOnly ":ro"}" ] ++ lib.optional config.service.useHostNixDaemon "/nix/var/nix/daemon-socket:/nix/var/nix/daemon-socket"; service.command = lib.mkDefault (map escape (config.image.rawConfig.Cmd or [])); }; diff --git a/src/nix/modules/service/image.nix b/src/nix/modules/service/image.nix index df78ac2..8d8884c 100644 --- a/src/nix/modules/service/image.nix +++ b/src/nix/modules/service/image.nix @@ -1,6 +1,15 @@ { pkgs, lib, config, options, ... }: let - inherit (lib) types mkOption; + inherit (lib) + functionArgs + mkOption + optionalAttrs + types + warn + ; + inherit (pkgs) + dockerTools + ; inherit (types) attrsOf listOf nullOr package str unspecified bool; # TODO: dummy-config is a useless layer. Nix 2.3 will let us inspect @@ -9,15 +18,37 @@ let (pkgs.writeText "dummy-config.json" (builtins.toJSON config.image.rawConfig)) ]; + includeStorePathsWarningAndDefault = lib.warn '' + You're using a version of Nixpkgs that doesn't support the includeStorePaths + parameter in dockerTools.streamLayeredImage. Without this, Arion's + useHostStore does not achieve the intended speedup. + '' {}; + buildOrStreamLayeredImage = args: - if pkgs.dockerTools?streamLayeredImage - then pkgs.dockerTools.streamLayeredImage args // { isExe = true; } - else pkgs.dockerTools.buildLayeredImage args; + let + args_base = builtins.intersectAttrs + { + name = null; tag = null; contents = null; config = null; + created = null; extraCommands = null; maxLayers = null; + } + args; + acceptedArgs = functionArgs dockerTools.streamLayeredImage; + args_no_store = lib.optionalAttrs (!(args.includeStorePaths or true)) ( + if acceptedArgs ? includeStorePaths + then { inherit (args) includeStorePaths; } + else includeStorePathsWarningAndDefault + ); + args_streamLayered = args_base // args_no_store; + in + if dockerTools?streamLayeredImage + then dockerTools.streamLayeredImage args_streamLayered // { isExe = true; } + else dockerTools.buildLayeredImage args_base; builtImage = buildOrStreamLayeredImage { inherit (config.image) name contents + includeStorePaths ; config = config.image.rawConfig; maxLayers = 100; @@ -89,6 +120,15 @@ in Top level paths in the container. ''; }; + image.includeStorePaths = mkOption { + type = bool; + default = true; + internal = true; + description = '' + Include all referenced store paths. You generally want this in your + image, unless you load store paths via some other means, like useHostStore = true; + ''; + }; image.rawConfig = mkOption { type = attrsOf unspecified; default = {};