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