at 22.05-pre 5.5 kB view raw
1{ config, lib, pkgs, ... }: 2let 3 cfg = config.virtualisation.podman; 4 toml = pkgs.formats.toml { }; 5 json = pkgs.formats.json { }; 6 7 inherit (lib) mkOption types; 8 9 podmanPackage = (pkgs.podman.override { inherit (cfg) extraPackages; }); 10 11 # Provides a fake "docker" binary mapping to podman 12 dockerCompat = pkgs.runCommand "${podmanPackage.pname}-docker-compat-${podmanPackage.version}" { 13 outputs = [ "out" "man" ]; 14 inherit (podmanPackage) meta; 15 } '' 16 mkdir -p $out/bin 17 ln -s ${podmanPackage}/bin/podman $out/bin/docker 18 19 mkdir -p $man/share/man/man1 20 for f in ${podmanPackage.man}/share/man/man1/*; do 21 basename=$(basename $f | sed s/podman/docker/g) 22 ln -s $f $man/share/man/man1/$basename 23 done 24 ''; 25 26 net-conflist = pkgs.runCommand "87-podman-bridge.conflist" { 27 nativeBuildInputs = [ pkgs.jq ]; 28 extraPlugins = builtins.toJSON cfg.defaultNetwork.extraPlugins; 29 jqScript = '' 30 . + { "plugins": (.plugins + $extraPlugins) } 31 ''; 32 } '' 33 jq <${cfg.package}/etc/cni/net.d/87-podman-bridge.conflist \ 34 --argjson extraPlugins "$extraPlugins" \ 35 "$jqScript" \ 36 >$out 37 ''; 38 39in 40{ 41 imports = [ 42 ./podman-dnsname.nix 43 ./podman-network-socket.nix 44 (lib.mkRenamedOptionModule [ "virtualisation" "podman" "libpod" ] [ "virtualisation" "containers" "containersConf" ]) 45 ]; 46 47 meta = { 48 maintainers = lib.teams.podman.members; 49 }; 50 51 options.virtualisation.podman = { 52 53 enable = 54 mkOption { 55 type = types.bool; 56 default = false; 57 description = '' 58 This option enables Podman, a daemonless container engine for 59 developing, managing, and running OCI Containers on your Linux System. 60 61 It is a drop-in replacement for the <command>docker</command> command. 62 ''; 63 }; 64 65 dockerSocket.enable = mkOption { 66 type = types.bool; 67 default = false; 68 description = '' 69 Make the Podman socket available in place of the Docker socket, so 70 Docker tools can find the Podman socket. 71 72 Podman implements the Docker API. 73 74 Users must be in the <code>podman</code> group in order to connect. As 75 with Docker, members of this group can gain root access. 76 ''; 77 }; 78 79 dockerCompat = mkOption { 80 type = types.bool; 81 default = false; 82 description = '' 83 Create an alias mapping <command>docker</command> to <command>podman</command>. 84 ''; 85 }; 86 87 enableNvidia = mkOption { 88 type = types.bool; 89 default = false; 90 description = '' 91 Enable use of NVidia GPUs from within podman containers. 92 ''; 93 }; 94 95 extraPackages = mkOption { 96 type = with types; listOf package; 97 default = [ ]; 98 example = lib.literalExpression '' 99 [ 100 pkgs.gvisor 101 ] 102 ''; 103 description = '' 104 Extra packages to be installed in the Podman wrapper. 105 ''; 106 }; 107 108 package = lib.mkOption { 109 type = types.package; 110 default = podmanPackage; 111 internal = true; 112 description = '' 113 The final Podman package (including extra packages). 114 ''; 115 }; 116 117 defaultNetwork.extraPlugins = lib.mkOption { 118 type = types.listOf json.type; 119 default = []; 120 description = '' 121 Extra CNI plugin configurations to add to podman's default network. 122 ''; 123 }; 124 125 }; 126 127 config = lib.mkIf cfg.enable (lib.mkMerge [ 128 { 129 environment.systemPackages = [ cfg.package ] 130 ++ lib.optional cfg.dockerCompat dockerCompat; 131 132 environment.etc."cni/net.d/87-podman-bridge.conflist".source = net-conflist; 133 134 virtualisation.containers = { 135 enable = true; # Enable common /etc/containers configuration 136 containersConf.settings = lib.optionalAttrs cfg.enableNvidia { 137 engine = { 138 conmon_env_vars = [ "PATH=${lib.makeBinPath [ pkgs.nvidia-podman ]}" ]; 139 runtimes.nvidia = [ "${pkgs.nvidia-podman}/bin/nvidia-container-runtime" ]; 140 }; 141 }; 142 }; 143 144 systemd.packages = [ cfg.package ]; 145 146 systemd.services.podman.serviceConfig = { 147 ExecStart = [ "" "${cfg.package}/bin/podman $LOGGING system service" ]; 148 }; 149 150 systemd.sockets.podman.wantedBy = [ "sockets.target" ]; 151 systemd.sockets.podman.socketConfig.SocketGroup = "podman"; 152 153 systemd.tmpfiles.packages = [ 154 # The /run/podman rule interferes with our podman group, so we remove 155 # it and let the systemd socket logic take care of it. 156 (pkgs.runCommand "podman-tmpfiles-nixos" { package = cfg.package; } '' 157 mkdir -p $out/lib/tmpfiles.d/ 158 grep -v 'D! /run/podman 0700 root root' \ 159 <$package/lib/tmpfiles.d/podman.conf \ 160 >$out/lib/tmpfiles.d/podman.conf 161 '') ]; 162 163 systemd.tmpfiles.rules = 164 lib.optionals cfg.dockerSocket.enable [ 165 "L! /run/docker.sock - - - - /run/podman/podman.sock" 166 ]; 167 168 users.groups.podman = {}; 169 170 assertions = [ 171 { 172 assertion = cfg.dockerCompat -> !config.virtualisation.docker.enable; 173 message = "Option dockerCompat conflicts with docker"; 174 } 175 { 176 assertion = cfg.dockerSocket.enable -> !config.virtualisation.docker.enable; 177 message = '' 178 The options virtualisation.podman.dockerSocket.enable and virtualisation.docker.enable conflict, because only one can serve the socket. 179 ''; 180 } 181 ]; 182 } 183 ]); 184}