From patchwork Wed Mar 19 12:45:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxim Cournoyer X-Patchwork-Id: 40430 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 2233327BBEA; Wed, 19 Mar 2025 12:47:43 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-6.6 required=5.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI, RCVD_IN_DNSWL_BLOCKED,RCVD_IN_VALIDITY_CERTIFIED,RCVD_IN_VALIDITY_RPBL, RCVD_IN_VALIDITY_SAFE,SPF_HELO_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 550EC27BBE2 for ; Wed, 19 Mar 2025 12:47:41 +0000 (GMT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tuspG-0007ve-2y; Wed, 19 Mar 2025 08:47:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tusp6-0007uS-B4 for guix-patches@gnu.org; Wed, 19 Mar 2025 08:47:05 -0400 Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tusp6-0003kr-0S; Wed, 19 Mar 2025 08:47:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=MIME-Version:References:In-Reply-To:Date:From:To:Subject; bh=4e8Ktcnql/Tq/L48R9uVthsZAO/H47c+VcIutrwnx5s=; b=Ew3FX/gnp6fj8viLg+jgZjHDxT1o55DId4THLaDFMNxjxABNIes/kpYPQeJeqC0UgDwlqWlYpad0Abct0QXah8BEwvMw3wql3J3174evBB0o/y5e20viwZPP9A54fFSnOLuFb4ttfghH/ee9v3WKQo5S5HLoF8ga1hM4IJN4EHLUZ1uuFy7cMelYf9SIJwaBI/QHW4TX92Ds014FoXW44NPh2fLXGPO0MqhlSHwBBCsx2FfWVEVojCcr0EjvPKpFwGco/7IItEXINjMjAo4L8Ymbpa9aAIs4U9z7ISUEeQKOP3vLT1R3igCrU5yy5XWLEfWIGIVAlXbFG8nRandgdA==; Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tusp4-0003ML-S0; Wed, 19 Mar 2025 08:47:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#77110] [PATCH 2/2] services: libvirt: Add UEFI firmware support. Resent-From: Maxim Cournoyer Original-Sender: "Debbugs-submit" Resent-CC: ludo@gnu.org, maxim.cournoyer@gmail.com, guix-patches@gnu.org Resent-Date: Wed, 19 Mar 2025 12:47:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 77110 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 77110@debbugs.gnu.org Cc: Maxim Cournoyer , Ludovic =?utf-8?q?Court?= =?utf-8?q?=C3=A8s?= , Maxim Cournoyer X-Debbugs-Original-Xcc: Ludovic =?utf-8?q?Court=C3=A8s?= , Maxim Cournoyer Received: via spool by 77110-submit@debbugs.gnu.org id=B77110.174238837112835 (code B ref 77110); Wed, 19 Mar 2025 12:47:02 +0000 Received: (at 77110) by debbugs.gnu.org; 19 Mar 2025 12:46:11 +0000 Received: from localhost ([127.0.0.1]:49348 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tusoD-0003Kv-6b for submit@debbugs.gnu.org; Wed, 19 Mar 2025 08:46:11 -0400 Received: from mail-pl1-x62d.google.com ([2607:f8b0:4864:20::62d]:61950) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1tuso7-0003K8-O1 for 77110@debbugs.gnu.org; Wed, 19 Mar 2025 08:46:05 -0400 Received: by mail-pl1-x62d.google.com with SMTP id d9443c01a7336-2260c915749so48245965ad.3 for <77110@debbugs.gnu.org>; Wed, 19 Mar 2025 05:46:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1742388357; x=1742993157; darn=debbugs.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4e8Ktcnql/Tq/L48R9uVthsZAO/H47c+VcIutrwnx5s=; b=ZI+mVVHX8U193xPp8Wj7QajrIpRKXYIHFxbggnUV8uzCV7ro+nYMgR7IA2zhOlCstf +ZreLqJ63A4SWPESHdYQDloG8X42/rawVQwKiwG++4vjnb/++AGGwSz1FvB4QgJg2KuT 6jMGn0GtU7K5P34HYdCA5pANacmGtWdpa7qs8mykUeeFYillfqrco8xlGuHifxB/vHLn 3R4AxcKnOoBMdCJBzL72T3ReCdKQ20+D/4AZe7ngf69fjf4cdEKL68jomj6RdRHHUb6R OuqI4V2qXqzsnotoYxF1RMYvhCXD1WRxnbfh9m+o2xfTf0joJ7rf0dJMwv5tZH8NoKF8 VlZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742388357; x=1742993157; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4e8Ktcnql/Tq/L48R9uVthsZAO/H47c+VcIutrwnx5s=; b=Xzc/osHUAW+7sQl1vFyhuhhF2FPKsjclR1eanRqmMLLxTzRltNJDPbxbfUpc9ofxQM 4vQkCPt/ZzAc+QdvAtthWpROBvWz8DEF+HOoEG0sN6G2pi4nBD6Rm3cvXtMouOhZGEIb ebHVb3xse4HuuYEA8KlbbV2HSQdjMqLd3DQyb/KZUZc3TfXPIQV+fpRGbSRz9Za4BBkg 4XTSmpqlT8QrDbTuz4odQRwZ5JECx84eLwSzFqhcaTZ1fRKvROJZX/CyxpoHQWXivZdR j+/9W/v9DKwxuBeThDnoHmBcALIfTW1Pqg6FAROFO/q2oy83PDMHZsQ2N45dfA7rsJLK KcMw== X-Gm-Message-State: AOJu0Yxaybssxj4rEfPtyWfb3OMpMtlR6JrbADhuWhzRXRfNvRfMcSsW B4xGy1IYYgMpVA3mG6dkkNVswuYcgDuxNlt1+tYD4Oy0SPoM0DTS/x5ZdyJ2 X-Gm-Gg: ASbGncvPviwiHniXXl8NCzP/ybz10O6ieCNnILR3phKiL25TkZpF3DfYBnjA/T3mgqA prkB9bpNJ0WFqv+biqMSR1mwked8QRmN9RXOhS6wIpKTLDBQ65XRf8LCW7xunFjO8A1l2itp42G 5GFb5p1YMlU8gbHSGSbLDSLUcnUpEOiKmuZ4ExV+0APy+S1eHaDWu7TMdSwjvNmzA7GFRupxPYL kh2yFgHf62znqyS8jH6WCklOhj5gxCQsU8pVaKrZAdqaVdDrHw9xn7THMo0/fu47hW+cZlzUK8W vLLk/OguXNhrr6e3SY+icGKdtK36daI5AbTZmCezdriRGGYNB1jIdx62d9dWLXrb X-Google-Smtp-Source: AGHT+IEbeP23ifEEicxpE0CO7eEGohPHixWHH8uspW+JxjZgsnE8p+6DViEpauFVajaJpulQDBiapg== X-Received: by 2002:a05:6a00:2350:b0:736:53c5:33ba with SMTP id d2e1a72fcca58-7376d6f2168mr4381069b3a.16.1742388356233; Wed, 19 Mar 2025 05:45:56 -0700 (PDT) Received: from localhost.localdomain ([2405:6586:be0:0:83c8:d31d:2cec:f542]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73711578a5csm11472600b3a.74.2025.03.19.05.45.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Mar 2025 05:45:55 -0700 (PDT) From: Maxim Cournoyer Date: Wed, 19 Mar 2025 21:45:13 +0900 Message-ID: <75bedfb1eb523c75eb913ff7967528f93a8f8e70.1742388313.git.maxim.cournoyer@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches This makes libvirt able to boot images that require a UEFI bootloader, with the available firmwares exposed to libvirt made configurable via a new configuration field. For more background on the problem this fixes, see the same issue that was reported in NixOS (see: https://github.com/NixOS/nixpkgs/issues/115996). * gnu/services/virtualization.scm: (list-of-file-likes?): New predicate. (libvirt-configuration): [firmwares]: New field. (/etc/qemu/firmware): New procedure. (libvirt-service-type): Extend the etc-service-type with it. (generate-libvirt-documentation): Delete obsolete procedure. * doc/guix.texi: Re-generate doc. * gnu/tests/virtualization.scm (run-libvirt-test): Augment memory from 256 to 512 MiB. Test it. Change-Id: I40694964405f13681520bf1e28b7365b0200d8f7 --- doc/guix.texi | 506 ++++++++------------------------ gnu/services/virtualization.scm | 76 +++-- gnu/tests/virtualization.scm | 33 ++- 3 files changed, 211 insertions(+), 404 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 0488559332..e36fbad19f 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -37895,406 +37895,220 @@ Virtualization Services @end lisp @end defvar -@c Auto-generated with (generate-libvirt-documentation) +@c Auto-generated with (configuration->documentation 'libvirt-configuration) +@c %start of fragment +@deftp {Data Type} libvirt-configuration Available @code{libvirt-configuration} fields are: -@deftypevr {@code{libvirt-configuration} parameter} package libvirt +@table @asis +@item @code{libvirt} (default: @code{libvirt}) (type: file-like) Libvirt package. -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} boolean listen-tls? -Flag listening for secure TLS connections on the public TCP/IP port. -You must set @code{listen} for this to have any effect. - -It is necessary to setup a CA and issue server certificates before using -this capability. - -Defaults to @samp{#t}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} boolean listen-tcp? -Listen for unencrypted TCP connections on the public TCP/IP port. You must -set @code{listen} for this to have any effect. - -Using the TCP socket requires SASL authentication by default. Only SASL -mechanisms which support data encryption are allowed. This is -DIGEST_MD5 and GSSAPI (Kerberos5). - -Defaults to @samp{#f}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string tls-port -Port for accepting secure TLS connections. This can be a port number, -or service name. +@item @code{qemu} (default: @code{qemu}) (type: file-like) +Qemu package. -Defaults to @samp{"16514"}. +@item @code{firmwares} (default: @code{(ovmf-x86-64)}) (type: list-of-file-likes) +List of UEFI/BIOS firmware packages to make available. Each firmware +package should contain a @file{share/qemu/firmware/@var{NAME}.json} QEMU +firmware metadata file. -@end deftypevr +@item @code{listen-tls?} (default: @code{#t}) (type: boolean) +Flag listening for secure TLS connections on the public TCP/IP port. +must set @code{listen} for this to have any effect. It is necessary to +setup a CA and issue server certificates before using this capability. -@deftypevr {@code{libvirt-configuration} parameter} string tcp-port -Port for accepting insecure TCP connections. This can be a port number, -or service name. +@item @code{listen-tcp?} (default: @code{#f}) (type: boolean) +Listen for unencrypted TCP connections on the public TCP/IP port. must +set @code{listen} for this to have any effect. Using the TCP socket +requires SASL authentication by default. Only SASL mechanisms which +support data encryption are allowed. This is DIGEST_MD5 and GSSAPI +(Kerberos5) -Defaults to @samp{"16509"}. +@item @code{tls-port} (default: @code{"16514"}) (type: string) +Port for accepting secure TLS connections This can be a port number, or +service name -@end deftypevr +@item @code{tcp-port} (default: @code{"16509"}) (type: string) +Port for accepting insecure TCP connections This can be a port number, +or service name -@deftypevr {@code{libvirt-configuration} parameter} string listen-addr +@item @code{listen-addr} (default: @code{"0.0.0.0"}) (type: string) IP address or hostname used for client connections. -Defaults to @samp{"0.0.0.0"}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} boolean mdns-adv? -Flag toggling mDNS advertisement of the libvirt service. - -Alternatively can disable for all services on a host by stopping the -Avahi daemon. +@item @code{mdns-adv?} (default: @code{#f}) (type: boolean) +Flag toggling mDNS advertisement of the libvirt service. Alternatively +can disable for all services on a host by stopping the Avahi daemon. -Defaults to @samp{#f}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string mdns-name +@item @code{mdns-name} (default: @code{"Virtualization Host terra"}) (type: string) Default mDNS advertisement name. This must be unique on the immediate broadcast network. -Defaults to @samp{"Virtualization Host "}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string unix-sock-group +@item @code{unix-sock-group} (default: @code{"libvirt"}) (type: string) UNIX domain socket group ownership. This can be used to allow a 'trusted' set of users access to management capabilities without becoming root. -Defaults to @samp{"libvirt"}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string unix-sock-ro-perms +@item @code{unix-sock-ro-perms} (default: @code{"0777"}) (type: string) UNIX socket permissions for the R/O socket. This is used for monitoring VM status only. -Defaults to @samp{"0777"}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string unix-sock-rw-perms +@item @code{unix-sock-rw-perms} (default: @code{"0770"}) (type: string) UNIX socket permissions for the R/W socket. Default allows only root. If PolicyKit is enabled on the socket, the default will change to allow everyone (eg, 0777) -Defaults to @samp{"0770"}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string unix-sock-admin-perms +@item @code{unix-sock-admin-perms} (default: @code{"0777"}) (type: string) UNIX socket permissions for the admin socket. Default allows only owner (root), do not change it unless you are sure to whom you are exposing the access to. -Defaults to @samp{"0777"}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string unix-sock-dir +@item @code{unix-sock-dir} (default: @code{"/var/run/libvirt"}) (type: string) The directory in which sockets will be found/created. -Defaults to @samp{"/var/run/libvirt"}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string auth-unix-ro +@item @code{auth-unix-ro} (default: @code{"polkit"}) (type: string) Authentication scheme for UNIX read-only sockets. By default socket permissions allow anyone to connect -Defaults to @samp{"polkit"}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string auth-unix-rw +@item @code{auth-unix-rw} (default: @code{"polkit"}) (type: string) Authentication scheme for UNIX read-write sockets. By default socket permissions only allow root. If PolicyKit support was compiled into libvirt, the default will be to use 'polkit' auth. -Defaults to @samp{"polkit"}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string auth-tcp +@item @code{auth-tcp} (default: @code{"sasl"}) (type: string) Authentication scheme for TCP sockets. If you don't enable SASL, then all TCP traffic is cleartext. Don't do this outside of a dev/test scenario. -Defaults to @samp{"sasl"}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string auth-tls +@item @code{auth-tls} (default: @code{"none"}) (type: string) Authentication scheme for TLS sockets. TLS sockets already have encryption provided by the TLS layer, and limited authentication is done -by certificates. - -It is possible to make use of any SASL authentication mechanism as well, -by using 'sasl' for this option +by certificates. It is possible to make use of any SASL authentication +mechanism as well, by using 'sasl' for this option -Defaults to @samp{"none"}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} optional-list access-drivers -API access control scheme. - -By default an authenticated user is allowed access to all APIs. Access -drivers can place restrictions on this. - -Defaults to @samp{'()}. - -@end deftypevr +@item @code{access-drivers} (default: @code{()}) (type: optional-list) +API access control scheme. By default an authenticated user is allowed +access to all APIs. Access drivers can place restrictions on this. -@deftypevr {@code{libvirt-configuration} parameter} string key-file +@item @code{key-file} (default: @code{""}) (type: string) Server key file path. If set to an empty string, then no private key is loaded. -Defaults to @samp{""}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string cert-file +@item @code{cert-file} (default: @code{""}) (type: string) Server key file path. If set to an empty string, then no certificate is loaded. -Defaults to @samp{""}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string ca-file +@item @code{ca-file} (default: @code{""}) (type: string) Server key file path. If set to an empty string, then no CA certificate is loaded. -Defaults to @samp{""}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string crl-file +@item @code{crl-file} (default: @code{""}) (type: string) Certificate revocation list path. If set to an empty string, then no CRL is loaded. -Defaults to @samp{""}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} boolean tls-no-sanity-cert -Disable verification of our own server certificates. +@item @code{tls-no-sanity-cert} (default: @code{#f}) (type: boolean) +Disable verification of our own server certificates. When libvirtd +starts it performs some sanity checks against its own certificates. -When libvirtd starts it performs some sanity checks against its own -certificates. +@item @code{tls-no-verify-cert} (default: @code{#f}) (type: boolean) +Disable verification of client certificates. Client certificate +verification is the primary authentication mechanism. Any client which +does not present a certificate signed by the CA will be rejected. -Defaults to @samp{#f}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} boolean tls-no-verify-cert -Disable verification of client certificates. - -Client certificate verification is the primary authentication mechanism. -Any client which does not present a certificate signed by the CA will be -rejected. - -Defaults to @samp{#f}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} optional-list tls-allowed-dn-list +@item @code{tls-allowed-dn-list} (default: @code{()}) (type: optional-list) Whitelist of allowed x509 Distinguished Name. -Defaults to @samp{'()}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} optional-list sasl-allowed-usernames +@item @code{sasl-allowed-usernames} (default: @code{()}) (type: optional-list) Whitelist of allowed SASL usernames. The format for username depends on the SASL authentication mechanism. -Defaults to @samp{'()}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string tls-priority +@item @code{tls-priority} (default: @code{"NORMAL"}) (type: string) Override the compile time default TLS priority string. The default is -usually @samp{"NORMAL"} unless overridden at build time. Only set this is it +usually "NORMAL" unless overridden at build time. Only set this is it is desired for libvirt to deviate from the global default settings. -Defaults to @samp{"NORMAL"}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer max-clients +@item @code{max-clients} (default: @code{5000}) (type: integer) Maximum number of concurrent client connections to allow over all sockets combined. -Defaults to @samp{5000}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer max-queued-clients +@item @code{max-queued-clients} (default: @code{1000}) (type: integer) Maximum length of queue of connections waiting to be accepted by the daemon. Note, that some protocols supporting retransmission may obey this so that a later reattempt at connection succeeds. -Defaults to @samp{1000}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer max-anonymous-clients +@item @code{max-anonymous-clients} (default: @code{20}) (type: integer) Maximum length of queue of accepted but not yet authenticated clients. Set this to zero to turn this feature off -Defaults to @samp{20}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer min-workers +@item @code{min-workers} (default: @code{5}) (type: integer) Number of workers to start up initially. -Defaults to @samp{5}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer max-workers -Maximum number of worker threads. - -If the number of active clients exceeds @code{min-workers}, then more -threads are spawned, up to max_workers limit. Typically you'd want -max_workers to equal maximum number of clients allowed. - -Defaults to @samp{20}. - -@end deftypevr +@item @code{max-workers} (default: @code{20}) (type: integer) +Maximum number of worker threads. If the number of active clients +exceeds @code{min-workers}, then more threads are spawned, up to +max_workers limit. Typically you'd want max_workers to equal maximum +number of clients allowed. -@deftypevr {@code{libvirt-configuration} parameter} integer prio-workers +@item @code{prio-workers} (default: @code{5}) (type: integer) Number of priority workers. If all workers from above pool are stuck, some calls marked as high priority (notably domainDestroy) can be executed in this pool. -Defaults to @samp{5}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer max-requests +@item @code{max-requests} (default: @code{20}) (type: integer) Total global limit on concurrent RPC calls. -Defaults to @samp{20}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer max-client-requests +@item @code{max-client-requests} (default: @code{5}) (type: integer) Limit on concurrent requests from a single client connection. To avoid one client monopolizing the server this should be a small fraction of the global max_requests and max_workers parameter. -Defaults to @samp{5}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer admin-min-workers +@item @code{admin-min-workers} (default: @code{1}) (type: integer) Same as @code{min-workers} but for the admin interface. -Defaults to @samp{1}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer admin-max-workers +@item @code{admin-max-workers} (default: @code{5}) (type: integer) Same as @code{max-workers} but for the admin interface. -Defaults to @samp{5}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer admin-max-clients +@item @code{admin-max-clients} (default: @code{5}) (type: integer) Same as @code{max-clients} but for the admin interface. -Defaults to @samp{5}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer admin-max-queued-clients +@item @code{admin-max-queued-clients} (default: @code{5}) (type: integer) Same as @code{max-queued-clients} but for the admin interface. -Defaults to @samp{5}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer admin-max-client-requests +@item @code{admin-max-client-requests} (default: @code{5}) (type: integer) Same as @code{max-client-requests} but for the admin interface. -Defaults to @samp{5}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer log-level +@item @code{log-level} (default: @code{3}) (type: integer) Logging level. 4 errors, 3 warnings, 2 information, 1 debug. -Defaults to @samp{3}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string log-filters -Logging filters. - -A filter allows to select a different logging level for a given category -of logs. The format for a filter is one of: +@item @code{log-filters} (default: @code{"3:remote 4:event"}) (type: string) +Logging filters. A filter allows selecting a different logging level +for a given category of logs The format for a filter is one of: @itemize @bullet -@item -x:name - -@item -x:+name - +@item x:name +@item x:+name @end itemize where @code{name} is a string which is matched against the category given in the @code{VIR_LOG_INIT()} at the top of each libvirt source -file, e.g., @samp{"remote"}, @samp{"qemu"}, or @samp{"util.json"} (the -name in the filter can be a substring of the full category name, in -order to match multiple similar categories), the optional @samp{"+"} -prefix tells libvirt to log stack trace for each message matching name, -and @code{x} is the minimal level where matching messages should be -logged: +file, e.g., "remote", "qemu", or "util.json" (the name in the filter can +be a substring of the full category name, in order to match multiple +similar categories), the optional "+" prefix tells libvirt to log stack +trace for each message matching name, and @code{x} is the minimal level +where matching messages should be logged: @itemize @bullet -@item -1: DEBUG - -@item -2: INFO - -@item -3: WARNING - -@item -4: ERROR - +@item 1: DEBUG +@item 2: INFO +@item 3: WARNING +@item 4: ERROR @end itemize Multiple filters can be defined in a single filters statement, they just need to be separated by spaces. -Defaults to @samp{"3:remote 4:event"}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} string log-outputs -Logging outputs. - -An output is one of the places to save logging information. The format -for an output can be: +@item @code{log-outputs} (default: @code{"3:syslog:libvirtd"}) (type: string) +Logging outputs. An output is one of the places to save logging +information The format for an output can be: @table @code @item x:stderr @@ -38308,137 +38122,77 @@ Virtualization Services @item x:journald output to journald logging system - @end table -In all case the x prefix is the minimal level, acting as a filter +In all case the x prefix is the minimal level, acting as a +filter @itemize @bullet -@item -1: DEBUG - -@item -2: INFO - -@item -3: WARNING - -@item -4: ERROR - +@item 1: DEBUG +@item 2: INFO +@item 3: WARNING +@item 4: ERROR @end itemize Multiple outputs can be defined, they just need to be separated by spaces. -Defaults to @samp{"3:stderr"}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer audit-level +@item @code{audit-level} (default: @code{1}) (type: integer) Allows usage of the auditing subsystem to be altered @itemize @bullet -@item -0: disable all auditing - -@item -1: enable auditing, only if enabled on host - -@item -2: enable auditing, and exit if disabled on host. - +@item 0: disable all auditing +@item 1: enable auditing, only if enabled on host +@item 2: enable auditing, and exit if disabled on host. @end itemize -Defaults to @samp{1}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} boolean audit-logging +@item @code{audit-logging} (default: @code{#f}) (type: boolean) Send audit messages via libvirt logging infrastructure. -Defaults to @samp{#f}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} optional-string host-uuid -Host UUID@. UUID must not have all digits be the same. - -Defaults to @samp{""}. - -@end deftypevr +@item @code{host-uuid} (default: @code{""}) (type: optional-string) +Host UUID. UUID must not have all digits be the same. -@deftypevr {@code{libvirt-configuration} parameter} string host-uuid-source +@item @code{host-uuid-source} (default: @code{"smbios"}) (type: string) Source to read host UUID. @itemize @bullet -@item -@code{smbios}: fetch the UUID from @code{dmidecode -s system-uuid} - -@item -@code{machine-id}: fetch the UUID from @code{/etc/machine-id} - +@item @code{smbios}: fetch the UUID from @code{dmidecode -s system-uuid} +@item @code{machine-id}: fetch the UUID from @code{/etc/machine-id} @end itemize If @code{dmidecode} does not provide a valid UUID a temporary UUID will be generated. -Defaults to @samp{"smbios"}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer keepalive-interval +@item @code{keepalive-interval} (default: @code{5}) (type: integer) A keepalive message is sent to a client after @code{keepalive_interval} seconds of inactivity to check if the client is still responding. If set to -1, libvirtd will never send keepalive requests; however clients can still send them and the daemon will send responses. -Defaults to @samp{5}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer keepalive-count +@item @code{keepalive-count} (default: @code{5}) (type: integer) Maximum number of keepalive messages that are allowed to be sent to the client without getting any response before the connection is considered -broken. - -In other words, the connection is automatically closed approximately -after @code{keepalive_interval * (keepalive_count + 1)} seconds since -the last message received from the client. When @code{keepalive-count} -is set to 0, connections will be automatically closed after -@code{keepalive-interval} seconds of inactivity without sending any -keepalive messages. - -Defaults to @samp{5}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer admin-keepalive-interval +broken. In other words, the connection is automatically closed +approximately after @code{keepalive_interval * (keepalive_count + 1)} +seconds since the last message received from the client. When +@code{keepalive-count} is set to 0, connections will be automatically +closed after @code{keepalive-interval} seconds of inactivity without +sending any keepalive messages. + +@item @code{admin-keepalive-interval} (default: @code{5}) (type: integer) Same as above but for admin interface. -Defaults to @samp{5}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer admin-keepalive-count +@item @code{admin-keepalive-count} (default: @code{5}) (type: integer) Same as above but for admin interface. -Defaults to @samp{5}. - -@end deftypevr - -@deftypevr {@code{libvirt-configuration} parameter} integer ovs-timeout -Timeout for Open vSwitch calls. +@item @code{ovs-timeout} (default: @code{5}) (type: integer) +Timeout for Open vSwitch calls. The @code{ovs-vsctl} utility is used +for the configuration and its timeout option is set by default to 5 +seconds to avoid potential infinite waits blocking libvirt. -The @code{ovs-vsctl} utility is used for the configuration and its -timeout option is set by default to 5 seconds to avoid potential -infinite waits blocking libvirt. - -Defaults to @samp{5}. - -@end deftypevr - -@c %end of autogenerated docs +@end table +@end deftp +@c %end of fragment @subsubheading Virtlog daemon The virtlogd service is a server side daemon component of libvirt that is diff --git a/gnu/services/virtualization.scm b/gnu/services/virtualization.scm index 555c0be55e..40dad7dc1e 100644 --- a/gnu/services/virtualization.scm +++ b/gnu/services/virtualization.scm @@ -7,6 +7,7 @@ ;;; Copyright © 2022 Leo Nikkilä ;;; Copyright © 2023 Efraim Flashner ;;; Copyright © 2024 Raven Hallsby +;;; Copyright © 2025 Maxim Cournoyer ;;; ;;; This file is part of GNU Guix. ;;; @@ -29,6 +30,7 @@ (define-module (gnu services virtualization) #:use-module (gnu image) #:use-module (gnu packages admin) #:use-module (gnu packages bash) + #:use-module (gnu packages firmware) #:use-module (gnu packages gdb) #:autoload (gnu packages gnupg) (guile-gcrypt) #:use-module (gnu packages package-management) @@ -107,6 +109,7 @@ (define-module (gnu services virtualization) libvirt-configuration-ca-file libvirt-configuration-cert-file libvirt-configuration-crl-file + libvirt-configuration-firmwares libvirt-configuration-host-uuid libvirt-configuration-host-uuid-source libvirt-configuration-keepalive-count @@ -205,6 +208,9 @@ (define (serialize-optional-string field-name val) (format #t "# ~a = \"\"\n" (uglify-field-name field-name)) (serialize-string field-name val))) +(define list-of-file-likes? + (list-of file-like?)) + (define-configuration libvirt-configuration (libvirt (file-like libvirt) @@ -212,7 +218,12 @@ (define-configuration libvirt-configuration (qemu (file-like qemu) "Qemu package.") - + (firmwares + (list-of-file-likes (list ovmf-x86-64)) + "List of UEFI/BIOS firmware packages to make available. Each firmware +package should contain a @file{share/qemu/firmware/@var{NAME}.json} QEMU +firmware metadata file." + (serializer empty-serializer)) (listen-tls? (boolean #t) "Flag listening for secure TLS connections on the public TCP/IP port. @@ -540,7 +551,6 @@ (define (%libvirt-activation config) (use-modules (guix build utils)) (mkdir-p #$sock-dir)))) - (define (libvirt-shepherd-service config) (let* ((config-file (libvirt-conf-file config)) (libvirt (libvirt-configuration-libvirt config)) @@ -553,7 +563,8 @@ (define (libvirt-shepherd-service config) (list (string-append #$libvirt "/sbin/libvirtd") "-f" #$config-file #$@(if listen-tcp? '("--listen") '())) - ;; For finding qemu, ip binaries and kernel modules. + ;; For finding qemu, firmwares, the 'ip' command and + ;; kernel modules. #:environment-variables (list (string-append @@ -564,29 +575,45 @@ (define (libvirt-shepherd-service config) "/run/booted-system/kernel/lib/modules")))) (stop #~(make-kill-destructor)))))) +(define (/etc/qemu/firmware config) + (let ((firmwares (libvirt-configuration-firmwares config))) + `(("qemu" + ,(computed-file + "etc-qemu-firmware" + (with-imported-modules '((guix build union)) + #~(begin + (use-modules (guix build union) (srfi srfi-26)) + (mkdir #$output) + (union-build (string-append #$output "/firmware") + (map (cut string-append <> "/share/qemu/firmware") + (list #$@firmwares)))))))))) + (define libvirt-service-type - (service-type (name 'libvirt) - (extensions - (list - (service-extension polkit-service-type - (compose list libvirt-configuration-libvirt)) - (service-extension profile-service-type - (lambda (config) - (list - (libvirt-configuration-libvirt config) - (libvirt-configuration-qemu config)))) - (service-extension activation-service-type - %libvirt-activation) - (service-extension shepherd-root-service-type - libvirt-shepherd-service) - (service-extension account-service-type - (const %libvirt-accounts)))) - (default-value (libvirt-configuration)) - (description "Run @command{libvirtd}, a daemon of the libvirt + (service-type + (name 'libvirt) + (extensions + (list + (service-extension polkit-service-type + (compose list libvirt-configuration-libvirt)) + (service-extension profile-service-type + (lambda (config) + (list (libvirt-configuration-libvirt config) + (libvirt-configuration-qemu config)))) + ;; Libvirt only considers the $libvirt/share/qemu/firmware and + ;; /etc/qemu/firmware directories to locate the QEMU firmware metadata + ;; specifications. + (service-extension etc-service-type /etc/qemu/firmware) + (service-extension activation-service-type + %libvirt-activation) + (service-extension shepherd-root-service-type + libvirt-shepherd-service) + (service-extension account-service-type + (const %libvirt-accounts)))) + (default-value (libvirt-configuration)) + (description "Run @command{libvirtd}, a daemon of the libvirt virtualization management system. This daemon runs on host servers and performs required management tasks for virtualized guests."))) - (define-record-type* virtlog-configuration make-virtlog-configuration virtlog-configuration? @@ -638,11 +665,6 @@ (define virtlog-service-type (description "Run @command{virtlogd}, a daemon libvirt that is used to manage logs from @acronym{VM, virtual machine} consoles."))) -(define (generate-libvirt-documentation) - (generate-documentation - `((libvirt-configuration ,libvirt-configuration-fields)) - 'libvirt-configuration)) - ;;; ;;; Transparent QEMU emulation via binfmt_misc. diff --git a/gnu/tests/virtualization.scm b/gnu/tests/virtualization.scm index a3c9c4014b..e08f66eb28 100644 --- a/gnu/tests/virtualization.scm +++ b/gnu/tests/virtualization.scm @@ -4,6 +4,7 @@ ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen ;;; Copyright © 2021 Pierre Langlois ;;; Copyright © 2022 Marius Bakke +;;; Copyright © 2025 Maxim Cournoyer ;;; ;;; This file is part of GNU Guix. ;;; @@ -69,7 +70,8 @@ (define (run-libvirt-test) (define vm (virtual-machine (operating-system os) - (port-forwardings '()))) + (port-forwardings '()) + (memory-size 512))) (define test (with-imported-modules '((gnu build marionette)) @@ -135,6 +137,35 @@ (define (run-libvirt-test) "-c" "qemu:///system" "net-start" "default")) marionette)) + (test-assert "configured firmwares are available to libvirt" + (marionette-eval + '(begin + (use-modules (ice-9 popen) + (ice-9 textual-ports) + (srfi srfi-1) + (srfi srfi-26)) + (let* ((conf-firmwares (list #$@(libvirt-configuration-firmwares + (libvirt-configuration)))) + (virsh #$(file-append libvirt "/bin/virsh")) + (input-pipe (open-pipe* + OPEN_READ + virsh "-c" "qemu:///system" + "domcapabilities" "--xpath" + "/domainCapabilities/os/loader/value/text()")) + (output (get-string-all input-pipe)) + (found-firmwares (string-split (string-trim-both output) + #\newline))) + (close-pipe input-pipe) + ;; Check that every configured firmware package is covered + ;; by at least by one firmware file available to libvirt. + (every (lambda (conf-firmware) + ;; The firmwares listed by virsh contains their + ;; full file names, not just their package output. + (any (cut string-prefix? conf-firmware <>) + found-firmwares)) + conf-firmwares))) + marionette)) + (test-end)))) (gexp->derivation "libvirt-test" test))