From b512a788a4c135c42a5af75ece88d67efaddd4d9 Mon Sep 17 00:00:00 2001 From: adisbladis Date: Mon, 20 Apr 2020 09:37:53 +0100 Subject: [PATCH 1/4] nixos/virtualisation.podman: Init module --- nixos/doc/manual/release-notes/rl-2009.xml | 5 + nixos/modules/module-list.nix | 1 + nixos/modules/virtualisation/podman.nix | 192 +++++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/podman.nix | 30 ++++ 5 files changed, 229 insertions(+) create mode 100644 nixos/modules/virtualisation/podman.nix create mode 100644 nixos/tests/podman.nix diff --git a/nixos/doc/manual/release-notes/rl-2009.xml b/nixos/doc/manual/release-notes/rl-2009.xml index 0f22f4331f4d..85071bf78465 100644 --- a/nixos/doc/manual/release-notes/rl-2009.xml +++ b/nixos/doc/manual/release-notes/rl-2009.xml @@ -40,6 +40,11 @@ make use of these new options instead. + + + There is a new module for Podman(virtualisation.podman), a drop-in replacement for the Docker command line. + + diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index df08ac2959ed..38452fddf315 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -997,6 +997,7 @@ ./virtualisation/kvmgt.nix ./virtualisation/openvswitch.nix ./virtualisation/parallels-guest.nix + ./virtualisation/podman.nix ./virtualisation/qemu-guest-agent.nix ./virtualisation/railcar.nix ./virtualisation/rkt.nix diff --git a/nixos/modules/virtualisation/podman.nix b/nixos/modules/virtualisation/podman.nix new file mode 100644 index 000000000000..c1777eb95d94 --- /dev/null +++ b/nixos/modules/virtualisation/podman.nix @@ -0,0 +1,192 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.virtualisation.podman; + + inherit (lib) mkOption types; + + + # Provides a fake "docker" binary mapping to podman + dockerCompat = pkgs.runCommandNoCC "${pkgs.podman.pname}-docker-compat-${pkgs.podman.version}" { + outputs = [ "out" "bin" "man" ]; + inherit (pkgs.podman) meta; + } '' + mkdir $out + + mkdir -p $bin/bin + ln -s ${pkgs.podman.bin}/bin/podman $bin/bin/docker + + mkdir -p $man/share/man/man1 + for f in ${pkgs.podman.man}/share/man/man1/*; do + basename=$(basename $f | sed s/podman/docker/g) + ln -s $f $man/share/man/man1/$basename + done + ''; + + # Once https://github.com/NixOS/nixpkgs/pull/75584 is merged we can use the TOML generator + toTOML = name: value: pkgs.runCommandNoCC name { + nativeBuildInputs = [ pkgs.remarshal ]; + value = builtins.toJSON value; + passAsFile = [ "value" ]; + } '' + json2toml "$valuePath" "$out" + ''; + + # Copy configuration files to avoid having the entire sources in the system closure + copyFile = filePath: pkgs.runCommandNoCC (builtins.unsafeDiscardStringContext (builtins.baseNameOf filePath)) {} '' + cp ${filePath} $out + ''; +in +{ + + options.virtualisation.podman = { + + enable = + mkOption { + type = types.bool; + default = false; + description = '' + This option enables Podman, a daemonless container engine for + developing, managing, and running OCI Containers on your Linux System. + + It is a drop-in replacement for the docker command. + ''; + }; + + dockerCompat = mkOption { + type = types.bool; + default = false; + description = '' + Create an alias mapping docker to podman. + ''; + }; + + registries = { + search = mkOption { + type = types.listOf types.str; + default = [ "docker.io" "quay.io" ]; + description = '' + List of repositories to search. + ''; + }; + + insecure = mkOption { + default = []; + type = types.listOf types.str; + description = '' + List of insecure repositories. + ''; + }; + + block = mkOption { + default = []; + type = types.listOf types.str; + description = '' + List of blocked repositories. + ''; + }; + }; + + policy = mkOption { + default = {}; + type = types.attrs; + example = lib.literalExample '' + { + default = [ { type = "insecureAcceptAnything"; } ]; + transports = { + docker-daemon = { + "" = [ { type = "insecureAcceptAnything"; } ]; + }; + }; + } + ''; + description = '' + Signature verification policy file. + If this option is empty the default policy file from + skopeo will be used. + ''; + }; + + users = mkOption { + default = []; + type = types.listOf types.str; + description = '' + List of users to set up subuid/subgid mappings for. + This is a requirement for running containers in rootless mode. + ''; + }; + + libpod = mkOption { + default = {}; + description = "Libpod configuration"; + type = types.submodule { + options = { + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra configuration that should be put in the libpod.conf + configuration file + ''; + + }; + }; + }; + }; + + }; + + config = lib.mkIf cfg.enable { + + environment.systemPackages = [ + pkgs.podman # Docker compat + pkgs.runc # Default container runtime + pkgs.crun # Default container runtime (cgroups v2) + pkgs.conmon # Container runtime monitor + pkgs.skopeo # Interact with container registry + pkgs.slirp4netns # User-mode networking for unprivileged namespaces + pkgs.fuse-overlayfs # CoW for images, much faster than default vfs + pkgs.utillinux # nsenter + pkgs.cni-plugins # Networking plugins + pkgs.iptables + ] + ++ lib.optional cfg.dockerCompat dockerCompat; + + environment.etc."containers/libpod.conf".text = '' + cni_plugin_dir = ["${pkgs.cni-plugins}/bin/"] + cni_config_dir = "/etc/cni/net.d/" + ${cfg.libpod.extraConfig} + ''; + + environment.etc."cni/net.d/87-podman-bridge.conflist".source = copyFile "${pkgs.podman.src}/cni/87-podman-bridge.conflist"; + + environment.etc."containers/registries.conf".source = toTOML "registries.conf" { + registries = lib.mapAttrs (n: v: { registries = v; }) cfg.registries; + }; + + users.extraUsers = builtins.listToAttrs ( + ( + builtins.foldl' ( + acc: user: { + values = acc.values ++ [ + { + name = user; + value = { + subUidRanges = [ { startUid = acc.offset; count = 65536; } ]; + subGidRanges = [ { startGid = acc.offset; count = 65536; } ]; + }; + } + ]; + offset = acc.offset + 65536; + } + ) + { values = []; offset = 100000; } cfg.users + ).values + ); + + environment.etc."containers/policy.json".source = + if cfg.policy != {} then pkgs.writeText "policy.json" (builtins.toJSON cfg.policy) + else copyFile "${pkgs.skopeo.src}/default-policy.json"; + }; + +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 30229a3a5b2f..396d1401245f 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -248,6 +248,7 @@ in php = handleTest ./php {}; plasma5 = handleTest ./plasma5.nix {}; plotinus = handleTest ./plotinus.nix {}; + podman = handleTest ./podman.nix {}; postgis = handleTest ./postgis.nix {}; postgresql = handleTest ./postgresql.nix {}; postgresql-wal-receiver = handleTest ./postgresql-wal-receiver.nix {}; diff --git a/nixos/tests/podman.nix b/nixos/tests/podman.nix new file mode 100644 index 000000000000..601a6791c2f7 --- /dev/null +++ b/nixos/tests/podman.nix @@ -0,0 +1,30 @@ +# This test runs podman and checks if simple container starts + +import ./make-test-python.nix ( + { pkgs, ... }: { + name = "podman"; + meta = with pkgs.stdenv.lib.maintainers; { + maintainers = [ adisbladis ]; + }; + + nodes = { + podman = + { pkgs, ... }: + { + virtualisation.podman.enable = true; + }; + }; + + testScript = '' + start_all() + + podman.wait_for_unit("sockets.target") + podman.succeed("tar cv --files-from /dev/null | podman import - scratchimg") + podman.succeed( + "podman run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10" + ) + podman.succeed("podman ps | grep sleeping") + podman.succeed("podman stop sleeping") + ''; + } +) From f0a92ef1d98a7f26e4918351fa865a17883de41b Mon Sep 17 00:00:00 2001 From: adisbladis Date: Mon, 20 Apr 2020 12:35:36 +0100 Subject: [PATCH 2/4] nixos/podman: Add maintainer team & add myself to podman team --- maintainers/team-list.nix | 3 ++- nixos/modules/virtualisation/podman.nix | 6 ++++-- nixos/tests/podman.nix | 6 +++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/maintainers/team-list.nix b/maintainers/team-list.nix index 7efff7f45eca..caee548d719c 100644 --- a/maintainers/team-list.nix +++ b/maintainers/team-list.nix @@ -33,10 +33,11 @@ with lib.maintainers; { podman = { members = [ + adisbladis saschagrunert vdemeester zowoq ]; - scope = "Maintain podman related packages."; + scope = "Maintain Podman related packages and modules."; }; } diff --git a/nixos/modules/virtualisation/podman.nix b/nixos/modules/virtualisation/podman.nix index c1777eb95d94..aa4846837c43 100644 --- a/nixos/modules/virtualisation/podman.nix +++ b/nixos/modules/virtualisation/podman.nix @@ -37,6 +37,9 @@ let ''; in { + meta = { + maintainers = lib.teams.podman.members; + }; options.virtualisation.podman = { @@ -143,7 +146,6 @@ in pkgs.runc # Default container runtime pkgs.crun # Default container runtime (cgroups v2) pkgs.conmon # Container runtime monitor - pkgs.skopeo # Interact with container registry pkgs.slirp4netns # User-mode networking for unprivileged namespaces pkgs.fuse-overlayfs # CoW for images, much faster than default vfs pkgs.utillinux # nsenter @@ -180,7 +182,7 @@ in offset = acc.offset + 65536; } ) - { values = []; offset = 100000; } cfg.users + { values = []; offset = 100000; } (lib.unique cfg.users) ).values ); diff --git a/nixos/tests/podman.nix b/nixos/tests/podman.nix index 601a6791c2f7..ccfe8334a160 100644 --- a/nixos/tests/podman.nix +++ b/nixos/tests/podman.nix @@ -1,10 +1,10 @@ # This test runs podman and checks if simple container starts import ./make-test-python.nix ( - { pkgs, ... }: { + { pkgs, lib, ... }: { name = "podman"; - meta = with pkgs.stdenv.lib.maintainers; { - maintainers = [ adisbladis ]; + meta = { + maintainers = lib.teams.podman.members; }; nodes = { From 650df709fb9312ec2128ba6a0600d6fb55af0084 Mon Sep 17 00:00:00 2001 From: adisbladis Date: Tue, 21 Apr 2020 10:36:01 +0100 Subject: [PATCH 3/4] nixos.virtualisation: Move containers.nix to nixos-containers.nix In anticipation of the new containers module. --- nixos/modules/module-list.nix | 2 +- .../virtualisation/{containers.nix => nixos-containers.nix} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename nixos/modules/virtualisation/{containers.nix => nixos-containers.nix} (100%) diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 38452fddf315..58f4b05c5465 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -983,7 +983,7 @@ ./testing/service-runner.nix ./virtualisation/anbox.nix ./virtualisation/container-config.nix - ./virtualisation/containers.nix + ./virtualisation/nixos-containers.nix ./virtualisation/cri-o.nix ./virtualisation/docker.nix ./virtualisation/docker-containers.nix diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/nixos-containers.nix similarity index 100% rename from nixos/modules/virtualisation/containers.nix rename to nixos/modules/virtualisation/nixos-containers.nix From 43f383c46472f3284d8ebe9b61f779270ffd1f78 Mon Sep 17 00:00:00 2001 From: adisbladis Date: Tue, 21 Apr 2020 10:22:20 +0100 Subject: [PATCH 4/4] nixos.virtualisation.containers: Init common /etc/containers configuration module What's happening now is that both cri-o and podman are creating /etc/containers/policy.json. By splitting out the creation of configuration files we can make the podman module leaner & compose better with other container software. --- nixos/modules/module-list.nix | 1 + nixos/modules/virtualisation/containers.nix | 150 ++++++++++++++++++++ nixos/modules/virtualisation/cri-o.nix | 7 +- nixos/modules/virtualisation/podman.nix | 118 +-------------- 4 files changed, 157 insertions(+), 119 deletions(-) create mode 100644 nixos/modules/virtualisation/containers.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 58f4b05c5465..7244a7e0a894 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -983,6 +983,7 @@ ./testing/service-runner.nix ./virtualisation/anbox.nix ./virtualisation/container-config.nix + ./virtualisation/containers.nix ./virtualisation/nixos-containers.nix ./virtualisation/cri-o.nix ./virtualisation/docker.nix diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix new file mode 100644 index 000000000000..e6127e284869 --- /dev/null +++ b/nixos/modules/virtualisation/containers.nix @@ -0,0 +1,150 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.virtualisation.containers; + + inherit (lib) mkOption types; + + # Once https://github.com/NixOS/nixpkgs/pull/75584 is merged we can use the TOML generator + toTOML = name: value: pkgs.runCommandNoCC name { + nativeBuildInputs = [ pkgs.remarshal ]; + value = builtins.toJSON value; + passAsFile = [ "value" ]; + } '' + json2toml "$valuePath" "$out" + ''; + + # Copy configuration files to avoid having the entire sources in the system closure + copyFile = filePath: pkgs.runCommandNoCC (builtins.unsafeDiscardStringContext (builtins.baseNameOf filePath)) {} '' + cp ${filePath} $out + ''; +in +{ + meta = { + maintainers = [] ++ lib.teams.podman.members; + }; + + options.virtualisation.containers = { + + enable = + mkOption { + type = types.bool; + default = false; + description = '' + This option enables the common libpod container configuration module. + ''; + }; + + registries = { + search = mkOption { + type = types.listOf types.str; + default = [ "docker.io" "quay.io" ]; + description = '' + List of repositories to search. + ''; + }; + + insecure = mkOption { + default = []; + type = types.listOf types.str; + description = '' + List of insecure repositories. + ''; + }; + + block = mkOption { + default = []; + type = types.listOf types.str; + description = '' + List of blocked repositories. + ''; + }; + }; + + policy = mkOption { + default = {}; + type = types.attrs; + example = lib.literalExample '' + { + default = [ { type = "insecureAcceptAnything"; } ]; + transports = { + docker-daemon = { + "" = [ { type = "insecureAcceptAnything"; } ]; + }; + }; + } + ''; + description = '' + Signature verification policy file. + If this option is empty the default policy file from + skopeo will be used. + ''; + }; + + users = mkOption { + default = []; + type = types.listOf types.str; + description = '' + List of users to set up subuid/subgid mappings for. + This is a requirement for running rootless containers. + ''; + }; + + libpod = mkOption { + default = {}; + description = "Libpod configuration"; + type = types.submodule { + options = { + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra configuration that should be put in the libpod.conf + configuration file + ''; + + }; + }; + }; + }; + + }; + + config = lib.mkIf cfg.enable { + + environment.etc."containers/libpod.conf".text = '' + cni_plugin_dir = ["${pkgs.cni-plugins}/bin/"] + cni_config_dir = "/etc/cni/net.d/" + + '' + cfg.libpod.extraConfig; + + environment.etc."containers/registries.conf".source = toTOML "registries.conf" { + registries = lib.mapAttrs (n: v: { registries = v; }) cfg.registries; + }; + + users.extraUsers = builtins.listToAttrs ( + ( + builtins.foldl' ( + acc: user: { + values = acc.values ++ [ + { + name = user; + value = { + subUidRanges = [ { startUid = acc.offset; count = 65536; } ]; + subGidRanges = [ { startGid = acc.offset; count = 65536; } ]; + }; + } + ]; + offset = acc.offset + 65536; + } + ) + { values = []; offset = 100000; } (lib.unique cfg.users) + ).values + ); + + environment.etc."containers/policy.json".source = + if cfg.policy != {} then pkgs.writeText "policy.json" (builtins.toJSON cfg.policy) + else copyFile "${pkgs.skopeo.src}/default-policy.json"; + }; + +} diff --git a/nixos/modules/virtualisation/cri-o.nix b/nixos/modules/virtualisation/cri-o.nix index 14a435f6c8bb..7882b7fc19de 100644 --- a/nixos/modules/virtualisation/cri-o.nix +++ b/nixos/modules/virtualisation/cri-o.nix @@ -62,9 +62,7 @@ in log_level = "${cfg.logLevel}" manage_network_ns_lifecycle = true ''; - environment.etc."containers/policy.json".text = '' - {"default": [{"type": "insecureAcceptAnything"}]} - ''; + environment.etc."cni/net.d/20-cri-o-bridge.conf".text = '' { "cniVersion": "0.3.1", @@ -83,6 +81,9 @@ in } ''; + # Enable common container configuration, this will create policy.json + virtualisation.containers.enable = true; + systemd.services.crio = { description = "Container Runtime Interface for OCI (CRI-O)"; documentation = [ "https://github.com/cri-o/cri-o" ]; diff --git a/nixos/modules/virtualisation/podman.nix b/nixos/modules/virtualisation/podman.nix index aa4846837c43..2ec45fa18a46 100644 --- a/nixos/modules/virtualisation/podman.nix +++ b/nixos/modules/virtualisation/podman.nix @@ -4,7 +4,6 @@ let inherit (lib) mkOption types; - # Provides a fake "docker" binary mapping to podman dockerCompat = pkgs.runCommandNoCC "${pkgs.podman.pname}-docker-compat-${pkgs.podman.version}" { outputs = [ "out" "bin" "man" ]; @@ -22,19 +21,11 @@ let done ''; - # Once https://github.com/NixOS/nixpkgs/pull/75584 is merged we can use the TOML generator - toTOML = name: value: pkgs.runCommandNoCC name { - nativeBuildInputs = [ pkgs.remarshal ]; - value = builtins.toJSON value; - passAsFile = [ "value" ]; - } '' - json2toml "$valuePath" "$out" - ''; - # Copy configuration files to avoid having the entire sources in the system closure copyFile = filePath: pkgs.runCommandNoCC (builtins.unsafeDiscardStringContext (builtins.baseNameOf filePath)) {} '' cp ${filePath} $out ''; + in { meta = { @@ -63,80 +54,6 @@ in ''; }; - registries = { - search = mkOption { - type = types.listOf types.str; - default = [ "docker.io" "quay.io" ]; - description = '' - List of repositories to search. - ''; - }; - - insecure = mkOption { - default = []; - type = types.listOf types.str; - description = '' - List of insecure repositories. - ''; - }; - - block = mkOption { - default = []; - type = types.listOf types.str; - description = '' - List of blocked repositories. - ''; - }; - }; - - policy = mkOption { - default = {}; - type = types.attrs; - example = lib.literalExample '' - { - default = [ { type = "insecureAcceptAnything"; } ]; - transports = { - docker-daemon = { - "" = [ { type = "insecureAcceptAnything"; } ]; - }; - }; - } - ''; - description = '' - Signature verification policy file. - If this option is empty the default policy file from - skopeo will be used. - ''; - }; - - users = mkOption { - default = []; - type = types.listOf types.str; - description = '' - List of users to set up subuid/subgid mappings for. - This is a requirement for running containers in rootless mode. - ''; - }; - - libpod = mkOption { - default = {}; - description = "Libpod configuration"; - type = types.submodule { - options = { - - extraConfig = mkOption { - type = types.lines; - default = ""; - description = '' - Extra configuration that should be put in the libpod.conf - configuration file - ''; - - }; - }; - }; - }; - }; config = lib.mkIf cfg.enable { @@ -154,41 +71,10 @@ in ] ++ lib.optional cfg.dockerCompat dockerCompat; - environment.etc."containers/libpod.conf".text = '' - cni_plugin_dir = ["${pkgs.cni-plugins}/bin/"] - cni_config_dir = "/etc/cni/net.d/" - ${cfg.libpod.extraConfig} - ''; - environment.etc."cni/net.d/87-podman-bridge.conflist".source = copyFile "${pkgs.podman.src}/cni/87-podman-bridge.conflist"; - environment.etc."containers/registries.conf".source = toTOML "registries.conf" { - registries = lib.mapAttrs (n: v: { registries = v; }) cfg.registries; - }; + virtualisation.containers.enable = true; - users.extraUsers = builtins.listToAttrs ( - ( - builtins.foldl' ( - acc: user: { - values = acc.values ++ [ - { - name = user; - value = { - subUidRanges = [ { startUid = acc.offset; count = 65536; } ]; - subGidRanges = [ { startGid = acc.offset; count = 65536; } ]; - }; - } - ]; - offset = acc.offset + 65536; - } - ) - { values = []; offset = 100000; } (lib.unique cfg.users) - ).values - ); - - environment.etc."containers/policy.json".source = - if cfg.policy != {} then pkgs.writeText "policy.json" (builtins.toJSON cfg.policy) - else copyFile "${pkgs.skopeo.src}/default-policy.json"; }; }