summary refs log tree commit diff
diff options
context:
space:
mode:
authoradisbladis <adisbladis@gmail.com>2020-04-20 12:31:07 +0100
committeradisbladis <adisbladis@gmail.com>2020-05-04 13:47:25 +0100
commit2f7747526cc80844a506c4aa14706429324be157 (patch)
treee5e61dd3873c02c23cced6afbc79c7be45294d8e
parent2fb5dac372fedd482ef3c65b608810bb7dd45083 (diff)
downloadnixpkgs-2f7747526cc80844a506c4aa14706429324be157.tar
nixpkgs-2f7747526cc80844a506c4aa14706429324be157.tar.gz
nixpkgs-2f7747526cc80844a506c4aa14706429324be157.tar.bz2
nixpkgs-2f7747526cc80844a506c4aa14706429324be157.tar.lz
nixpkgs-2f7747526cc80844a506c4aa14706429324be157.tar.xz
nixpkgs-2f7747526cc80844a506c4aa14706429324be157.tar.zst
nixpkgs-2f7747526cc80844a506c4aa14706429324be157.zip
nixos/docker-containers: Rename to virtualisation.oci-containers.containers.
And allow the runtime to be configurable via the
`virtualisation.oci-containers.backend` option.

Valid choices are "podman" and "docker".
-rw-r--r--nixos/doc/manual/release-notes/rl-2009.xml6
-rw-r--r--nixos/modules/module-list.nix2
-rw-r--r--nixos/modules/virtualisation/oci-containers.nix (renamed from nixos/modules/virtualisation/docker-containers.nix)124
-rw-r--r--nixos/modules/virtualisation/podman.nix12
-rw-r--r--nixos/tests/all-tests.nix2
-rw-r--r--nixos/tests/docker-containers.nix27
-rw-r--r--nixos/tests/oci-containers.nix43
7 files changed, 145 insertions, 71 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2009.xml b/nixos/doc/manual/release-notes/rl-2009.xml
index 78b8eee47ef..c6a766cc045 100644
--- a/nixos/doc/manual/release-notes/rl-2009.xml
+++ b/nixos/doc/manual/release-notes/rl-2009.xml
@@ -55,6 +55,12 @@
      The new <varname>virtualisation.containers</varname> module manages configuration shared by the CRI-O and Podman modules.
     </para>
    </listitem>
+   <listitem>
+    <para>
+      Declarative Docker containers are renamed from <varname>docker-containers</varname> to <varname>virtualisation.oci-containers.containers</varname>.
+      This is to make it possible to use <literal>podman</literal> instead of <literal>docker</literal>.
+    </para>
+   </listitem>
   </itemizedlist>
  </section>
 
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 0cd17775e51..28f536056bf 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -984,9 +984,9 @@
   ./virtualisation/container-config.nix
   ./virtualisation/containers.nix
   ./virtualisation/nixos-containers.nix
+  ./virtualisation/oci-containers.nix
   ./virtualisation/cri-o.nix
   ./virtualisation/docker.nix
-  ./virtualisation/docker-containers.nix
   ./virtualisation/ecs-agent.nix
   ./virtualisation/libvirtd.nix
   ./virtualisation/lxc.nix
diff --git a/nixos/modules/virtualisation/docker-containers.nix b/nixos/modules/virtualisation/oci-containers.nix
index 5ab990a3d7c..a46dd65eb49 100644
--- a/nixos/modules/virtualisation/docker-containers.nix
+++ b/nixos/modules/virtualisation/oci-containers.nix
@@ -1,17 +1,20 @@
-{ config, lib, pkgs, ... }:
+{ config, options, lib, pkgs, ... }:
 
 with lib;
 let
-  cfg = config.docker-containers;
+  cfg = config.virtualisation.oci-containers;
+  proxy_env = config.networking.proxy.envVars;
 
-  dockerContainer =
+  defaultBackend = options.virtualisation.oci-containers.backend.default;
+
+  containerOptions =
     { ... }: {
 
       options = {
 
         image = mkOption {
           type = with types; str;
-          description = "Docker image to run.";
+          description = "OCI image to run.";
           example = "library/hello-world";
         };
 
@@ -58,18 +61,19 @@ let
 
         log-driver = mkOption {
           type = types.str;
-          default = "none";
+          default = "journald";
           description = ''
             Logging driver for the container.  The default of
-            <literal>"none"</literal> means that the container's logs will be
-            handled as part of the systemd unit.  Setting this to
-            <literal>"journald"</literal> will result in duplicate logging, but
-            the container's logs will be visible to the <command>docker
-            logs</command> command.
-
-            For more details and a full list of logging drivers, refer to the
-            <link xlink:href="https://docs.docker.com/engine/reference/run/#logging-drivers---log-driver">
-            Docker engine documentation</link>
+            <literal>"journald"</literal> means that the container's logs will be
+            handled as part of the systemd unit.
+
+            For more details and a full list of logging drivers, refer to respective backends documentation.
+
+            For Docker:
+            <link xlink:href="https://docs.docker.com/engine/reference/run/#logging-drivers---log-driver">Docker engine documentation</link>
+
+            For Podman:
+            Refer to the docker-run(1) man page.
           '';
         };
 
@@ -172,10 +176,10 @@ let
           description = ''
             Define which other containers this one depends on. They will be added to both After and Requires for the unit.
 
-            Use the same name as the attribute under <literal>services.docker-containers</literal>.
+            Use the same name as the attribute under <literal>virtualisation.oci-containers</literal>.
           '';
           example = literalExample ''
-            services.docker-containers = {
+            virtualisation.oci-containers = {
               node1 = {};
               node2 = {
                 dependsOn = [ "node1" ];
@@ -184,10 +188,10 @@ let
           '';
         };
 
-        extraDockerOptions = mkOption {
+        extraOptions = mkOption {
           type = with types; listOf str;
           default = [];
-          description = "Extra options for <command>docker run</command>.";
+          description = "Extra options for <command>${defaultBackend} run</command>.";
           example = literalExample ''
             ["--network=host"]
           '';
@@ -205,24 +209,31 @@ let
     };
 
   mkService = name: container: let
-    mkAfter = map (x: "docker-${x}.service") container.dependsOn;
-  in rec {
+    dependsOn = map (x: "${cfg.backend}-${x}.service") container.dependsOn;
+  in {
     wantedBy = [] ++ optional (container.autoStart) "multi-user.target";
-    after = [ "docker.service" "docker.socket" ] ++ mkAfter;
-    requires = after;
-    path = [ pkgs.docker ];
+    after = lib.optionals (cfg.backend == "docker") [ "docker.service" "docker.socket" ] ++ dependsOn;
+    requires = dependsOn;
+    environment = proxy_env;
+
+    path =
+      if cfg.backend == "docker" then [ pkgs.docker ]
+      else if cfg.backend == "podman" then [ config.virtualisation.podman.package ]
+      else throw "Unhandled backend: ${cfg.backend}";
 
     preStart = ''
-      docker rm -f ${name} || true
+      ${cfg.backend} rm -f ${name} || true
       ${optionalString (container.imageFile != null) ''
-        docker load -i ${container.imageFile}
+        ${cfg.backend} load -i ${container.imageFile}
         ''}
       '';
-    postStop = "docker rm -f ${name} || true";
-        
+    postStop = "${cfg.backend} rm -f ${name} || true";
+
     serviceConfig = {
+      StandardOutput = "null";
+      StandardError = "null";
       ExecStart = concatStringsSep " \\\n  " ([
-        "${pkgs.docker}/bin/docker run"
+        "${config.system.path}/bin/${cfg.backend} run"
         "--rm"
         "--name=${name}"
         "--log-driver=${container.log-driver}"
@@ -233,12 +244,12 @@ let
         ++ optional (container.user != null) "-u ${escapeShellArg container.user}"
         ++ map (v: "-v ${escapeShellArg v}") container.volumes
         ++ optional (container.workdir != null) "-w ${escapeShellArg container.workdir}"
-        ++ map escapeShellArg container.extraDockerOptions
+        ++ map escapeShellArg container.extraOptions
         ++ [container.image]
         ++ map escapeShellArg container.cmd
       );
 
-      ExecStop = ''${pkgs.bash}/bin/sh -c "[ $SERVICE_RESULT = success ] || docker stop ${name}"'';
+      ExecStop = ''${pkgs.bash}/bin/sh -c "[ $SERVICE_RESULT = success ] || ${cfg.backend} stop ${name}"'';
 
       ### There is no generalized way of supporting `reload` for docker
       ### containers. Some containers may respond well to SIGHUP sent to their
@@ -263,19 +274,50 @@ let
   };
 
 in {
+  imports = [
+    (
+      lib.mkChangedOptionModule
+      [ "docker-containers"  ]
+      [ "virtualisation" "oci-containers" ]
+      (oldcfg: {
+        backend = "docker";
+        containers = lib.mapAttrs (n: v: builtins.removeAttrs (v // {
+          extraOptions = v.extraDockerOptions or [];
+        }) [ "extraDockerOptions" ]) oldcfg.docker-containers;
+      })
+    )
+  ];
+
+  options.virtualisation.oci-containers = {
+
+    backend = mkOption {
+      type = types.enum [ "podman" "docker" ];
+      default =
+        # TODO: Once https://github.com/NixOS/nixpkgs/issues/77925 is resolved default to podman
+        # if versionAtLeast config.system.stateVersion "20.09" then "podman"
+        # else "docker";
+        "docker";
+      description = "The underlying Docker implementation to use.";
+    };
 
-  options.docker-containers = mkOption {
-    default = {};
-    type = types.attrsOf (types.submodule dockerContainer);
-    description = "Docker containers to run as systemd services.";
-  };
-
-  config = mkIf (cfg != {}) {
-
-    systemd.services = mapAttrs' (n: v: nameValuePair "docker-${n}" (mkService n v)) cfg;
-
-    virtualisation.docker.enable = true;
+    containers = mkOption {
+      default = {};
+      type = types.attrsOf (types.submodule containerOptions);
+      description = "OCI (Docker) containers to run as systemd services.";
+    };
 
   };
 
+  config = lib.mkIf (cfg.containers != {}) (lib.mkMerge [
+    {
+      systemd.services = mapAttrs' (n: v: nameValuePair "${cfg.backend}-${n}" (mkService n v)) cfg.containers;
+    }
+    (lib.mkIf (cfg.backend == "podman") {
+      virtualisation.podman.enable = true;
+    })
+    (lib.mkIf (cfg.backend == "docker") {
+      virtualisation.docker.enable = true;
+    })
+  ]);
+
 }
diff --git a/nixos/modules/virtualisation/podman.nix b/nixos/modules/virtualisation/podman.nix
index 1dc79272ccb..9f98c2086d1 100644
--- a/nixos/modules/virtualisation/podman.nix
+++ b/nixos/modules/virtualisation/podman.nix
@@ -88,11 +88,21 @@ in
       };
     };
 
+    package = lib.mkOption {
+      type = types.package;
+      default = podmanPackage;
+      internal = true;
+      description = ''
+        The final Podman package (including extra packages).
+      '';
+    };
+
+
   };
 
   config = lib.mkIf cfg.enable {
 
-    environment.systemPackages = [ podmanPackage ]
+    environment.systemPackages = [ cfg.package ]
       ++ lib.optional cfg.dockerCompat dockerCompat;
 
     environment.etc."containers/libpod.conf".text = ''
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index eff1752bbbf..ebb0dfef15a 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -70,7 +70,7 @@ in
   dhparams = handleTest ./dhparams.nix {};
   dnscrypt-proxy2 = handleTestOn ["x86_64-linux"] ./dnscrypt-proxy2.nix {};
   docker = handleTestOn ["x86_64-linux"] ./docker.nix {};
-  docker-containers = handleTestOn ["x86_64-linux"] ./docker-containers.nix {};
+  oci-containers = handleTestOn ["x86_64-linux"] ./oci-containers.nix {};
   docker-edge = handleTestOn ["x86_64-linux"] ./docker-edge.nix {};
   docker-preloader = handleTestOn ["x86_64-linux"] ./docker-preloader.nix {};
   docker-registry = handleTest ./docker-registry.nix {};
diff --git a/nixos/tests/docker-containers.nix b/nixos/tests/docker-containers.nix
deleted file mode 100644
index 0e318a52d9f..00000000000
--- a/nixos/tests/docker-containers.nix
+++ /dev/null
@@ -1,27 +0,0 @@
-# Test Docker containers as systemd units
-
-import ./make-test-python.nix ({ pkgs, lib, ... }: {
-  name = "docker-containers";
-  meta = {
-    maintainers = with lib.maintainers; [ benley mkaito ];
-  };
-
-  nodes = {
-    docker = { pkgs, ... }: {
-      virtualisation.docker.enable = true;
-
-      docker-containers.nginx = {
-        image = "nginx-container";
-        imageFile = pkgs.dockerTools.examples.nginx;
-        ports = ["8181:80"];
-      };
-    };
-  };
-
-  testScript = ''
-    start_all()
-    docker.wait_for_unit("docker-nginx.service")
-    docker.wait_for_open_port(8181)
-    docker.wait_until_succeeds("curl http://localhost:8181 | grep Hello")
-  '';
-})
diff --git a/nixos/tests/oci-containers.nix b/nixos/tests/oci-containers.nix
new file mode 100644
index 00000000000..bb6c019f07c
--- /dev/null
+++ b/nixos/tests/oci-containers.nix
@@ -0,0 +1,43 @@
+{ system ? builtins.currentSystem
+, config ? {}
+, pkgs ? import ../.. { inherit system config; }
+, lib ? pkgs.lib
+}:
+
+let
+
+  inherit (import ../lib/testing-python.nix { inherit system pkgs; }) makeTest;
+
+  mkOCITest = backend: makeTest {
+    name = "oci-containers-${backend}";
+
+    meta = {
+      maintainers = with lib.maintainers; [ adisbladis benley mkaito ];
+    };
+
+    nodes = {
+      ${backend} = { pkgs, ... }: {
+        virtualisation.oci-containers = {
+          inherit backend;
+          containers.nginx = {
+            image = "nginx-container";
+            imageFile = pkgs.dockerTools.examples.nginx;
+            ports = ["8181:80"];
+          };
+        };
+      };
+    };
+
+    testScript = ''
+      start_all()
+      ${backend}.wait_for_unit("${backend}-nginx.service")
+      ${backend}.wait_for_open_port(8181)
+      ${backend}.wait_until_succeeds("curl http://localhost:8181 | grep Hello")
+    '';
+  };
+
+in
+lib.foldl' (attrs: backend: attrs // { ${backend} = mkOCITest backend; }) {} [
+  "docker"
+  "podman"
+]