lol
1{ lib
2, bash
3, bash-completion
4, bridge-utils
5, coreutils
6, curl
7, darwin
8, dbus
9, dnsmasq
10, docutils
11, fetchFromGitLab
12, fetchpatch
13, gettext
14, glib
15, gnutls
16, iproute2
17, iptables
18, libgcrypt
19, libpcap
20, libtasn1
21, libxml2
22, libxslt
23, makeWrapper
24, meson
25, ninja
26, openssh
27, perl
28, perlPackages
29, polkit
30, pkg-config
31, pmutils
32, python3
33, readline
34, rpcsvc-proto
35, stdenv
36, substituteAll
37, xhtml1
38, yajl
39, writeScript
40, nixosTests
41
42 # Linux
43, acl ? null
44, attr ? null
45, audit ? null
46, dmidecode ? null
47, fuse3 ? null
48, kmod ? null
49, libapparmor ? null
50, libcap_ng ? null
51, libnl ? null
52, libpciaccess ? null
53, libtirpc ? null
54, lvm2 ? null
55, numactl ? null
56, numad ? null
57, parted ? null
58, systemd ? null
59, util-linux ? null
60
61 # Darwin
62, gmp
63, libiconv
64, qemu
65, Carbon
66, AppKit
67
68 # Options
69, enableCeph ? false
70, ceph
71, enableGlusterfs ? false
72, glusterfs
73, enableIscsi ? false
74, openiscsi
75, libiscsi
76, enableXen ? false
77, xen
78, enableZfs ? stdenv.isLinux
79, zfs
80}:
81
82let
83 inherit (stdenv) isDarwin isLinux isx86_64;
84 binPath = lib.makeBinPath ([
85 dnsmasq
86 ] ++ lib.optionals isLinux [
87 bridge-utils
88 dmidecode
89 dnsmasq
90 iproute2
91 iptables
92 kmod
93 lvm2
94 numactl
95 numad
96 openssh
97 pmutils
98 systemd
99 ] ++ lib.optionals enableIscsi [
100 libiscsi
101 openiscsi
102 ] ++ lib.optionals enableZfs [
103 zfs
104 ]);
105in
106
107assert enableXen -> isLinux && isx86_64;
108assert enableCeph -> isLinux;
109assert enableGlusterfs -> isLinux;
110assert enableZfs -> isLinux;
111
112# if you update, also bump <nixpkgs/pkgs/development/python-modules/libvirt/default.nix> and SysVirt in <nixpkgs/pkgs/top-level/perl-packages.nix>
113stdenv.mkDerivation rec {
114 pname = "libvirt";
115 # NOTE: You must also bump:
116 # <nixpkgs/pkgs/development/python-modules/libvirt/default.nix>
117 # SysVirt in <nixpkgs/pkgs/top-level/perl-packages.nix>
118 version = "10.0.0";
119
120 src = fetchFromGitLab {
121 owner = pname;
122 repo = pname;
123 rev = "v${version}";
124 hash = "sha256-xFl8AHcbeuydWzhJNnwZ3Bd7TQiTU8hjBxaALXvcLgE=";
125 fetchSubmodules = true;
126 };
127
128 patches = [
129 ./0001-meson-patch-in-an-install-prefix-for-building-on-nix.patch
130 (fetchpatch {
131 name = "CVE-2024-2494.patch";
132 url = "https://gitlab.com/libvirt/libvirt/-/commit/8a3f8d957507c1f8223fdcf25a3ff885b15557f2.patch";
133 hash = "sha256-kxSIZ4bPOhN6PpJepoSF+EDTgdmazRWh3a3KSVfm1GU=";
134 })
135 (fetchpatch {
136 name = "CVE-2024-1441.patch";
137 url = "https://gitlab.com/libvirt/libvirt/-/commit/c664015fe3a7bf59db26686e9ed69af011c6ebb8.patch";
138 hash = "sha256-Qi/gk7+NPz9s9OpWOnF8XW6A75C9BbVxBTE4KVwalo4=";
139 })
140 ] ++ lib.optionals enableZfs [
141 (substituteAll {
142 src = ./0002-substitute-zfs-and-zpool-commands.patch;
143 zfs = "${zfs}/bin/zfs";
144 zpool = "${zfs}/bin/zpool";
145 })
146 ];
147
148 # remove some broken tests
149 postPatch = ''
150 sed -i '/commandtest/d' tests/meson.build
151 sed -i '/virnetsockettest/d' tests/meson.build
152 # delete only the first occurrence of this
153 sed -i '0,/qemuxml2argvtest/{/qemuxml2argvtest/d;}' tests/meson.build
154
155 '' + lib.optionalString isLinux ''
156 for binary in mount umount mkfs; do
157 substituteInPlace meson.build \
158 --replace "find_program('$binary'" "find_program('${lib.getBin util-linux}/bin/$binary'"
159 done
160
161 '' + ''
162 substituteInPlace meson.build \
163 --replace "'dbus-daemon'," "'${lib.getBin dbus}/bin/dbus-daemon',"
164 '' + lib.optionalString isLinux ''
165 sed -i 's,define PARTED "parted",define PARTED "${parted}/bin/parted",' \
166 src/storage/storage_backend_disk.c \
167 src/storage/storage_util.c
168 '' + lib.optionalString isDarwin ''
169 # Darwin doesn’t support -fsemantic-interposition, but the problem doesn’t seem to affect Mach-O.
170 # See https://gitlab.com/libvirt/libvirt/-/merge_requests/235
171 sed -i "s/not supported_cc_flags.contains('-fsemantic-interposition')/false/" meson.build
172 sed -i '/qemufirmwaretest/d' tests/meson.build
173 sed -i '/qemuhotplugtest/d' tests/meson.build
174 sed -i '/qemuvhostusertest/d' tests/meson.build
175 sed -i '/qemuxml2xmltest/d' tests/meson.build
176 '';
177
178 strictDeps = true;
179
180 nativeBuildInputs = [
181 meson
182 docutils
183 libxml2 # for xmllint
184 libxslt # for xsltproc
185 gettext
186 makeWrapper
187 ninja
188 pkg-config
189 perl
190 perlPackages.XMLXPath
191 ]
192 ++ lib.optional (!isDarwin) rpcsvc-proto
193 # NOTE: needed for rpcgen
194 ++ lib.optional isDarwin darwin.developer_cmds;
195
196 buildInputs = [
197 bash
198 bash-completion
199 curl
200 dbus
201 glib
202 gnutls
203 libgcrypt
204 libpcap
205 libtasn1
206 libxml2
207 python3
208 readline
209 xhtml1
210 yajl
211 ] ++ lib.optionals isLinux [
212 acl
213 attr
214 audit
215 fuse3
216 libapparmor
217 libcap_ng
218 libnl
219 libpciaccess
220 libtirpc
221 lvm2
222 numactl
223 numad
224 parted
225 systemd
226 util-linux
227 ] ++ lib.optionals isDarwin [
228 AppKit
229 Carbon
230 gmp
231 libiconv
232 ]
233 ++ lib.optionals enableCeph [ ceph ]
234 ++ lib.optionals enableGlusterfs [ glusterfs ]
235 ++ lib.optionals enableIscsi [ libiscsi openiscsi ]
236 ++ lib.optionals enableXen [ xen ]
237 ++ lib.optionals enableZfs [ zfs ];
238
239 preConfigure =
240 let
241 overrides = {
242 QEMU_BRIDGE_HELPER = "/run/wrappers/bin/qemu-bridge-helper";
243 QEMU_PR_HELPER = "/run/libvirt/nix-helpers/qemu-pr-helper";
244 };
245
246 patchBuilder = var: value: ''
247 sed -i meson.build -e "s|conf.set_quoted('${var}',.*|conf.set_quoted('${var}','${value}')|"
248 '';
249 in
250 ''
251 PATH="${binPath}:$PATH"
252 # the path to qemu-kvm will be stored in VM's .xml and .save files
253 # do not use "''${qemu_kvm}/bin/qemu-kvm" to avoid bound VMs to particular qemu derivations
254 substituteInPlace src/lxc/lxc_conf.c \
255 --replace 'lxc_path,' '"/run/libvirt/nix-emulators/libvirt_lxc",'
256
257 substituteInPlace build-aux/meson.build \
258 --replace "gsed" "sed" \
259 --replace "gmake" "make" \
260 --replace "ggrep" "grep"
261
262 substituteInPlace src/util/virpolkit.h \
263 --replace '"/usr/bin/pkttyagent"' '"${if isLinux then polkit.bin else "/usr"}/bin/pkttyagent"'
264
265 substituteInPlace src/util/virpci.c \
266 --replace '/lib/modules' '${if isLinux then "/run/booted-system/kernel-modules" else ""}/lib/modules'
267
268 patchShebangs .
269 ''
270 + (lib.concatStringsSep "\n" (lib.mapAttrsToList patchBuilder overrides));
271
272 mesonAutoFeatures = "disabled";
273
274 mesonFlags =
275 let
276 cfg = option: val: "-D${option}=${val}";
277 feat = option: enable: cfg option (if enable then "enabled" else "disabled");
278 driver = name: feat "driver_${name}";
279 storage = name: feat "storage_${name}";
280 in
281 [
282 "--sysconfdir=/var/lib"
283 (cfg "install_prefix" (placeholder "out"))
284 (cfg "localstatedir" "/var")
285 (cfg "runstatedir" (if isDarwin then "/var/run" else "/run"))
286
287 (cfg "init_script" (if isDarwin then "none" else "systemd"))
288 (cfg "qemu_datadir" (lib.optionalString isDarwin "${qemu}/share/qemu"))
289
290 (feat "apparmor" isLinux)
291 (feat "attr" isLinux)
292 (feat "audit" isLinux)
293 (feat "bash_completion" true)
294 (feat "blkid" isLinux)
295 (feat "capng" isLinux)
296 (feat "curl" true)
297 (feat "docs" true)
298 (feat "expensive_tests" true)
299 (feat "firewalld" isLinux)
300 (feat "firewalld_zone" isLinux)
301 (feat "fuse" isLinux)
302 (feat "glusterfs" enableGlusterfs)
303 (feat "host_validate" true)
304 (feat "libiscsi" enableIscsi)
305 (feat "libnl" isLinux)
306 (feat "libpcap" true)
307 (feat "libssh2" true)
308 (feat "login_shell" isLinux)
309 (feat "nss" (isLinux && !stdenv.hostPlatform.isMusl))
310 (feat "numactl" isLinux)
311 (feat "numad" isLinux)
312 (feat "pciaccess" isLinux)
313 (feat "polkit" isLinux)
314 (feat "readline" true)
315 (feat "secdriver_apparmor" isLinux)
316 (feat "tests" true)
317 (feat "udev" isLinux)
318 (feat "yajl" true)
319
320 (driver "ch" isLinux)
321 (driver "esx" true)
322 (driver "interface" isLinux)
323 (driver "libvirtd" true)
324 (driver "libxl" enableXen)
325 (driver "lxc" isLinux)
326 (driver "network" true)
327 (driver "openvz" isLinux)
328 (driver "qemu" true)
329 (driver "remote" true)
330 (driver "secrets" true)
331 (driver "test" true)
332 (driver "vbox" true)
333 (driver "vmware" true)
334
335 (storage "dir" true)
336 (storage "disk" isLinux)
337 (storage "fs" isLinux)
338 (storage "gluster" enableGlusterfs)
339 (storage "iscsi" enableIscsi)
340 (storage "iscsi_direct" enableIscsi)
341 (storage "lvm" isLinux)
342 (storage "mpath" isLinux)
343 (storage "rbd" enableCeph)
344 (storage "scsi" true)
345 (storage "vstorage" isLinux)
346 (storage "zfs" enableZfs)
347 ];
348
349 doCheck = true;
350
351 postInstall = ''
352 substituteInPlace $out/bin/virt-xml-validate \
353 --replace xmllint ${libxml2}/bin/xmllint
354
355 substituteInPlace $out/libexec/libvirt-guests.sh \
356 --replace 'ON_BOOT="start"' 'ON_BOOT=''${ON_BOOT:-start}' \
357 --replace 'ON_SHUTDOWN="suspend"' 'ON_SHUTDOWN=''${ON_SHUTDOWN:-suspend}' \
358 --replace 'PARALLEL_SHUTDOWN=0' 'PARALLEL_SHUTDOWN=''${PARALLEL_SHUTDOWN:-0}' \
359 --replace "$out/bin" '${gettext}/bin' \
360 --replace 'lock/subsys' 'lock' \
361 --replace 'gettext.sh' 'gettext.sh
362 # Added in nixpkgs:
363 gettext() { "${gettext}/bin/gettext" "$@"; }
364 '
365 '' + lib.optionalString isLinux ''
366 for f in $out/lib/systemd/system/*.service ; do
367 substituteInPlace $f --replace /bin/kill ${coreutils}/bin/kill
368 done
369 rm $out/lib/systemd/system/{virtlockd,virtlogd}.*
370 wrapProgram $out/sbin/libvirtd \
371 --prefix PATH : /run/libvirt/nix-emulators:${binPath}
372 '';
373
374 passthru.updateScript = writeScript "update-libvirt" ''
375 #!/usr/bin/env nix-shell
376 #!nix-shell -i bash -p curl jq common-updater-scripts
377
378 set -eu -o pipefail
379
380 libvirtVersion=$(curl https://gitlab.com/api/v4/projects/192693/repository/tags | jq -r '.[].name|select(. | contains("rc") | not)' | head -n1 | sed "s/v//g")
381 sysvirtVersion=$(curl https://gitlab.com/api/v4/projects/192677/repository/tags | jq -r '.[].name|select(. | contains("rc") | not)' | head -n1 | sed "s/v//g")
382 update-source-version ${pname} "$libvirtVersion"
383 update-source-version python3Packages.${pname} "$libvirtVersion"
384 update-source-version perlPackages.SysVirt "$sysvirtVersion" --file="pkgs/top-level/perl-packages.nix"
385 '';
386
387 passthru.tests.libvirtd = nixosTests.libvirtd;
388
389 meta = with lib; {
390 description = "A toolkit to interact with the virtualization capabilities of recent versions of Linux and other OSes";
391 homepage = "https://libvirt.org/";
392 changelog = "https://gitlab.com/libvirt/libvirt/-/raw/v${version}/NEWS.rst";
393 license = licenses.lgpl2Plus;
394 platforms = platforms.unix;
395 maintainers = with maintainers; [ fpletz globin lovesegfault ];
396 };
397}