From nobody Mon Feb 9 17:34:49 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) client-ip=170.10.129.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1695834702; cv=none; d=zohomail.com; s=zohoarc; b=d1+UlMxEnpYnMX0Vux41hEePvNeyQ1v2H4azQd7KJ0W2eevEoE0YEjjQmJSkqkRz76S3ILXSVLgLXY1ny8ghW/Ix6hWgSs3MrRGPVratQw0zENC5lo/y8T9n+oUkoHpoJCtMO4ogg0np4i+BxBSQq7qQFubwH5gbSoG8kx/bZ1A= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1695834702; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=ChjNpiLBjb9yGnh3AIXtBjmbW4nbIt1yuBpler24R7Y=; b=k+8FVbocPrEe6rVVSs4S4S4uN+g7W0oxy7nF1DMAtJTm/wcLf13oww54PtHo5XL5USRS0EENuiCtsTDFIuSH94vJ5HoMTL+87Cs/blIfuiyex4cyPyYUK2mRBf76600W/1hXJSusx7916bP259oSU//ozQYhPTSqWJAYTgTanXY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mx.zohomail.com with SMTPS id 1695834702338545.5381389481129; Wed, 27 Sep 2023 10:11:42 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-549-EnwUaALSPjWUOoGhG-D9sQ-1; Wed, 27 Sep 2023 13:11:38 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4EB9C85A5BF; Wed, 27 Sep 2023 17:11:34 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0331FC0FE03; Wed, 27 Sep 2023 17:11:34 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 6568319466FA; Wed, 27 Sep 2023 17:11:17 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 8FA2819465A4 for ; Wed, 27 Sep 2023 16:21:01 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id 210331005E2A; Wed, 27 Sep 2023 16:19:41 +0000 (UTC) Received: from harajuku.usersys.redhat.com (unknown [10.45.226.180]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8784E10EE6C9 for ; Wed, 27 Sep 2023 16:19:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1695834701; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=ChjNpiLBjb9yGnh3AIXtBjmbW4nbIt1yuBpler24R7Y=; b=g2mRnFgE78AuzrHFcwc+pTdgntnMuIM08g+dK4Dya/A4asDwtjHA67JTSfCv61B7FoNFat TYMDnsdAAfeN1xR8KGw7yzxoJrFToIJQsW4ALpibxqBHJgyo5gBY9ew/z/ms4XSt+UpDxo vKv+AtKQaA6QgL74VnqoZUaP4fUkq4w= X-MC-Unique: EnwUaALSPjWUOoGhG-D9sQ-1 X-Original-To: libvir-list@listman.corp.redhat.com From: Andrea Bolognani To: libvir-list@redhat.com Subject: [libvirt PATCH v2 06/33] systemd: Introduce common templates Date: Wed, 27 Sep 2023 18:19:07 +0200 Message-ID: <20230927161934.181728-7-abologna@redhat.com> In-Reply-To: <20230927161934.181728-1-abologna@redhat.com> References: <20230927161934.181728-1-abologna@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 3.1 on 10.11.54.8 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1695834703692100001 Content-Type: text/plain; charset="utf-8"; x-default="true" We already use templating to generate sockets, which are all based off libvirtd's. Push the idea further, and extend it to cover services as well. This is more challenging, as the various modular daemons each have their own needs in terms of what system services needs to be available before they can be started, which other components of libvirt they depend on, and so on. In order to make this sort of per-service tweaks possible, we introduce a Python script that can merge two systemd units together. The script is aware of the semantics of systemd's unit definition format, so it can intelligently merge sections together. This generic systemd unit merging mechanism will also supersede the extremely ad-hoc @deps@ variable, which is currently used in a single scenario. Signed-off-by: Andrea Bolognani Reviewed-by: Daniel P. Berrang=C3=A9 --- scripts/merge-systemd-units.py | 91 ++++++++++++++++++++++++++++++++++ scripts/meson.build | 1 + src/meson.build | 22 ++++++++ src/virtd-admin.socket.in | 13 +++++ src/virtd-ro.socket.in | 13 +++++ src/virtd-tcp.socket.in | 12 +++++ src/virtd-tls.socket.in | 12 +++++ src/virtd.service.in | 25 ++++++++++ src/virtd.socket.in | 12 +++++ 9 files changed, 201 insertions(+) create mode 100755 scripts/merge-systemd-units.py create mode 100644 src/virtd-admin.socket.in create mode 100644 src/virtd-ro.socket.in create mode 100644 src/virtd-tcp.socket.in create mode 100644 src/virtd-tls.socket.in create mode 100644 src/virtd.service.in create mode 100644 src/virtd.socket.in diff --git a/scripts/merge-systemd-units.py b/scripts/merge-systemd-units.py new file mode 100755 index 0000000000..136bc8d416 --- /dev/null +++ b/scripts/merge-systemd-units.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 + +import sys + +SECTIONS =3D [ + '[Unit]', + '[Service]', + '[Socket]', + '[Install]', +] + + +def parse_unit(unit_path): + unit =3D {} + current_section =3D '[Invalid]' + + with open(unit_path) as f: + for line in f: + line =3D line.strip() + + if line =3D=3D '': + continue + + if line[0] =3D=3D '[' and line[-1] =3D=3D ']': + if line not in SECTIONS: + print('Unknown section {}'.format(line)) + sys.exit(1) + + current_section =3D line + continue + + if current_section not in unit: + unit[current_section] =3D [] + + unit[current_section].append(line) + + if '[Invalid]' in unit: + print('Contents found outside of any section') + sys.exit(1) + + return unit + + +def format_unit(unit): + lines =3D [] + + for section in SECTIONS: + if section not in unit: + continue + + lines.append(section) + + for line in unit[section]: + lines.append(line) + + lines.append('') + + return '\n'.join(lines) + + +def merge_units(base, extra): + merged =3D {} + + for section in SECTIONS: + if section in extra and section not in base: + print('Section {} in extra but not in base'.format(section)) + sys.exit(1) + + if section not in base: + continue + + merged[section] =3D base[section] + + if section not in extra: + continue + + merged[section].extend(extra[section]) + + return merged + + +if len(sys.argv) < 2: + print('usage: {} BASE EXTRA'.format(sys.argv[0])) + sys.exit(1) + +base =3D parse_unit(sys.argv[1]) +extra =3D parse_unit(sys.argv[2]) + +merged =3D merge_units(base, extra) + +sys.stdout.write(format_unit(merged)) diff --git a/scripts/meson.build b/scripts/meson.build index 05b71184f1..65fd1e21c5 100644 --- a/scripts/meson.build +++ b/scripts/meson.build @@ -19,6 +19,7 @@ scripts =3D [ 'header-ifdef.py', 'hvsupport.py', 'hyperv_wmi_generator.py', + 'merge-systemd-units.py', 'meson-dist.py', 'meson-gen-authors.py', 'meson-gen-def.py', diff --git a/src/meson.build b/src/meson.build index 2fbf98b9fe..02c92621ba 100644 --- a/src/meson.build +++ b/src/meson.build @@ -203,6 +203,8 @@ libvirtd_socket_admin_in =3D files('remote' / 'libvirtd= -admin.socket.in') # * sockets - array of additional sockets (optional, default [ 'main', '= ro', 'admin' ]) # * service_in - service source file (optional, default remote/libvirtd.= service.in) # * socket_$name_in - additional socket source files (optional, default = remote/libvirtd.socket.in ) +# * service_extra_in - unit to merge with service_in (optional, default = None) +# * socket_extra_in - unit to merge with socket_$name_in (optional, defa= ult None) # * deps - socket dependencies (optional, default '') virt_daemon_units =3D [] =20 @@ -817,6 +819,7 @@ if conf.has('WITH_LIBVIRTD') 'initconfdir': initconfdir, 'name': unit['name'], 'service': unit['service'], + 'SERVICE': unit['service'].to_upper(), 'sockprefix': unit.get('sockprefix', unit['service']), 'deps': unit.get('deps', ''), 'sockmode': sockmode, @@ -825,6 +828,15 @@ if conf.has('WITH_LIBVIRTD') service_in =3D unit.get('service_in', service_in_default) service_out =3D '@0@.service'.format(unit['service']) =20 + if 'service_extra_in' in unit + service_in =3D configure_file( + input: [ service_in, unit['service_extra_in'] ], + output: '@0@.in'.format(service_out), + command: [ merge_systemd_units_prog, '@INPUT0@', '@INPUT1@' ], + capture: true, + ) + endif + configure_file( input: service_in, output: service_out, @@ -843,6 +855,16 @@ if conf.has('WITH_LIBVIRTD') socket_in =3D unit.get('socket_@0@_in'.format(socket), socket_in= _default) socket_out =3D '@0@-@1@.socket'.format(unit['service'], socket) endif + + if 'socket_extra_in' in unit + socket_in =3D configure_file( + input: [ socket_in, unit['socket_extra_in'] ], + output: '@0@.in'.format(socket_out), + command: [ merge_systemd_units_prog, '@INPUT0@', '@INPUT1@' ], + capture: true, + ) + endif + configure_file( input: socket_in, output: socket_out, diff --git a/src/virtd-admin.socket.in b/src/virtd-admin.socket.in new file mode 100644 index 0000000000..39bb0badea --- /dev/null +++ b/src/virtd-admin.socket.in @@ -0,0 +1,13 @@ +[Unit] +Description=3D@name@ admin socket +Before=3D@service@.service +BindsTo=3D@service@.socket +After=3D@service@.socket + +[Socket] +ListenStream=3D@runstatedir@/libvirt/@sockprefix@-admin-sock +Service=3D@service@.service +SocketMode=3D0600 + +[Install] +WantedBy=3Dsockets.target diff --git a/src/virtd-ro.socket.in b/src/virtd-ro.socket.in new file mode 100644 index 0000000000..b7b7ae0dd8 --- /dev/null +++ b/src/virtd-ro.socket.in @@ -0,0 +1,13 @@ +[Unit] +Description=3D@name@ local read-only socket +Before=3D@service@.service +BindsTo=3D@service@.socket +After=3D@service@.socket + +[Socket] +ListenStream=3D@runstatedir@/libvirt/@sockprefix@-sock-ro +Service=3D@service@.service +SocketMode=3D0666 + +[Install] +WantedBy=3Dsockets.target diff --git a/src/virtd-tcp.socket.in b/src/virtd-tcp.socket.in new file mode 100644 index 0000000000..7c8bcdb525 --- /dev/null +++ b/src/virtd-tcp.socket.in @@ -0,0 +1,12 @@ +[Unit] +Description=3D@name@ non-TLS IP socket +Before=3D@service@.service +BindsTo=3D@service@.socket +After=3D@service@.socket + +[Socket] +ListenStream=3D16509 +Service=3D@service@.service + +[Install] +WantedBy=3Dsockets.target diff --git a/src/virtd-tls.socket.in b/src/virtd-tls.socket.in new file mode 100644 index 0000000000..c6dceb2d4e --- /dev/null +++ b/src/virtd-tls.socket.in @@ -0,0 +1,12 @@ +[Unit] +Description=3D@name@ TLS IP socket +Before=3D@service@.service +BindsTo=3D@service@.socket +After=3D@service@.socket + +[Socket] +ListenStream=3D16514 +Service=3D@service@.service + +[Install] +WantedBy=3Dsockets.target diff --git a/src/virtd.service.in b/src/virtd.service.in new file mode 100644 index 0000000000..76f9c60351 --- /dev/null +++ b/src/virtd.service.in @@ -0,0 +1,25 @@ +[Unit] +Description=3D@name@ daemon +Conflicts=3Dlibvirtd.service +Requires=3D@service@.socket +Requires=3D@service@-ro.socket +Requires=3D@service@-admin.socket +After=3Dnetwork.target +After=3Ddbus.service +After=3Dapparmor.service +Documentation=3Dman:@service@(8) +Documentation=3Dhttps://libvirt.org + +[Service] +Type=3Dnotify +Environment=3D@SERVICE@_ARGS=3D"--timeout 120" +EnvironmentFile=3D-@initconfdir@/@service@ +ExecStart=3D@sbindir@/@service@ $@SERVICE@_ARGS +ExecReload=3D/bin/kill -HUP $MAINPID +Restart=3Don-failure + +[Install] +WantedBy=3Dmulti-user.target +Also=3D@service@.socket +Also=3D@service@-ro.socket +Also=3D@service@-admin.socket diff --git a/src/virtd.socket.in b/src/virtd.socket.in new file mode 100644 index 0000000000..aec0708fd4 --- /dev/null +++ b/src/virtd.socket.in @@ -0,0 +1,12 @@ +[Unit] +Description=3D@name@ local socket +Before=3D@service@.service + +[Socket] +ListenStream=3D@runstatedir@/libvirt/@sockprefix@-sock +Service=3D@service@.service +SocketMode=3D@sockmode@ +RemoveOnStop=3Dyes + +[Install] +WantedBy=3Dsockets.target --=20 2.41.0