diff options
Diffstat (limited to 'contrib/fedora')
| -rwxr-xr-x | contrib/fedora/REQUIRED_PACKAGES | 108 | ||||
| -rw-r--r-- | contrib/fedora/rpm/00-server.conf | 14 | ||||
| -rw-r--r-- | contrib/fedora/rpm/20-connectivity-fedora.conf | 10 | ||||
| -rw-r--r-- | contrib/fedora/rpm/20-connectivity-redhat.conf | 10 | ||||
| -rw-r--r-- | contrib/fedora/rpm/22-wifi-mac-addr.conf | 31 | ||||
| -rw-r--r-- | contrib/fedora/rpm/70-nm-connectivity.conf | 15 | ||||
| -rw-r--r-- | contrib/fedora/rpm/NetworkManager.conf | 52 | ||||
| -rw-r--r-- | contrib/fedora/rpm/NetworkManager.spec | 1307 | ||||
| -rw-r--r-- | contrib/fedora/rpm/README | 27 | ||||
| -rwxr-xr-x | contrib/fedora/rpm/build.sh | 288 | ||||
| -rwxr-xr-x | contrib/fedora/rpm/build_clean.sh | 303 | ||||
| -rwxr-xr-x | contrib/fedora/rpm/configure-for-system.sh | 526 | ||||
| -rwxr-xr-x | contrib/fedora/rpm/mockbuild.sh | 20 | ||||
| -rw-r--r-- | contrib/fedora/rpm/readme-ifcfg-rh-migrated.txt | 84 | ||||
| -rw-r--r-- | contrib/fedora/rpm/readme-ifcfg-rh.txt | 63 | ||||
| -rwxr-xr-x | contrib/fedora/rpm/release.sh | 604 | ||||
| -rwxr-xr-x | contrib/fedora/utils/makerepo.sh | 698 |
17 files changed, 4160 insertions, 0 deletions
diff --git a/contrib/fedora/REQUIRED_PACKAGES b/contrib/fedora/REQUIRED_PACKAGES new file mode 100755 index 00000000..38ca9026 --- /dev/null +++ b/contrib/fedora/REQUIRED_PACKAGES @@ -0,0 +1,108 @@ +#!/bin/bash + +# A list of packages useful/needed to build and develop +# NetworkManager on Fedora and RHEL. +# +# Not all of these packages are available, depending +# on your distribution/release. But yum will happily +# skip them. +# +# Not all of these packages are strictly speaking necessary. +# This is a generous list of related packages. + +set -xe + +DNF="$(command -v dnf &>/dev/null && echo dnf || echo yum)" + +SUDO= +[ "$EUID" -eq 0 ] || SUDO=sudo + +install() { + if [ "$NM_INSTALL" != "" ]; then + $NM_INSTALL "$@" + else + $SUDO "$DNF" install -y "$@" + fi +} + +install_ignore_missing() { + for p; do + install "$p" || : + done +} + +if test "$NM_NO_EXTRA" != 1; then + # these packages are convenient for developing, but not necessary + # for CI testing. + EXTRA_PACKAGES=( + bash-completion \ + cscope \ + ) +else + EXTRA_PACKAGES=() +fi + +install \ + /usr/bin/clang-format \ + /usr/bin/xargs \ + ModemManager-devel \ + ModemManager-glib-devel \ + audit-libs-devel \ + bluez-libs-devel \ + clang \ + dbus-devel \ + dbus-x11 \ + dhclient \ + firewalld-filesystem \ + gcc-c++ \ + gettext-devel \ + git \ + glib2-doc \ + gnutls-devel \ + gobject-introspection-devel \ + gtk-doc \ + iptables \ + jansson-devel \ + jq \ + libcurl-devel \ + libndp-devel \ + libselinux-devel \ + libtool \ + libuuid-devel \ + make \ + meson \ + mobile-broadband-provider-info-devel \ + newt-devel \ + nss-devel \ + polkit-devel \ + ppp \ + ppp-devel \ + python3-dbus \ + python3-gobject \ + python3-pexpect \ + readline-devel \ + rpm-build \ + systemd-devel \ + teamd-devel \ + util-linux \ + vala \ + valgrind \ + which \ + "${EXTRA_PACKAGES[@]}" + +# some packages don't exist in certain distributions. Install them one-by-one, and ignore errors. +install_ignore_missing \ + black \ + dbus-python \ + iproute-tc \ + libasan \ + libpsl-devel \ + libubsan \ + libvala-devel \ + pexpect \ + pygobject3-base \ + python-gobject-base \ + python36-pexpect \ + qt-devel \ + vala-devel \ + #end diff --git a/contrib/fedora/rpm/00-server.conf b/contrib/fedora/rpm/00-server.conf new file mode 100644 index 00000000..ba3d29fb --- /dev/null +++ b/contrib/fedora/rpm/00-server.conf @@ -0,0 +1,14 @@ +# This configuration file changes NetworkManager's behavior to +# what's expected on "traditional UNIX server" type deployments. +# +# See "man NetworkManager.conf" for more information about these +# and other keys. + +[main] +# Do not do automatic (DHCP/SLAAC) configuration on ethernet devices +# with no other matching connections. +no-auto-default=* + +# Ignore the carrier (cable plugged in) state when attempting to +# activate static-IP connections. +ignore-carrier=* diff --git a/contrib/fedora/rpm/20-connectivity-fedora.conf b/contrib/fedora/rpm/20-connectivity-fedora.conf new file mode 100644 index 00000000..5c9476a0 --- /dev/null +++ b/contrib/fedora/rpm/20-connectivity-fedora.conf @@ -0,0 +1,10 @@ +# Enable connectivity checking for NetworkManager. +# See `man NetworkManager.conf`. +# +# Note that connectivity checking works badly with rp_filter set to +# strict. Check "/proc/sys/net/ipv4/conf/*/rp_filter". +[connectivity] +enabled=true +uri=http://fedoraproject.org/static/hotspot.txt +response=OK +interval=300 diff --git a/contrib/fedora/rpm/20-connectivity-redhat.conf b/contrib/fedora/rpm/20-connectivity-redhat.conf new file mode 100644 index 00000000..070f030b --- /dev/null +++ b/contrib/fedora/rpm/20-connectivity-redhat.conf @@ -0,0 +1,10 @@ +# Enable connectivity checking for NetworkManager. +# See `man NetworkManager.conf`. +# +# Note that connectivity checking works badly with rp_filter set to +# strict. Check "/proc/sys/net/ipv4/conf/*/rp_filter". +[connectivity] +enabled=true +uri=http://static.redhat.com/test/rhel-networkmanager.txt +response=OK +interval=300 diff --git a/contrib/fedora/rpm/22-wifi-mac-addr.conf b/contrib/fedora/rpm/22-wifi-mac-addr.conf new file mode 100644 index 00000000..2e329c88 --- /dev/null +++ b/contrib/fedora/rpm/22-wifi-mac-addr.conf @@ -0,0 +1,31 @@ +# This sets defaults for Wi-Fi profiles to set a generated, stable MAC address. +# +# Do not modify this file. You can hide/overwrite this file by placing a file +# to "/etc/NetworkManager/conf.d/22-wifi-mac-addr.conf". You can also add +# configuration snippets with higher priority that override this setting (see +# `man 5 NetworkManager.conf`). Most importantly, this snippet only sets +# default values for the profile. You can explicitly set the value for each +# profile, so that this default value is not used. +# +# For example, on a particular profile/network set +# +# $ nmcli connection modify "$PROFILE" wifi.cloned-mac-address permanent +# +# to use the hardware MAC address. This prevents the default from this file +# to take effect. +# +# Or +# +# $ nmcli connection modify "$PROFILE" wifi.cloned-mac-address stable connection.stable-id '${NETWORK_SSID}/${BOOT}' +# +# to get a generated MAC address that changes on each boot. Note how setting +# "connection.stable-id" also affects other aspects of the profile. +# +# See `man 5 nm-settings` for "wifi.cloned-mac-address" and "connection.stable-id". + +[connection.22-wifi-mac-addr] +match-device=type:wifi +wifi.cloned-mac-address=stable-ssid + +[.config] +enable=nm-version-min:1.45 diff --git a/contrib/fedora/rpm/70-nm-connectivity.conf b/contrib/fedora/rpm/70-nm-connectivity.conf new file mode 100644 index 00000000..0e4b0e27 --- /dev/null +++ b/contrib/fedora/rpm/70-nm-connectivity.conf @@ -0,0 +1,15 @@ +# The Strict mode of RFC3704 Reverse Path filtering breaks some pretty +# common and reasonable use cases. +# +# Notably, it makes it impossible for NetworkManager to do connectivity +# check on a newly arriving default route (it starts with a higher metric +# and is bumped lower if there's connectivity). +# +# Kernel's default is 0 (no filter), systemd configures a Loose filter since +# commit 230450d4e4f1 ('sysctl.d: switch net.ipv4.conf.all.rp_filter from 1 +# to 2'). However, RHEL systemd package happens to default to Strict mode +# for historic reasons. Let's override it if we're doing connectivity +# checking. + +# Source route verification +net.ipv4.conf.all.rp_filter = 0 diff --git a/contrib/fedora/rpm/NetworkManager.conf b/contrib/fedora/rpm/NetworkManager.conf new file mode 100644 index 00000000..287c9d01 --- /dev/null +++ b/contrib/fedora/rpm/NetworkManager.conf @@ -0,0 +1,52 @@ +# Configuration file for NetworkManager. +# +# See "man 5 NetworkManager.conf" for details. +# +# The directories /usr/lib/NetworkManager/conf.d/ and /run/NetworkManager/conf.d/ +# can contain additional .conf snippets installed by packages. These files are +# read before NetworkManager.conf and have thus lowest priority. +# The directory /etc/NetworkManager/conf.d/ can contain additional .conf +# snippets. Those snippets are merged last and overwrite the settings from this main +# file. +# +# The files within one conf.d/ directory are read in asciibetical order. +# +# You can prevent loading a file /usr/lib/NetworkManager/conf.d/NAME.conf +# by having a file NAME.conf in either /run/NetworkManager/conf.d/ or /etc/NetworkManager/conf.d/. +# Likewise, snippets from /run can be prevented from loading by placing +# a file with the same name in /etc/NetworkManager/conf.d/. +# +# If two files define the same key, the one that is read afterwards will overwrite +# the previous one. + +[main] +#plugins=keyfile,ifcfg-rh + + +[logging] +# When debugging NetworkManager, enabling debug logging is of great help. +# +# Logfiles contain no passwords and little sensitive information. But please +# check before posting the file online. You can also personally hand over the +# logfile to a NM developer to treat it confidential. Meet us on #nm on Libera.Chat. +# +# You can also change the log-level at runtime via +# $ nmcli general logging level TRACE domains ALL +# However, usually it's cleaner to enable debug logging +# in the configuration and restart NetworkManager so that +# debug logging is enabled from the start. +# +# You will find the logfiles in syslog, for example via +# $ journalctl -u NetworkManager +# +# Please post full logfiles for bug reports without pre-filtering or truncation. +# Also, for debugging the entire `journalctl` output can be interesting. Don't +# limit unnecessarily with `journalctl -u`. Exceptions are if you are worried +# about private data. Check before posting logfiles! +# +# Note that debug logging of NetworkManager can be quite verbose. Some messages +# might be rate-limited by the logging daemon (see RateLimitIntervalSec, RateLimitBurst +# in man journald.conf). Please disable rate-limiting before collecting debug logs! +# +#level=TRACE +#domains=ALL diff --git a/contrib/fedora/rpm/NetworkManager.spec b/contrib/fedora/rpm/NetworkManager.spec new file mode 100644 index 00000000..f55d243d --- /dev/null +++ b/contrib/fedora/rpm/NetworkManager.spec @@ -0,0 +1,1307 @@ +# SPEC file to build NetworkManager for testing. It aims for a similar +# configuration as rhel-7.0 and Fedora rawhide +# +# This spec file is not used as is to create official packages for RHEL, Fedora or any +# other distribution. +# +# Note that it contains __PLACEHOLDERS__ that will be replaced by the accompanying 'build.sh' script. + + +%global wpa_supplicant_version 1:1.1 + +%global ppp_version %(pkg-config --modversion pppd 2>/dev/null || sed -n 's/^#define\\s*VERSION\\s*"\\([^\\s]*\\)"$/\\1/p' %{_includedir}/pppd/patchlevel.h 2>/dev/null | grep . || echo bad) +%global glib2_version %(pkg-config --modversion glib-2.0 2>/dev/null || echo bad) + +%global epoch_version 1 +%global real_version __VERSION__ +%global rpm_version %{real_version} +%global release_version __RELEASE_VERSION__ +%global snapshot __SNAPSHOT__ +%global git_sha __COMMIT__ +%global bcond_default_debug __BCOND_DEFAULT_DEBUG__ +%global bcond_default_lto __BCOND_DEFAULT_LTO__ +%global bcond_default_test __BCOND_DEFAULT_TEST__ + +%global obsoletes_device_plugins 1:0.9.9.95-1 +%global obsoletes_ppp_plugin 1:1.5.3 +%global obsoletes_initscripts_updown 1:1.36.0-0.6 +%global obsoletes_ifcfg_rh 1:1.36.2 + +%global nmlibdir %{_prefix}/lib/%{name} +%global nmplugindir %{_libdir}/%{name}/%{version}-%{release} + +%global _hardened_build 1 + +%if "x%{?snapshot}" != "x" +%global snapshot_dot .%{snapshot} +%endif +%if "x%{?git_sha}" != "x" +%global git_sha_dot .%{git_sha} +%endif + +%global snap %{?snapshot_dot}%{?git_sha_dot} + +%global real_version_major %(printf '%s' '%{real_version}' | sed -n 's/^\\([1-9][0-9]*\\.[0-9][0-9]*\\)\\.[0-9][0-9]*$/\\1/p') + +%global systemd_units NetworkManager.service NetworkManager-wait-online.service NetworkManager-dispatcher.service nm-priv-helper.service + +%global systemd_units_cloud_setup nm-cloud-setup.service nm-cloud-setup.timer + +############################################################################### +%if 0%{?fedora} > 40 +%bcond_without meson +%else +%bcond_with meson +%endif +%bcond_without adsl +%bcond_without bluetooth +%bcond_without wwan +%if 0%{?rhel} >= 10 +%bcond_with team +%else +%bcond_without team +%endif +%bcond_without wifi +%bcond_without ovs +%bcond_without ppp +%bcond_without nmtui +%bcond_without nm_cloud_setup +%bcond_without regen_docs +%if %{bcond_default_debug} +%bcond_without debug +%else +%bcond_with debug +%endif +%if %{bcond_default_test} +%bcond_without test +%else +%bcond_with test +%endif +%if "%{?bcond_default_lto}" == "" +%if 0%{?fedora} >= 33 || 0%{?rhel} >= 9 +%bcond_without lto +%else +%bcond_with lto +%endif +%else +%if %{bcond_default_lto} +%bcond_without lto +%else +%bcond_with lto +%endif +%endif +%bcond_with sanitizer +%if 0%{?fedora} +%bcond_without connectivity_fedora +%else +%bcond_with connectivity_fedora +%endif +%if 0%{?rhel} && 0%{?rhel} >= 8 +%bcond_without connectivity_redhat +%else +%bcond_with connectivity_redhat +%endif +%if 0%{?fedora} >= 29 || 0%{?rhel} >= 8 +%bcond_without crypto_gnutls +%else +%bcond_with crypto_gnutls +%endif +%if 0%{?rhel} +%bcond_with iwd +%else +%bcond_without iwd +%endif +%if 0%{?fedora} >= 32 || 0%{?rhel} >= 8 +%bcond_without firewalld_zone +%else +%bcond_with firewalld_zone +%endif + +############################################################################### + +%if 0%{?fedora} || 0%{?rhel} >= 8 +%global dbus_version 1.9.18 +%global dbus_sys_dir %{_datadir}/dbus-1/system.d +%else +%global dbus_version 1.1 +%global dbus_sys_dir %{_sysconfdir}/dbus-1/system.d +%endif + +# Older libndp versions use select() (rh#1933041). On well known distros, +# choose a version that has the necessary fix. +%if 0%{?rhel} && 0%{?rhel} == 8 +%global libndp_version 1.7-4 +%else +%global libndp_version %{nil} +%endif + +%if %{with bluetooth} || %{with wwan} +%global with_modem_manager_1 1 +%else +%global with_modem_manager_1 0 +%endif + +%if 0%{?fedora} >= 31 || 0%{?rhel} >= 8 +%global dhcp_default internal +%else +%global dhcp_default dhclient +%endif + +%if 0%{?fedora} || 0%{?rhel} >= 8 +%global logging_backend_default journal +%if 0%{?fedora} || 0%{?rhel} >= 9 +%global dns_rc_manager_default auto +%else +%global dns_rc_manager_default symlink +%endif +%else +%global logging_backend_default syslog +%global dns_rc_manager_default file +%endif + +%if 0%{?fedora} >= 33 || 0%{?rhel} >= 9 +%global config_plugins_default_ifcfg_rh 0 +%else +%global config_plugins_default_ifcfg_rh 1 +%endif + +%if 0%{?rhel} >= 10 +%global with_ifcfg_rh 0 +%global split_ifcfg_rh 0 +%elif 0%{?fedora} >= 36 +%global with_ifcfg_rh 1 +%global split_ifcfg_rh 1 +%else +%global with_ifcfg_rh 1 +%global split_ifcfg_rh 0 +%endif + +%if (0%{?fedora} >= 36 && 0%{?fedora} < 39) || 0%{?rhel} == 9 +%global ifcfg_warning 1 +%else +%global ifcfg_warning 0 +%endif + +%if 0%{?fedora} >= 39 +%global ifcfg_migrate 1 +%else +%global ifcfg_migrate 0 +%endif + +%if 0%{?fedora} +# Although eBPF would be available on Fedora's kernel, it seems +# we often get SELinux denials (rh#1651654). But even aside them, +# bpf(BPF_MAP_CREATE, ...) randomly fails with EPERM. That might +# be related to `ulimit -l`. Anyway, this is not usable at the +# moment. +%global ebpf_enabled "no" +%else +%global ebpf_enabled "no" +%endif + +# Fedora 33 enables LTO by default by setting CFLAGS="-flto -ffat-lto-objects". +# However, we also require "-flto -flto-partition=none", so disable Fedora's +# default and use our configure option --with-lto instead. +%define _lto_cflags %{nil} + +############################################################################### + +Name: NetworkManager +Summary: Network connection manager and user applications +Epoch: %{epoch_version} +Version: %{rpm_version} +Release: %{release_version}%{?snap}%{?dist} +Group: System Environment/Base +License: GPL-2.0-or-later AND LGPL-2.1-or-later +URL: https://networkmanager.dev/ + +#Source: https://download.gnome.org/sources/NetworkManager/%{real_version_major}/%{name}-%{real_version}.tar.xz +Source: __SOURCE1__ +Source1: NetworkManager.conf +Source2: 00-server.conf +Source4: 20-connectivity-fedora.conf +Source5: 20-connectivity-redhat.conf +Source6: 22-wifi-mac-addr.conf +Source7: 70-nm-connectivity.conf +Source8: readme-ifcfg-rh.txt +Source9: readme-ifcfg-rh-migrated.txt + +#Patch1: 0001-some.patch + +Requires(post): systemd +%if 0%{?fedora} || 0%{?rhel} >= 8 +Requires(post): systemd-udev +%endif +Requires(post): /usr/sbin/update-alternatives +Requires(preun): systemd +Requires(preun): /usr/sbin/update-alternatives +Requires(postun): systemd + +Requires: dbus >= %{dbus_version} +Requires: glib2 >= %{glib2_version} +Requires: %{name}-libnm%{?_isa} = %{epoch}:%{version}-%{release} +%if "%{libndp_version}" != "" +Requires: libndp >= %{libndp_version} +%endif +Obsoletes: NetworkManager < %{obsoletes_device_plugins} +Obsoletes: NetworkManager < %{obsoletes_ppp_plugin} +Obsoletes: NetworkManager-wimax < 1:1.2 +%if 0%{?rhel} && 0%{?rhel} == 8 +Suggests: NetworkManager-initscripts-updown +%endif +Obsoletes: NetworkManager < %{obsoletes_initscripts_updown} +%if 0%{?split_ifcfg_rh} +Obsoletes: NetworkManager < %{obsoletes_ifcfg_rh} +%endif + +%if 0%{?rhel} && 0%{?rhel} <= 7 +# Kept for RHEL to ensure that wired 802.1x works out of the box +Requires: wpa_supplicant >= 1:1.1 +%endif + +Conflicts: NetworkManager-vpnc < 1:0.7.0.99-1 +Conflicts: NetworkManager-openvpn < 1:0.7.0.99-1 +Conflicts: NetworkManager-pptp < 1:0.7.0.99-1 +Conflicts: NetworkManager-openconnect < 0:0.7.0.99-1 +Conflicts: kde-plasma-networkmanagement < 1:0.9-0.49.20110527git.nm09 + +BuildRequires: make +BuildRequires: gcc +BuildRequires: libtool +BuildRequires: pkgconfig +%if %{with meson} +BuildRequires: meson +%else +BuildRequires: automake +BuildRequires: autoconf +%endif +BuildRequires: gettext-devel >= 0.19.8 + +BuildRequires: dbus-devel >= %{dbus_version} +BuildRequires: glib2-devel >= 2.40.0 +BuildRequires: gobject-introspection-devel >= 0.10.3 +%if %{with ppp} +BuildRequires: ppp-devel >= 2.4.5 +%endif +%if %{with crypto_gnutls} +BuildRequires: gnutls-devel >= 2.12 +%else +BuildRequires: nss-devel >= 3.11.7 +%endif +BuildRequires: readline-devel +BuildRequires: audit-libs-devel +%if %{with regen_docs} +BuildRequires: gtk-doc +%endif +BuildRequires: libudev-devel +BuildRequires: libuuid-devel +BuildRequires: /usr/bin/valac +BuildRequires: libxslt +%if %{with bluetooth} +BuildRequires: bluez-libs-devel +%endif +BuildRequires: systemd >= 200-3 systemd-devel +%if 0%{?fedora} +BuildRequires: libpsl-devel >= 0.1 +%endif +BuildRequires: libcurl-devel +BuildRequires: libndp-devel >= 1.0 +%if 0%{?with_modem_manager_1} +BuildRequires: ModemManager-glib-devel >= 1.0 +%endif +%if %{with wwan} +BuildRequires: mobile-broadband-provider-info-devel +%endif +%if %{with nmtui} +BuildRequires: newt-devel +%endif +BuildRequires: /usr/bin/dbus-launch +BuildRequires: python3 +BuildRequires: python3-gobject-base +BuildRequires: python3-dbus +BuildRequires: python3-pexpect +BuildRequires: libselinux-devel +BuildRequires: polkit-devel +BuildRequires: jansson-devel +%if %{with sanitizer} +BuildRequires: libasan +%if 0%{?fedora} || 0%{?rhel} >= 8 +BuildRequires: libubsan +%endif +%endif +%if %{with firewalld_zone} +BuildRequires: firewalld-filesystem +%endif +BuildRequires: iproute +%if 0%{?fedora} || 0%{?rhel} >= 8 +BuildRequires: iproute-tc +%endif + +Provides: %{name}-dispatcher%{?_isa} = %{epoch}:%{version}-%{release} + +# NetworkManager uses various parts of systemd-networkd internally, including +# DHCP client, IPv4 Link-Local address negotiation or LLDP support. +# This provide is essentially here so that NetworkManager shows on Security +# Response Team's radar in case a flaw is found. The code is frequently +# synchronized and thus it's not easy to establish a good version number +# here. The version of zero is there just to have something conservative so +# that the scripts that would parse the SPEC file naively would be unlikely +# to fail. Refer to git log for the real date and commit number of last +# synchronization: +# https://gitlab.freedesktop.org/NetworkManager/NetworkManager/commits/main/src/ +Provides: bundled(systemd) = 0 + + +%description +NetworkManager is a system service that manages network interfaces and +connections based on user or automatic configuration. It supports +Ethernet, Bridge, Bond, VLAN, Team, InfiniBand, Wi-Fi, mobile broadband +(WWAN), PPPoE and other devices, and supports a variety of different VPN +services. + + +%if %{with adsl} +%package adsl +Summary: ADSL device plugin for NetworkManager +Group: System Environment/Base +Requires: %{name}%{?_isa} = %{epoch}:%{version}-%{release} +Obsoletes: NetworkManager < %{obsoletes_device_plugins} + +%description adsl +This package contains NetworkManager support for ADSL devices. +%endif + + +%if %{with bluetooth} +%package bluetooth +Summary: Bluetooth device plugin for NetworkManager +Group: System Environment/Base +Requires: %{name}%{?_isa} = %{epoch}:%{version}-%{release} +Requires: NetworkManager-wwan = %{epoch}:%{version}-%{release} +%if 0%{?rhel} && 0%{?rhel} <= 7 +# No Requires:bluez to prevent it being installed when updating +# to the split NM package +%else +Requires: bluez >= 4.101-5 +%endif +Obsoletes: NetworkManager < %{obsoletes_device_plugins} + +%description bluetooth +This package contains NetworkManager support for Bluetooth devices. +%endif + + +%if %{with team} +%package team +Summary: Team device plugin for NetworkManager +Group: System Environment/Base +BuildRequires: teamd-devel +Requires: %{name}%{?_isa} = %{epoch}:%{version}-%{release} +Obsoletes: NetworkManager < %{obsoletes_device_plugins} +%if 0%{?fedora} || 0%{?rhel} >= 8 +# Team was split from main NM binary between 0.9.10 and 1.0 +# We need this Obsoletes in addition to the one above +# (git:3aede801521ef7bff039e6e3f1b3c7b566b4338d). +Obsoletes: NetworkManager < 1:1.0.0 +%endif + +%description team +This package contains NetworkManager support for team devices. +%endif + + +%if %{with wifi} +%package wifi +Summary: Wifi plugin for NetworkManager +Group: System Environment/Base +Requires: %{name}%{?_isa} = %{epoch}:%{version}-%{release} + +%if 0%{?fedora} >= 29 || 0%{?rhel} >= 9 +Requires: wireless-regdb +%else +Requires: crda +%endif + +%if %{with iwd} && (0%{?fedora} >= 25 || 0%{?rhel} >= 8) +Requires: (wpa_supplicant >= %{wpa_supplicant_version} or iwd) +Suggests: wpa_supplicant +%else +# Just require wpa_supplicant on platforms that don't support boolean +# dependencies even though the plugin supports both supplicant and +# iwd backend. +Requires: wpa_supplicant >= %{wpa_supplicant_version} +%endif + +Obsoletes: NetworkManager < %{obsoletes_device_plugins} + +%description wifi +This package contains NetworkManager support for Wifi and OLPC devices. +%endif + + +%if %{with wwan} +%package wwan +Summary: Mobile broadband device plugin for NetworkManager +Group: System Environment/Base +Requires: %{name}%{?_isa} = %{epoch}:%{version}-%{release} +%if 0%{?rhel} && 0%{?rhel} <= 7 +# No Requires:ModemManager to prevent it being installed when updating +# to the split NM package +%else +Requires: ModemManager +%endif +Obsoletes: NetworkManager < %{obsoletes_device_plugins} + +%description wwan +This package contains NetworkManager support for mobile broadband (WWAN) +devices. +%endif + + +%if %{with ovs} +%package ovs +Summary: Open vSwitch device plugin for NetworkManager +Group: System Environment/Base +Requires: %{name}%{?_isa} = %{epoch}:%{version}-%{release} +%if 0%{?rhel} == 0 +Requires: openvswitch +%endif + +%description ovs +This package contains NetworkManager support for Open vSwitch bridges. +%endif + + +%if %{with ppp} +%package ppp +Summary: PPP plugin for NetworkManager +Group: System Environment/Base +Requires: %{name}%{?_isa} = %{epoch}:%{version}-%{release} +Requires: ppp = %{ppp_version} +Requires: NetworkManager = %{epoch}:%{version}-%{release} +Obsoletes: NetworkManager < %{obsoletes_ppp_plugin} + +%description ppp +This package contains NetworkManager support for PPP. +%endif + + +%package libnm +Summary: Libraries for adding NetworkManager support to applications. +Group: Development/Libraries +Conflicts: NetworkManager-glib < 1:1.31.0 +License: LGPL-2.1-or-later + +%description libnm +This package contains the libraries that make it easier to use some +NetworkManager functionality from applications. + + +%package libnm-devel +Summary: Header files for adding NetworkManager support to applications. +Group: Development/Libraries +Requires: %{name}-libnm%{?_isa} = %{epoch}:%{version}-%{release} +Requires: glib2-devel +Requires: pkgconfig +License: LGPL-2.1-or-later + +%description libnm-devel +This package contains the header and pkg-config files for development +applications using NetworkManager functionality from applications. + + +%if %{with connectivity_fedora} +%package config-connectivity-fedora +Summary: NetworkManager config file for connectivity checking via Fedora servers +Group: System Environment/Base +BuildArch: noarch +Provides: NetworkManager-config-connectivity = %{epoch}:%{version}-%{release} + +%description config-connectivity-fedora +This adds a NetworkManager configuration file to enable connectivity checking +via Fedora infrastructure. +%endif + + +%if %{with connectivity_redhat} +%package config-connectivity-redhat +Summary: NetworkManager config file for connectivity checking via Red Hat servers +Group: System Environment/Base +BuildArch: noarch +Provides: NetworkManager-config-connectivity = %{epoch}:%{version}-%{release} + +%description config-connectivity-redhat +This adds a NetworkManager configuration file to enable connectivity checking +via Red Hat infrastructure. +%endif + + +%package config-server +Summary: NetworkManager config file for "server-like" defaults +Group: System Environment/Base +BuildArch: noarch + +%description config-server +This adds a NetworkManager configuration file to make it behave more +like the old "network" service. In particular, it stops NetworkManager +from automatically running DHCP on unconfigured ethernet devices, and +allows connections with static IP addresses to be brought up even on +ethernet devices with no carrier. + +This package is intended to be installed by default for server +deployments. + + +%if %{?with_ifcfg_rh} +%package dispatcher-routing-rules +Summary: NetworkManager dispatcher file for advanced routing rules +Group: System Environment/Base +%if 0%{?split_ifcfg_rh} +Requires: %{name}-initscripts-ifcfg-rh +%endif +BuildArch: noarch +Provides: %{name}-config-routing-rules = %{epoch}:%{version}-%{release} +Obsoletes: %{name}-config-routing-rules < 1:1.31.0 + +%description dispatcher-routing-rules +This adds a NetworkManager dispatcher file to support networking +configurations using "/etc/sysconfig/network-scripts/rule-NAME" files +(eg, to do policy-based routing). +%endif + + +%if %{with nmtui} +%package tui +Summary: NetworkManager curses-based UI +Group: System Environment/Base +Requires: %{name} = %{epoch}:%{version}-%{release} +Requires: %{name}-libnm%{?_isa} = %{epoch}:%{version}-%{release} + +%description tui +This adds a curses-based "TUI" (Text User Interface) to +NetworkManager, to allow performing some of the operations supported +by nm-connection-editor and nm-applet in a non-graphical environment. +%endif + + +%if 0%{?split_ifcfg_rh} +%package initscripts-ifcfg-rh +Summary: NetworkManager plugin for reading and writing connections in ifcfg-rh format +Group: System Environment/Base +Requires: %{name} = %{epoch}:%{version}-%{release} +Obsoletes: NetworkManager < %{obsoletes_ifcfg_rh} + +%description initscripts-ifcfg-rh +Installs a plugin for reading and writing connection profiles using +the Red Hat ifcfg format in /etc/sysconfig/network-scripts/. +%endif + + +%if %{with nm_cloud_setup} +%package cloud-setup +Summary: Automatically configure NetworkManager in cloud +Group: System Environment/Base +Requires: %{name} = %{epoch}:%{version}-%{release} +Requires: %{name}-libnm%{?_isa} = %{epoch}:%{version}-%{release} + +%description cloud-setup +Installs a nm-cloud-setup tool that can automatically configure +NetworkManager in cloud environment. Only certain cloud providers +like Aliyun, Azure, EC2, GCP are supported. +%endif + + +%if %{?with_ifcfg_rh} +%package initscripts-updown +Summary: Legacy ifup/ifdown scripts for NetworkManager that replace initscripts (network-scripts) +Group: System Environment/Base +BuildArch: noarch +Requires: NetworkManager +Requires: /usr/bin/nmcli +Obsoletes: NetworkManager < %{obsoletes_initscripts_updown} + +%description initscripts-updown +Installs alternative ifup/ifdown scripts that talk to NetworkManager. +This is only for backward compatibility with initscripts (network-scripts). +Preferably use nmcli instead. +%endif + +%prep +%autosetup -p1 -n NetworkManager-%{real_version} + + +%build +%if %{with meson} +%meson \ + -Db_ndebug=false \ + --warnlevel 2 \ +%if %{with test} + --werror \ +%endif + -Dnft=%{_sbindir}/nft \ + -Diptables=%{_sbindir}/iptables \ + -Ddhclient=%{_sbindir}/dhclient \ + -Ddhcpcanon=no \ + -Ddhcpcd=no \ + -Dconfig_dhcp_default=%{dhcp_default} \ +%if %{with crypto_gnutls} + -Dcrypto=gnutls \ +%else + -Dcrypto=nss \ +%endif +%if %{with debug} + -Dmore_logging=true \ + -Dmore_asserts=10000 \ +%else + -Dmore_logging=false \ + -Dmore_asserts=0 \ +%endif + -Dld_gc=true \ +%if %{with lto} + -D b_lto=true \ +%else + -D b_lto=false \ +%endif + -Dlibaudit=yes-disabled-by-default \ +%if 0%{?with_modem_manager_1} + -Dmodem_manager=true \ +%else + -Dmodem_manager=false \ +%endif +%if %{with wifi} + -Dwifi=true \ +%if 0%{?fedora} + -Dwext=true \ +%else + -Dwext=false \ +%endif +%else + -Dwifi=false \ +%endif +%if %{with iwd} + -Diwd=true \ +%else + -Diwd=false \ +%endif +%if %{with bluetooth} + -Dbluez5_dun=true \ +%else + -Dbluez5_dun=false \ +%endif +%if %{with nmtui} + -Dnmtui=true \ +%else + -Dnmtui=false \ +%endif +%if %{with nm_cloud_setup} + -Dnm_cloud_setup=true \ +%else + -Dnm_cloud_setup=false \ +%endif + -Dvapi=true \ + -Dintrospection=true \ +%if %{with regen_docs} + -Ddocs=true \ +%else + -Ddocs=false \ +%endif + -Dqt=false \ +%if %{with team} + -Dteamdctl=true \ +%else + -Dteamdctl=false \ +%endif +%if %{with ovs} + -Dovs=true \ +%else + -Dovs=false \ +%endif + -Dselinux=true \ + -Dpolkit=true \ + -Dconfig_auth_polkit_default=true \ + -Dmodify_system=true \ + -Dconcheck=true \ +%if 0%{?fedora} + -Dlibpsl=true \ +%else + -Dlibpsl=false \ +%endif +%if %{ebpf_enabled} != "yes" + -Debpf=false \ +%else + -Debpf=true \ +%endif + -Dsession_tracking=systemd \ + -Dsuspend_resume=systemd \ + -Dsystemdsystemunitdir=%{_unitdir} \ + -Dsystem_ca_path=/etc/pki/tls/cert.pem \ + -Ddbus_conf_dir=%{dbus_sys_dir} \ + -Dtests=yes \ + -Dvalgrind=no \ +%if %{?with_ifcfg_rh} + -Difcfg_rh=true \ +%else + -Difcfg_rh=false \ +%endif + -Difupdown=false \ +%if %{with ppp} + -Dppp=true \ + -Dpppd="%{_sbindir}/pppd" \ + -Dpppd_plugin_dir="%{_libdir}/pppd/%{ppp_version}" \ +%else + -Dppp=false \ +%endif +%if %{with firewalld_zone} + -Dfirewalld_zone=true \ +%else + -Dfirewalld_zone=false \ +%endif + -Ddist_version=%{version}-%{release} \ +%if %{?config_plugins_default_ifcfg_rh} + -Dconfig_plugins_default=ifcfg-rh \ +%endif +%if %{?ifcfg_migrate} + -Dconfig_migrate_ifcfg_rh_default=true \ +%endif + -Dresolvconf=no \ + -Dnetconfig=no \ + -Dconfig_dns_rc_manager_default=%{dns_rc_manager_default} \ + -Dconfig_logging_backend_default=%{logging_backend_default} + +%meson_build + +%else +# autotools +%if %{with regen_docs} +gtkdocize +%endif +autoreconf --install --force +%configure \ + --with-runstatedir=%{_rundir} \ + --enable-silent-rules=no \ + --enable-static=no \ + --with-nft=%{_sbindir}/nft \ + --with-iptables=%{_sbindir}/iptables \ + --with-dhclient=%{_sbindir}/dhclient \ + --with-dhcpcd=no \ + --with-dhcpcanon=no \ + --with-config-dhcp-default=%{dhcp_default} \ +%if %{with crypto_gnutls} + --with-crypto=gnutls \ +%else + --with-crypto=nss \ +%endif +%if %{with sanitizer} + --with-address-sanitizer=exec \ +%if 0%{?fedora} || 0%{?rhel} >= 8 + --enable-undefined-sanitizer=yes \ +%else + --enable-undefined-sanitizer=no \ +%endif +%else + --with-address-sanitizer=no \ + --enable-undefined-sanitizer=no \ +%endif +%if %{with debug} + --enable-more-logging=yes \ + --with-more-asserts=10000 \ +%else + --enable-more-logging=no \ + --with-more-asserts=0 \ +%endif + --enable-ld-gc=yes \ +%if %{with lto} + --enable-lto=yes \ +%else + --enable-lto=no \ +%endif + --with-libaudit=yes-disabled-by-default \ +%if 0%{?with_modem_manager_1} + --with-modem-manager-1=yes \ +%else + --with-modem-manager-1=no \ +%endif +%if %{with wifi} + --enable-wifi=yes \ +%if 0%{?fedora} + --with-wext=yes \ +%else + --with-wext=no \ +%endif +%else + --enable-wifi=no \ +%endif +%if %{with iwd} + --with-iwd=yes \ +%else + --with-iwd=no \ +%endif +%if %{with bluetooth} + --enable-bluez5-dun=yes \ +%else + --enable-bluez5-dun=no \ +%endif +%if %{with nmtui} + --with-nmtui=yes \ +%else + --with-nmtui=no \ +%endif +%if %{with nm_cloud_setup} + --with-nm-cloud-setup=yes \ +%else + --with-nm-cloud-setup=no \ +%endif + --enable-vala=yes \ + --enable-introspection=yes \ +%if %{with regen_docs} + --enable-gtk-doc=yes \ +%else + --enable-gtk-doc=no \ +%endif +%if %{with team} + --enable-teamdctl=yes \ +%else + --enable-teamdctl=no \ +%endif +%if %{with ovs} + --enable-ovs=yes \ +%else + --enable-ovs=no \ +%endif + --with-selinux=yes \ + --enable-polkit=yes \ + --enable-modify-system=yes \ + --enable-concheck=yes \ +%if 0%{?fedora} + --with-libpsl=yes \ +%else + --with-libpsl=no \ +%endif + --with-ebpf=%{ebpf_enabled} \ + --with-session-tracking=systemd \ + --with-suspend-resume=systemd \ + --with-systemdsystemunitdir=%{_unitdir} \ + --with-system-ca-path=/etc/pki/tls/cert.pem \ + --with-dbus-sys-dir=%{dbus_sys_dir} \ + --with-tests=yes \ +%if %{with test} + --enable-more-warnings=error \ +%else + --enable-more-warnings=yes \ +%endif + --with-valgrind=no \ +%if %{?with_ifcfg_rh} + --enable-ifcfg-rh=yes \ +%else + --enable-ifcfg-rh=no \ +%endif + --enable-ifupdown=no \ +%if %{with ppp} + --enable-ppp=yes \ + --with-pppd="%{_sbindir}/pppd" \ + --with-pppd-plugin-dir="%{_libdir}/pppd/%{ppp_version}" \ +%else + --enable-ppp=no \ +%endif +%if %{with firewalld_zone} + --enable-firewalld-zone=yes \ +%else + --enable-firewalld-zone=no \ +%endif + --with-dist-version=%{version}-%{release} \ +%if %{?config_plugins_default_ifcfg_rh} + --with-config-plugins-default=ifcfg-rh \ +%endif +%if %{?ifcfg_migrate} + --with-config-migrate-ifcfg-rh-default=yes \ +%endif + --with-resolvconf=no \ + --with-netconfig=no \ + --with-config-dns-rc-manager-default=%{dns_rc_manager_default} \ + --with-config-logging-backend-default=%{logging_backend_default} + +%make_build + +%endif + +%install +%if %{with meson} +%meson_install +%else +%make_install +%endif + +cp %{SOURCE1} %{buildroot}%{_sysconfdir}/%{name}/ + +cp %{SOURCE2} %{buildroot}%{nmlibdir}/conf.d/ + +%if %{with connectivity_fedora} +cp %{SOURCE4} %{buildroot}%{nmlibdir}/conf.d/ +%endif + +%if %{with connectivity_redhat} +cp %{SOURCE5} %{buildroot}%{nmlibdir}/conf.d/ +mkdir -p %{buildroot}%{_sysctldir} +cp %{SOURCE7} %{buildroot}%{_sysctldir} +%endif + +%if 0%{?fedora} >= 40 +cp %{SOURCE6} %{buildroot}%{nmlibdir}/conf.d/ +%endif + +%if 0%{?ifcfg_warning} +cp %{SOURCE8} %{buildroot}%{_sysconfdir}/sysconfig/network-scripts +%endif +%if 0%{?ifcfg_migrate} +cp %{SOURCE9} %{buildroot}%{_sysconfdir}/sysconfig/network-scripts/readme-ifcfg-rh.txt +%endif + +%if %{?with_ifcfg_rh} +cp examples/dispatcher/10-ifcfg-rh-routes.sh %{buildroot}%{nmlibdir}/dispatcher.d/ +ln -s ../no-wait.d/10-ifcfg-rh-routes.sh %{buildroot}%{nmlibdir}/dispatcher.d/pre-up.d/ +ln -s ../10-ifcfg-rh-routes.sh %{buildroot}%{nmlibdir}/dispatcher.d/no-wait.d/ +%endif + +%find_lang %{name} + +rm -f %{buildroot}%{_libdir}/*.la +rm -f %{buildroot}%{_libdir}/pppd/%{ppp_version}/*.la +rm -f %{buildroot}%{nmplugindir}/*.la + +# Ensure the documentation timestamps are constant to avoid multilib conflicts +find %{buildroot}%{_datadir}/gtk-doc -exec touch --reference configure.ac '{}' \+ + +%if 0%{?__debug_package} && ! 0%{?flatpak} +mkdir -p %{buildroot}%{_prefix}/src/debug/NetworkManager-%{real_version} +cp valgrind.suppressions %{buildroot}%{_prefix}/src/debug/NetworkManager-%{real_version} +%endif + +%if %{?with_ifcfg_rh} +touch %{buildroot}%{_sbindir}/ifup +touch %{buildroot}%{_sbindir}/ifdown +%endif + +%check +%if %{with meson} +%if %{with test} +%meson_test +%else +%ninja_test -C %{_vpath_builddir} || : +%endif +%else +# autotools +%if %{with test} +make -k %{?_smp_mflags} check +%else +make -k %{?_smp_mflags} check || : +%endif +%endif + + +%pre +if [ -f "%{_unitdir}/network-online.target.wants/NetworkManager-wait-online.service" ] ; then + # older versions used to install this file, effectively always enabling + # NetworkManager-wait-online.service. We no longer do that and rely on + # preset. + # But on package upgrade we must explicitly enable it (rh#1455704). + systemctl enable NetworkManager-wait-online.service || : +fi + + +%post +# skip triggering if udevd isn't even accessible, e.g. containers or +# rpm-ostree-based systems +if [ -S /run/udev/control ]; then + /usr/bin/udevadm control --reload-rules || : + /usr/bin/udevadm trigger --subsystem-match=net || : +fi +%if %{with firewalld_zone} +%firewalld_reload +%endif + +%systemd_post %{systemd_units} + + +%if %{?with_ifcfg_rh} +%post initscripts-updown +if [ -f %{_sbindir}/ifup -a ! -L %{_sbindir}/ifup ]; then + # initscripts package too old, won't let us set an alternative + /usr/sbin/update-alternatives --remove ifup %{_libexecdir}/nm-ifup >/dev/null 2>&1 || : +else + /usr/sbin/update-alternatives --install %{_sbindir}/ifup ifup %{_libexecdir}/nm-ifup 50 \ + --slave %{_sbindir}/ifdown ifdown %{_libexecdir}/nm-ifdown +fi +%endif + + +%if %{with nm_cloud_setup} +%post cloud-setup +%systemd_post %{systemd_units_cloud_setup} +%endif + + +%preun +if [ $1 -eq 0 ]; then + # Package removal, not upgrade + /bin/systemctl --no-reload disable NetworkManager.service >/dev/null 2>&1 || : + + # Don't kill networking entirely just on package remove + #/bin/systemctl stop NetworkManager.service >/dev/null 2>&1 || : +fi +%systemd_preun NetworkManager-wait-online.service NetworkManager-dispatcher.service nm-priv-helper.service + + +%if %{?with_ifcfg_rh} +%preun initscripts-updown +if [ $1 -eq 0 ]; then + /usr/sbin/update-alternatives --remove ifup %{_libexecdir}/nm-ifup >/dev/null 2>&1 || : +fi +%endif + + +%if %{with nm_cloud_setup} +%preun cloud-setup +%systemd_preun %{systemd_units_cloud_setup} +%endif + + +%postun +/usr/bin/udevadm control --reload-rules || : +/usr/bin/udevadm trigger --subsystem-match=net || : +%if %{with firewalld_zone} +%firewalld_reload +%endif + +%systemd_postun %{systemd_units} + + +%if (0%{?fedora} && 0%{?fedora} < 28) || 0%{?rhel} +%post libnm -p /sbin/ldconfig +%postun libnm -p /sbin/ldconfig +%endif + + +%if %{with nm_cloud_setup} +%postun cloud-setup +%systemd_postun %{systemd_units_cloud_setup} +%endif + + +%files +%{dbus_sys_dir}/org.freedesktop.NetworkManager.conf +%{dbus_sys_dir}/nm-dispatcher.conf +%{dbus_sys_dir}/nm-priv-helper.conf +%if %{?with_ifcfg_rh} && 0%{?split_ifcfg_rh} == 0 +%{dbus_sys_dir}/nm-ifcfg-rh.conf +%endif +%{_sbindir}/%{name} +%{_bindir}/nmcli +%{_datadir}/bash-completion/completions/nmcli +%dir %{_sysconfdir}/%{name} +%dir %{_sysconfdir}/%{name}/conf.d +%dir %{_sysconfdir}/%{name}/dispatcher.d +%dir %{_sysconfdir}/%{name}/dispatcher.d/pre-down.d +%dir %{_sysconfdir}/%{name}/dispatcher.d/pre-up.d +%dir %{_sysconfdir}/%{name}/dispatcher.d/no-wait.d +%dir %{_sysconfdir}/%{name}/dnsmasq.d +%dir %{_sysconfdir}/%{name}/dnsmasq-shared.d +%dir %{_sysconfdir}/%{name}/system-connections +%config(noreplace) %{_sysconfdir}/%{name}/NetworkManager.conf +%if 0%{?fedora} >= 40 +%{nmlibdir}/conf.d/22-wifi-mac-addr.conf +%endif +%ghost %{_sysconfdir}/%{name}/VPN +%{_bindir}/nm-online +%{_libexecdir}/nm-dhcp-helper +%{_libexecdir}/nm-dispatcher +%{_libexecdir}/nm-initrd-generator +%{_libexecdir}/nm-daemon-helper +%{_libexecdir}/nm-priv-helper +%dir %{_libdir}/%{name} +%dir %{nmplugindir} +%if %{?with_ifcfg_rh} && 0%{?split_ifcfg_rh} == 0 +%{nmplugindir}/libnm-settings-plugin-ifcfg-rh.so +%endif +%if %{with nmtui} +%exclude %{_mandir}/man1/nmtui* +%endif +%dir %{nmlibdir} +%dir %{nmlibdir}/conf.d +%dir %{nmlibdir}/dispatcher.d +%dir %{nmlibdir}/dispatcher.d/pre-down.d +%dir %{nmlibdir}/dispatcher.d/pre-up.d +%dir %{nmlibdir}/dispatcher.d/no-wait.d +%dir %{nmlibdir}/VPN +%dir %{nmlibdir}/system-connections +%{_mandir}/man1/* +%{_mandir}/man5/* +%{_mandir}/man7/nmcli-examples.7* +%{_mandir}/man8/nm-initrd-generator.8* +%{_mandir}/man8/NetworkManager.8* +%{_mandir}/man8/NetworkManager-dispatcher.8* +%{_mandir}/man8/NetworkManager-wait-online.service.8* +%dir %{_localstatedir}/lib/NetworkManager +%if %{?with_ifcfg_rh} +%dir %{_sysconfdir}/sysconfig/network-scripts +%endif +%{_datadir}/dbus-1/system-services/org.freedesktop.nm_dispatcher.service +%{_datadir}/dbus-1/system-services/org.freedesktop.nm_priv_helper.service +%{_datadir}/polkit-1/actions/*.policy +%{_prefix}/lib/udev/rules.d/*.rules +%if %{with firewalld_zone} +%{_prefix}/lib/firewalld/zones/nm-shared.xml +%endif +# systemd stuff +%{_unitdir}/NetworkManager.service +%{_unitdir}/NetworkManager-wait-online.service +%{_unitdir}/NetworkManager-dispatcher.service +%{_unitdir}/nm-priv-helper.service +%dir %{_datadir}/doc/NetworkManager/examples +%{_datadir}/doc/NetworkManager/examples/server.conf +%if 0%{?ifcfg_warning} || 0%{?ifcfg_migrate} +%{_sysconfdir}/sysconfig/network-scripts/readme-ifcfg-rh.txt +%endif +%doc NEWS AUTHORS README.md CONTRIBUTING.md +%license COPYING +%license COPYING.LGPL +%license COPYING.GFDL + + +%if %{with adsl} +%files adsl +%{nmplugindir}/libnm-device-plugin-adsl.so +%else +%exclude %{nmplugindir}/libnm-device-plugin-adsl.so +%endif + + +%if %{with bluetooth} +%files bluetooth +%{nmplugindir}/libnm-device-plugin-bluetooth.so +%endif + + +%if %{with team} +%files team +%{nmplugindir}/libnm-device-plugin-team.so +%endif + + +%if %{with wifi} +%files wifi +%{nmplugindir}/libnm-device-plugin-wifi.so +%endif + + +%if %{with wwan} +%files wwan +%{nmplugindir}/libnm-device-plugin-wwan.so +%{nmplugindir}/libnm-wwan.so +%endif + + +%if %{with ovs} +%files ovs +%{nmplugindir}/libnm-device-plugin-ovs.so +%{_unitdir}/NetworkManager.service.d/NetworkManager-ovs.conf +%{_mandir}/man7/nm-openvswitch.7* +%endif + + +%if %{with ppp} +%files ppp +%{_libdir}/pppd/%{ppp_version}/nm-pppd-plugin.so +%{nmplugindir}/libnm-ppp-plugin.so +%endif + + +%files libnm -f %{name}.lang +%{_libdir}/libnm.so.* +%{_libdir}/girepository-1.0/NM-1.0.typelib + + +%files libnm-devel +%dir %{_includedir}/libnm +%{_includedir}/libnm/*.h +%{_libdir}/pkgconfig/libnm.pc +%{_libdir}/libnm.so +%{_datadir}/gir-1.0/NM-1.0.gir +%dir %{_datadir}/gtk-doc/html/libnm +%{_datadir}/gtk-doc/html/libnm/* +%dir %{_datadir}/gtk-doc/html/NetworkManager +%{_datadir}/gtk-doc/html/NetworkManager/* +%{_datadir}/vala/vapi/libnm.deps +%{_datadir}/vala/vapi/libnm.vapi +%{_datadir}/dbus-1/interfaces/*.xml + + +%if %{with connectivity_fedora} +%files config-connectivity-fedora +%dir %{nmlibdir} +%dir %{nmlibdir}/conf.d +%{nmlibdir}/conf.d/20-connectivity-fedora.conf +%endif + + +%if %{with connectivity_redhat} +%files config-connectivity-redhat +%dir %{nmlibdir} +%dir %{nmlibdir}/conf.d +%{nmlibdir}/conf.d/20-connectivity-redhat.conf +%{_sysctldir}/70-nm-connectivity.conf +%endif + + +%files config-server +%dir %{nmlibdir} +%dir %{nmlibdir}/conf.d +%{nmlibdir}/conf.d/00-server.conf + + +%if %{?with_ifcfg_rh} +%files dispatcher-routing-rules +%{nmlibdir}/dispatcher.d/10-ifcfg-rh-routes.sh +%{nmlibdir}/dispatcher.d/no-wait.d/10-ifcfg-rh-routes.sh +%{nmlibdir}/dispatcher.d/pre-up.d/10-ifcfg-rh-routes.sh +%endif + +%if %{with nmtui} +%files tui +%{_bindir}/nmtui +%{_bindir}/nmtui-edit +%{_bindir}/nmtui-connect +%{_bindir}/nmtui-hostname +%{_mandir}/man1/nmtui* +%endif + + +%if 0%{?split_ifcfg_rh} +%files initscripts-ifcfg-rh +%{nmplugindir}/libnm-settings-plugin-ifcfg-rh.so +%{dbus_sys_dir}/nm-ifcfg-rh.conf +%endif + + +%if %{with nm_cloud_setup} +%files cloud-setup +%{_libexecdir}/nm-cloud-setup +%{_unitdir}/nm-cloud-setup.service +%{_unitdir}/nm-cloud-setup.timer +%{nmlibdir}/dispatcher.d/90-nm-cloud-setup.sh +%{nmlibdir}/dispatcher.d/no-wait.d/90-nm-cloud-setup.sh +%{nmlibdir}/dispatcher.d/pre-up.d/90-nm-cloud-setup.sh +%{_mandir}/man8/nm-cloud-setup.8* +%endif + + +%if %{?with_ifcfg_rh} +%files initscripts-updown +%{_libexecdir}/nm-ifup +%ghost %attr(755, root, root) %{_sbindir}/ifup +%{_libexecdir}/nm-ifdown +%ghost %attr(755, root, root) %{_sbindir}/ifdown +%endif + + +%changelog +__CHANGELOG__ diff --git a/contrib/fedora/rpm/README b/contrib/fedora/rpm/README new file mode 100644 index 00000000..7982a1ef --- /dev/null +++ b/contrib/fedora/rpm/README @@ -0,0 +1,27 @@ +# To build RPM packages for Fedora derivates directly from git, just do: + + +# +# preparation: +# +git clone https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git +cd NetworkManager +git checkout $WHATEVER +./contrib/fedora/REQUIRED_PACKAGES + + +# +# build the packages. Pass --help for usage help. +# +./contrib/fedora/rpm/build_clean.sh + + +# +# install +# +sudo dnf install ./contrib/fedora/rpm/latest/RPMS/x86_64/*rpm + + + +# To generate a clean build from git using mock, run: +./contrib/fedora/rpm/mockbuild.sh diff --git a/contrib/fedora/rpm/build.sh b/contrib/fedora/rpm/build.sh new file mode 100755 index 00000000..8160b915 --- /dev/null +++ b/contrib/fedora/rpm/build.sh @@ -0,0 +1,288 @@ +#!/bin/bash + +#set -vx + +# Set arguments via environment variables. +# Argument can be omitted and defaults will be detected. +# +# BUILDTYPE=|SRPM +# NM_RPMBUILD_ARGS=<additional argus for rpmbuild> +# RELEASE_VERSION= +# SNAPSHOT= +# VERSION= +# COMMIT_FULL= +# COMMIT= +# USERNAME= +# SPECFILE= +# SOURCE=<path> +# SOURCE_FROM_GIT=|1|0 +# SOURCE_NETWORKMANAGER_CONF= +# SOURCE_CONFIG_SERVER= +# SOURCE_CONFIG_CONNECTIVITY_FEDORA= +# SOURCE_CONFIG_CONNECTIVITY_REDHAT= +# SOURCE_SYSCTL_RP_FILTER_REDHAT= +# SOURCE_README_IFCFG_FILES= +# SOURCE_README_IFCFG_MIGRATED= +# SIGN_SOURCE= +# DO_RELEASE= +# BCOND_DEFAULT_DEBUG= +# BCOND_DEFAULT_LTO= +# BCOND_DEFAULT_TEST= + +die() { + echo "$*" >&2 + exit 1 +} + +# copy output also to logfile +LOG() { + echo "$*" +} + +coerce_bool() { + case "$1" in + no|n|NO|N|0) + echo 0 + ;; + yes|y|YES|Y|1) + echo 1 + ;; + "") + printf '%s' "$2" + ;; + esac +} + +in_set() { + local v="$1" + shift + for v2; do + test "$v" = "$v2" && return 0 + done + return 1 +} + +abs_path() { + local F="$1" + + if [[ "$F" != "" ]]; then + F="$(cd "$ORIGDIR" && readlink -f "$F")" || exit 55 + [[ -f "$F" ]] || exit 55 + else + F="$2" + fi + printf '%s' "$F" + exit 0 +} + +get_version() { + local major minor micro + local F="${1:-"$GITDIR/configure.ac"}" + + vars="$(sed -n 's/^m4_define(\[nm_\(major\|minor\|micro\)_version\], *\[\([0-9]\+\)\]) *$/local \1='\''\2'\''/p' "$F" 2>/dev/null)" + eval "$vars" + + [[ -n "$major" && -n "$minor" && "$micro" ]] || return 1 + echo "$major.$minor.$micro" +} + +write_changelog() { + if [[ "x$CHANGELOG" == x ]]; then + cat <<- EOF + * $(LC_TIME=C date '+%a %b %d %Y') $USERNAME - %{epoch_version}:%{version}-%{release_version}%{?snap} + - build of NetworkManager ($DATE, uuid: $UUID, git: $COMMIT_FULL) + $(git log -n20 --date=local --format='- %h %s [%an] (%ci)') + - ... + EOF + else + echo "$CHANGELOG" + fi > "$TEMP/SOURCES/CHANGELOG" +} + +ORIGDIR="$(readlink -f "$PWD")" +SCRIPTDIR="$(dirname "$(readlink -f "$0")")" +LOG "Change to directory \"$SCRIPTDIR\"" +cd "$SCRIPTDIR" || die "could not change into $SCRIPTDIR" +GITDIR="$(cd "$SCRIPTDIR" && git rev-parse --show-toplevel || die "Could not get GITDIR")" + +DATE="$(date '+%Y%m%d-%H%M%S')" + +BUILDLOG="$(mktemp ./.build.log.XXXXXXX)" +chmod +r "$BUILDLOG" + +exec > >(tee "$BUILDLOG") +exec 2>&1 + +UUID=`uuidgen` +RELEASE_VERSION="${RELEASE_VERSION:-$(git rev-list HEAD | wc -l)}" +SNAPSHOT="${SNAPSHOT:-%{nil\}}" +VERSION="${VERSION:-$(get_version || die "Could not read $VERSION")}" +COMMIT_FULL="${COMMIT_FULL:-$(git rev-parse --verify HEAD || die "Error reading HEAD revision")}" +COMMIT="${COMMIT:-$(printf '%s' "$COMMIT_FULL" | sed 's/^\(.\{10\}\).*/\1/' || die "Error reading HEAD revision")}" +BCOND_DEFAULT_DEBUG="${BCOND_DEFAULT_DEBUG:-0}" +BCOND_DEFAULT_TEST="${BCOND_DEFAULT_TEST:-0}" +BCOND_DEFAULT_LTO="${BCOND_DEFAULT_LTO}" +USERNAME="${USERNAME:-"$(git config user.name) <$(git config user.email)>"}" +SPECFILE="$(abs_path "$SPECFILE" "$SCRIPTDIR/NetworkManager.spec")" || die "invalid \$SPECFILE argument" +SOURCE_FROM_GIT="$(coerce_bool "$SOURCE_FROM_GIT" "")" +SOURCE="$(abs_path "$SOURCE")" || die "invalid \$SOURCE argument" +DO_RELEASE="$(coerce_bool "$DO_RELEASE" "0")" +SIGN_SOURCE="$(coerce_bool "$SIGN_SOURCE" "$DO_RELEASE")" +if [ -n "$SOURCE" ]; then + [[ "$SOURCE_FROM_GIT" == 1 ]] && die "Cannot set both \$SOURCE and \$SOURCE_FROM_GIT=1" + SOURCE_FROM_GIT=0 +elif [[ "$SOURCE_FROM_GIT" != "1" ]]; then + SOURCE="$(ls -1 "$GITDIR/NetworkManager-${VERSION}.tar."* 2>/dev/null | head -n1)" + if [[ -z "$SOURCE" ]]; then + [[ "$SOURCE_FROM_GIT" == "0" ]] && die "Either set \$SOURCE or set \$SOURCE_FROM_GIT=1" + SOURCE_FROM_GIT=1 + else + SOURCE_FROM_GIT=0 + fi +fi + +SOURCE_NETWORKMANAGER_CONF="$(abs_path "$SOURCE_NETWORKMANAGER_CONF" "$SCRIPTDIR/NetworkManager.conf")" || die "invalid \$SOURCE_NETWORKMANAGER_CONF argument" +SOURCE_CONFIG_SERVER="$(abs_path "$SOURCE_CONFIG_SERVER" "$SCRIPTDIR/00-server.conf")" || die "invalid \$SOURCE_CONFIG_SERVER argument" +SOURCE_CONFIG_CONNECTIVITY_FEDORA="$(abs_path "$SOURCE_CONFIG_CONNECTIVITY_FEDORA" "$SCRIPTDIR/20-connectivity-fedora.conf")" || die "invalid \$SOURCE_CONFIG_CONNECTIVITY_FEDORA argument" +SOURCE_CONFIG_CONNECTIVITY_REDHAT="$(abs_path "$SOURCE_CONFIG_CONNECTIVITY_REDHAT" "$SCRIPTDIR/20-connectivity-redhat.conf")" || die "invalid \$SOURCE_CONFIG_CONNECTIVITY_REDHAT argument" +SOURCE_CONFIG_WIFI_MAC_ADDR="$(abs_path "$SOURCE_CONFIG_WIFI_MAC_ADDR" "$SCRIPTDIR/22-wifi-mac-addr.conf")" || die "invalid \$SOURCE_CONFIG_WIFI_MAC_ADDR argument" +SOURCE_SYSCTL_RP_FILTER_REDHAT="$(abs_path "$SOURCE_SYSCTL_RP_FILTER_REDHAT" "$SCRIPTDIR/70-nm-connectivity.conf")" || die "invalid \$SOURCE_SYSCTL_RP_FILTER_REDHAT argument" +SOURCE_README_IFCFG_FILES="$(abs_path "$SOURCE_README_IFCFG_FILES" "$SCRIPTDIR/readme-ifcfg-rh.txt")" || die "invalid \$SOURCE_README_IFCFG_FILES argument" +SOURCE_README_IFCFG_MIGRATED="$(abs_path "$SOURCE_README_IFCFG_MIGRATED" "$SCRIPTDIR/readme-ifcfg-rh-migrated.txt")" || die "invalid \$SOURCE_README_IFCFG_MIGRATED argument" + +TEMP="$(mktemp -d "$SCRIPTDIR/NetworkManager.$DATE.XXXXXX")" +TEMPBASE="$(basename "$TEMP")" + +if [[ "$SOURCE_FROM_GIT" == "1" ]]; then + mkdir -p "$TEMP/SOURCES" + SOURCE="$TEMP/SOURCES/NetworkManager-${VERSION}.tar.xz" + (cd "$GITDIR" && git archive --prefix="NetworkManager-$VERSION"/ "$COMMIT_FULL") | xz > "$SOURCE" +fi + +LOG "VERSION=$VERSION" +LOG "RELEASE_VERSION=$RELEASE_VERSION" +LOG "SNAPSHOT=$SNAPSHOT" +LOG "COMMIT_FULL=$COMMIT_FULL" +LOG "COMMIT=$COMMIT" +LOG "USERNAME=$USERNAME" +LOG "SPECFILE=$SPECFILE" +LOG "SOURCE=$SOURCE" +LOG "SIGN_SOURCE=$SIGN_SOURCE" +LOG "DO_RELEASE=$DO_RELEASE" +LOG "SOURCE_FROM_GIT=$SOURCE_FROM_GIT" +LOG "SOURCE_NETWORKMANAGER_CONF=$SOURCE_NETWORKMANAGER_CONF" +LOG "SOURCE_CONFIG_SERVER=$SOURCE_CONFIG_SERVER" +LOG "SOURCE_CONFIG_CONNECTIVITY_FEDORA=$SOURCE_CONFIG_CONNECTIVITY_FEDORA" +LOG "SOURCE_CONFIG_CONNECTIVITY_REDHAT=$SOURCE_CONFIG_CONNECTIVITY_REDHAT" +LOG "SOURCE_SYSCTL_RP_FILTER_REDHAT=$SOURCE_SYSCTL_RP_FILTER_REDHAT" +LOG "SOURCE_README_IFCFG_FILES=$SOURCE_README_IFCFG_FILES" +LOG "SOURCE_README_IFCFG_MIGRATED=$SOURCE_README_IFCFG_MIGRATED" +LOG "BUILDTYPE=$BUILDTYPE" +LOG "NM_RPMBUILD_ARGS=$NM_RPMBUILD_ARGS" +LOG "BCOND_DEFAULT_DEBUG=$BCOND_DEFAULT_DEBUG" +LOG "BCOND_DEFAULT_LTO=$BCOND_DEFAULT_LTO" +LOG "BCOND_DEFAULT_TEST=$BCOND_DEFAULT_TEST" +LOG "" +LOG "UUID=$UUID" +LOG "BASEDIR=$TEMP" + +in_set "$BCOND_DEFAULT_DEBUG" 0 1 || die "Invalid value for \$BCOND_DEFAULT_DEBUG: \"$BCOND_DEFAULT_DEBUG\"" +in_set "$BCOND_DEFAULT_LTO" '' 0 1 || die "Invalid value for \$BCOND_DEFAULT_LTO: \"$BCOND_DEFAULT_LTO\"" +in_set "$BCOND_DEFAULT_TEST" 0 1 || die "Invalid value for \$BCOND_DEFAULT_TEST: \"$BCOND_DEFAULT_TEST\"" + +ln -snf "$TEMPBASE" ./latest0 +ln "$BUILDLOG" "$TEMPBASE/build.log" +rm -f "$BUILDLOG" + +TEMPSPEC="$TEMP/SPECS/NetworkManager.spec" +mkdir -p "$TEMP/SOURCES/" "$TEMP/SPECS/" || die "error creating SPECS directory" + +if [[ "$(dirname "$SOURCE")" != "$TEMP/SOURCES" ]]; then + cp "$SOURCE" "$TEMP/SOURCES/" || die "Could not copy source $SOURCE to $TEMP/SOURCES" +fi +cp "$SOURCE_NETWORKMANAGER_CONF" "$TEMP/SOURCES/NetworkManager.conf" || die "Could not copy source $SOURCE_NETWORKMANAGER_CONF to $TEMP/SOURCES" +cp "$SOURCE_CONFIG_SERVER" "$TEMP/SOURCES/00-server.conf" || die "Could not copy source $SOURCE_CONFIG_SERVER to $TEMP/SOURCES" +cp "$SOURCE_CONFIG_CONNECTIVITY_FEDORA" "$TEMP/SOURCES/20-connectivity-fedora.conf" || die "Could not copy source $SOURCE_CONFIG_CONNECTIVITY_FEDORA to $TEMP/SOURCES" +cp "$SOURCE_CONFIG_CONNECTIVITY_REDHAT" "$TEMP/SOURCES/20-connectivity-redhat.conf" || die "Could not copy source $SOURCE_CONFIG_CONNECTIVITY_REDHAT to $TEMP/SOURCES" +cp "$SOURCE_CONFIG_WIFI_MAC_ADDR" "$TEMP/SOURCES/22-wifi-mac-addr.conf" || die "Could not copy source $SOURCE_CONFIG_WIFI_MAC_ADDR to $TEMP/SOURCES" +cp "$SOURCE_SYSCTL_RP_FILTER_REDHAT" "$TEMP/SOURCES/70-nm-connectivity.conf" || die "Could not copy source $SOURCE_SYSCTL_RP_FILTER_REDHAT to $TEMP/SOURCES" +cp "$SOURCE_README_IFCFG_FILES" "$TEMP/SOURCES/readme-ifcfg-rh.txt" || die "Could not copy source $SOURCE_README_IFCFG_FILES to $TEMP/SOURCES" +cp "$SOURCE_README_IFCFG_MIGRATED" "$TEMP/SOURCES/readme-ifcfg-rh-migrated.txt" || die "Could not copy source $SOURCE_README_IFCFG_MIGRATED to $TEMP/SOURCES" + +write_changelog + +sed -e "s/__VERSION__/$VERSION/g" \ + -e "s/__RELEASE_VERSION__/$RELEASE_VERSION/g" \ + -e "s/__SNAPSHOT__/$SNAPSHOT/g" \ + -e "s/__COMMIT__/$COMMIT/g" \ + -e "s/__COMMIT_FULL__/$COMMIT_FULL/g" \ + -e "s/__SNAPSHOT__/$SNAPSHOT/g" \ + -e "s/__SOURCE1__/$(basename "$SOURCE")/g" \ + -e "s/__BCOND_DEFAULT_DEBUG__/$BCOND_DEFAULT_DEBUG/g" \ + -e "s/__BCOND_DEFAULT_LTO__/${BCOND_DEFAULT_LTO:-"%{nil}"}/g" \ + -e "s/__BCOND_DEFAULT_TEST__/$BCOND_DEFAULT_TEST/g" \ + "$SPECFILE" | +sed -e "/^__CHANGELOG__$/ \ + { + r $TEMPBASE/SOURCES/CHANGELOG + d + }" > "$TEMPSPEC" || die "Error reading spec file" + +case "$BUILDTYPE" in + "SRPM") + RPM_BUILD_OPTION=-bs + ;; + *) + RPM_BUILD_OPTION=-ba + ;; +esac + +rpmbuild --define "_topdir $TEMP" $RPM_BUILD_OPTION "$TEMPSPEC" $NM_RPMBUILD_ARGS || die "ERROR: rpmbuild FAILED" + +LS_EXTRA=() + +if [ "$SIGN_SOURCE" = 1 ]; then + SIGNKEY="$(git config --get user.signingkey)" + if [ "$SIGNKEY" != "" ]; then + SIGNKEY="--local-user $(printf '%q' "$SIGNKEY")" + fi + gpg $SIGNKEY --output "$SOURCE.sig" --armor --detach-sig "$SOURCE" || die "ERROR: failure to sign $SOURCE" + LS_EXTRA+=("$SOURCE.sig") +fi + +ln -snf "$TEMPBASE" ./latest +TEMP_LATEST="$(readlink -f .)"/latest + +LOG +LOG +LOG "Finished with success." +LOG +LOG "See \"$TEMP_LATEST/\" which symlinks to \"$TEMPBASE\"" +LOG +LOG "Result:" +ls -dla \ + "$TEMP_LATEST" \ + "$SOURCE" \ + "${LS_EXTRA[@]}" \ + "$(dirname "$TEMP_LATEST")/$TEMPBASE/" \ + "$TEMP_LATEST"/RPMS/*/ \ + "$TEMP_LATEST"/RPMS/*/*.rpm \ + "$TEMP_LATEST"/SRPMS/ \ + "$TEMP_LATEST"/SRPMS/*.rpm \ + 2>/dev/null | sed 's/^/ /' +LOG +if [[ "$BUILDTYPE" == "SRPM" ]]; then + LOG sudo $(command -v dnf &>/dev/null && echo dnf builddep || echo yum-builddep) $TEMP_LATEST/SRPMS/*.src.rpm + LOG +else + LOG "sudo $(command -v dnf &>/dev/null && echo dnf || echo yum) install '$TEMP_LATEST/RPMS'/*/*.rpm" + LOG +fi + +if [[ "$DO_RELEASE" == 1 ]]; then + LOG "RELEASE \"$SOURCE\" :" + for c in md5 sha1 sha256 sha512; do + LOG "$(printf '%8s: %s' "$c" $("${c}sum" "$SOURCE" | sed 's/ .*//'))" + done + LOG +fi diff --git a/contrib/fedora/rpm/build_clean.sh b/contrib/fedora/rpm/build_clean.sh new file mode 100755 index 00000000..d06d4341 --- /dev/null +++ b/contrib/fedora/rpm/build_clean.sh @@ -0,0 +1,303 @@ +#!/bin/bash + + +die() { + echo "$*" >&2 + exit 1 +} + +usage() { + echo "USAGE: $0 [-h|--help|-?|help] [-f|--force] [-c|--clean] [-S|--srpm] [-g|--git] [-Q|--quick] [-N|--no-dist] [[-w|--with OPTION] ...] [[-W|--without OPTION] ...]" + echo + echo "Does all the steps from a clean git working directory to an RPM of NetworkManager" + echo + echo "This is also the preferred way to create a distribution tarball for release:" + echo " $ $0 -r" + echo + echo "Options:" + echo " -f|--force: force build, even if working directory is not clean and has local modifications" + echo " -c|--clean: run \`git-clean -fdx :/\` before build" + echo " -S|--srpm: only build the SRPM" + echo " -g|--git: create tarball from current git HEAD (skips make dist)" + echo " -Q|--quick: only create the distribution tarball, without running checks" + echo " -N|--no-dist: skip creating the source tarball if you already did \`make dist\`" + echo " -m|--meson: (default) use meson to create the source tarball" + echo " -A|--autotools: use autotools to create the source tarball" + echo " -w|--with \$OPTION: pass --with \$OPTION to rpmbuild. For example --with debug" + echo " -W|--without \$OPTION: pass --without \$OPTION to rpmbuild. For example --without debug" + echo " -s|--snapshot TEXT: use TEXT as the snapshot version for the new package (overwrites \$NM_BUILD_SNAPSHOT environment)" + echo " -r|--release: built a release tarball (this option must be alone)" + echo " --default-for-debug \$OPTION: set the default for "debug" option in the generated spec file" + echo " --default-for-lto \$OPTION: set the default for "lto" option in the generated spec file" + echo " --default-for-test \$OPTION: set the default for "test" option in the generated spec file" +} + +in_set() { + local v="$1" + shift + for v2; do + test "$v" = "$v2" && return 0 + done + return 1 +} + +ORIGDIR="$(readlink -f "$PWD")" +SCRIPTDIR="$(dirname "$(readlink -f "$0")")" +GITDIR="$(cd "$SCRIPTDIR" && git rev-parse --show-toplevel || die "Could not get GITDIR")" + + +[[ -x "$SCRIPTDIR"/build.sh ]] || die "could not find \"$SCRIPTDIR/build.sh\"" + +cd "$GITDIR" || die "could not change to $GITDIR" + +IGNORE_DIRTY=0 +GIT_CLEAN=0 +QUICK=0 +NO_DIST=0 +WITH_LIST=() +SOURCE_FROM_GIT=0 +SNAPSHOT="$NM_BUILD_SNAPSHOT" +DO_RELEASE=0 +unset BCOND_DEFAULT_DEBUG +unset BCOND_DEFAULT_LTO +unset BCOND_DEFAULT_TEST + +ADD_WITH_TEST=1 + +NARGS=$# + +while [[ $# -gt 0 ]]; do + A="$1" + shift + case "$A" in + -h|--help|-\?|help) + usage + exit 0 + ;; + -f|--force) + IGNORE_DIRTY=1 + ;; + -r|--release) + [[ $NARGS -eq 1 ]] || die "--release option must be alone" + export NMTST_CHECK_GTK_DOC=1 + BUILDTYPE=SRPM + DO_RELEASE=1 + ;; + -c|--clean) + GIT_CLEAN=1 + ;; + -S|--srpm) + BUILDTYPE=SRPM + ;; + -s|--snapshot) + [[ $# -gt 0 ]] || die "Missing argument to $A" + SNAPSHOT="$1" + shift + ;; + -g|--git) + NO_DIST=1 + IGNORE_DIRTY=1 + SOURCE_FROM_GIT=1 + ;; + -m|--meson) + [ "$USE_AUTOTOOLS" = 1 ] && die "conflicting argument: $A when building with autotools is requested"; + USE_MESON=1 + ;; + -A|--autotools) + [ "$USE_MESON" = 1 ] && die "conflicting argument: $A when building with meson is explicitly requested"; + USE_AUTOTOOLS=1 + ;; + -Q|--quick) + QUICK=1 + ;; + -N|--no-dist) + NO_DIST=1 + IGNORE_DIRTY=1 + SOURCE_FROM_GIT=0 + ;; + -w|--with) + [[ $# -gt 0 ]] || die "Missing argument to $A" + WITH_LIST=("${WITH_LIST[@]}" "--with" "$1") + case "$1" in + debug) + [[ -z ${BCOND_DEFAULT_DEBUG+.} ]] && BCOND_DEFAULT_DEBUG=1 + ;; + lto) + [[ -z ${BCOND_DEFAULT_LTO+.} ]] && BCOND_DEFAULT_LTO=1 + ;; + test) + ADD_WITH_TEST=0 + [[ -z ${BCOND_DEFAULT_TEST+.} ]] && BCOND_DEFAULT_TEST=1 + ;; + esac + shift + ;; + -W|--without) + [[ $# -gt 0 ]] || die "Missing argument to $A" + WITH_LIST=("${WITH_LIST[@]}" "--without" "$1") + case "$1" in + debug) + [[ -z ${BCOND_DEFAULT_DEBUG+.} ]] && BCOND_DEFAULT_DEBUG=0 + ;; + lto) + [[ -z ${BCOND_DEFAULT_LTO+.} ]] && BCOND_DEFAULT_LTO=0 + ;; + test) + ADD_WITH_TEST=0 + [[ -z ${BCOND_DEFAULT_TEST+.} ]] && BCOND_DEFAULT_TEST=0 + ;; + esac + shift + ;; + --no-auto-with-test) + # by default, the script adds "-w test" (unless the command line contains + # "-w test" or "-W test"). This flags allows to suppress that automatism. + # It's really only useful to test the spec file's internal default for the + # "test" option. Otherwise, you can always just explicitly select "-w test" + # or "-W test". + ADD_WITH_TEST=0 + ;; + --default-for-debug) + [[ $# -gt 0 ]] || die "Missing argument to $A" + in_set "$1" "" 0 1 || die "invalid argument $A \"$1\"" + BCOND_DEFAULT_DEBUG="$1" + shift + ;; + --default-for-lto) + [[ $# -gt 0 ]] || die "Missing argument to $A" + in_set "$1" "" 0 1 || die "invalid argument $A \"$1\"" + BCOND_DEFAULT_LTO="$1" + shift + ;; + --default-for-test) + [[ $# -gt 0 ]] || die "Missing argument to $A" + in_set "$1" "" 0 1 || die "invalid argument $A \"$1\"" + BCOND_DEFAULT_TEST="$1" + shift + ;; + *) + usage + die "Unexpected argument \"$A\"" + ;; + esac +done + +if [[ $GIT_CLEAN == 1 ]]; then + git clean -fdx :/ +fi + +if [[ $IGNORE_DIRTY != 1 ]]; then + # check for a clean working directory. + # We ignore the /contrib directory, because this is where the automation + # scripts and the build results will be. + if [[ "x$(LANG=C git clean -ndx | grep '^Would \(remove contrib/\|skip repository libgsystem/\).*$' -v)" != x ]]; then + die "The working directory is not clean. Refuse to run. Try \`$0 --force\`, \`$0 --clean\`, or \`git clean -e :/contrib -dx -n\`" + fi + if [[ "x$(git status --porcelain)" != x ]]; then + die "The working directory has local changes. Refuse to run. Try \`$0 --force\`" + fi +fi + +get_version_meson() { + meson introspect "$GITDIR/build" --projectinfo | jq -r .version +} + +if [[ $NO_DIST != 1 ]]; then + if [[ $USE_AUTOTOOLS != 1 ]]; then + meson setup "$GITDIR/build" \ + --prefix=/usr \ + --bindir=/usr/bin \ + --sbindir=/usr/sbin \ + --sysconfdir=/etc \ + --datadir=/usr/share \ + --includedir=/usr/include \ + --libdir=/usr/lib \ + --libexecdir=/usr/libexec \ + --localstatedir=/var \ + --sharedstatedir=/var/lib \ + --mandir=/usr/share/man \ + --infodir=/usr/share/info \ + -Ddocs=true \ + -Dintrospection=true \ + -Difcfg_rh=true \ + -Difupdown=true \ + -Dconfig_logging_backend_default=syslog \ + -Dconfig_wifi_backend_default=wpa_supplicant \ + -Dlibaudit=yes-disabled-by-default \ + -Dpolkit=true \ + -Dnm_cloud_setup=true \ + -Dconfig_dhcp_default=internal \ + -Dconfig_dns_rc_manager_default=auto \ + -Diptables=/usr/sbin/iptables \ + -Dnft=/usr/bin/nft \ + || die "Error meson setup" + + VERSION="${VERSION:-$(get_version_meson || die "Could not read $VERSION")}" + if [[ $QUICK == 1 ]]; then + meson dist --allow-dirty -C "$GITDIR/build/" --no-tests || die "Error meson dist" + else + meson dist --allow-dirty -C "$GITDIR/build/" || die "Error meson dist with tests" + fi + export SOURCE="$(ls -1 "$GITDIR/build/meson-dist/NetworkManager-${VERSION}.tar.xz" 2>/dev/null | head -n1)" + else + ./autogen.sh \ + --with-runstatedir=/run \ + --program-prefix= \ + --prefix=/usr \ + --exec-prefix=/usr \ + --bindir=/usr/bin \ + --sbindir=/usr/sbin \ + --sysconfdir=/etc \ + --datadir=/usr/share \ + --includedir=/usr/include \ + --libdir=/usr/lib \ + --libexecdir=/usr/libexec \ + --localstatedir=/var \ + --sharedstatedir=/var/lib \ + --mandir=/usr/share/man \ + --infodir=/usr/share/info \ + \ + --disable-dependency-tracking \ + --enable-gtk-doc \ + --enable-introspection \ + --enable-ifcfg-rh \ + --enable-ifupdown \ + --with-config-logging-backend-default=syslog \ + --with-config-wifi-backend-default=wpa_supplicant \ + --with-libaudit=yes-disabled-by-default \ + --enable-polkit=yes \ + --with-nm-cloud-setup=yes \ + --with-config-dhcp-default=internal \ + --with-config-dns-rc-manager-default=auto \ + \ + --with-iptables=/usr/sbin/iptables \ + --with-nft=/usr/sbin/nft \ + \ + || die "Error autogen.sh" + if [[ $QUICK == 1 ]]; then + make dist -j 7 || die "Error make dist" + else + make distcheck -j 7 || die "Error make distcheck" + fi + fi +fi + +if [[ "$ADD_WITH_TEST" == 1 ]]; then + WITH_LIST=("${WITH_LIST[@]}" "--with" "test") +fi + +if [[ "$USE_AUTOTOOLS" != 1 ]]; then + WITH_LIST=("${WITH_LIST[@]}" "--with" "meson") +fi + +export SOURCE_FROM_GIT +export BUILDTYPE +export NM_RPMBUILD_ARGS="${WITH_LIST[@]}" +export SNAPSHOT +export DO_RELEASE +export BCOND_DEFAULT_DEBUG="$BCOND_DEFAULT_DEBUG" +export BCOND_DEFAULT_LTO="$BCOND_DEFAULT_LTO" +export BCOND_DEFAULT_TEST="$BCOND_DEFAULT_TEST" + +"$SCRIPTDIR"/build.sh + diff --git a/contrib/fedora/rpm/configure-for-system.sh b/contrib/fedora/rpm/configure-for-system.sh new file mode 100755 index 00000000..acf5eb9c --- /dev/null +++ b/contrib/fedora/rpm/configure-for-system.sh @@ -0,0 +1,526 @@ +#!/bin/bash + +# Run configure/meson for NetworkManager in a way similar to how an RPM build does it. +# The effect is, that if you do `make install`, that it will overwrite the files that +# you'd usually get by installing the NetworkManager RPM. Also, it means you can afterwards +# systemctl restart NetworkManager. + +die() { + printf "%s\n" "$*" + exit 1 +} + +BASE_DIR="$(cd "$(dirname "$BASH_SOURCE")"; git rev-parse --show-toplevel)" + +cd "$BASE_DIR" || die "Cannot cd to base directory" + +vars() { + sed -e '1,/[P]VARS/!d' "$BASH_SOURCE" | sed -n 's/^'"$1"'_\([^=]*\)=.*/\1/p' +} + +vars_with_vals() { + echo "Variables:" + for v in $(vars P); do + printf " %s=%q\n" "$v" "$(eval "echo \"\$P_$v\"")" + done + echo "Directories:" + for v in $(vars D); do + printf " %s=%q\n" "$v" "$(eval "echo \"\$D_$v\"")" + done +} + +usage() { + echo "$ $0 [-m|--meson] [-a|--autotools] [-s|--show] [-B|--no-build] [-h|--help]" + echo "" + echo "Configure NetworkManager in a way that is similar to when building" + echo "RPMs of NetworkManager for Fedora/RHEL. The effect is that \`make install\`" + echo "will overwrite the files in /usr that you installed via the package management" + echo "systemd. Also, subsequent \`systemctl restart NetworkManager\` works." + echo "You don't want to do this on your real system, because it messes up your" + echo "installation" + echo + + vars_with_vals +} + +get_version() { + local major minor micro + local F="./configure.ac" + + vars="$(sed -n 's/^m4_define(\[nm_\(major\|minor\|micro\)_version\], *\[\([0-9]\+\)\]) *$/local \1='\''\2'\''/p' "$F" 2>/dev/null)" + eval "$vars" + + [[ -n "$major" && -n "$minor" && "$micro" ]] || return 1 + echo "$major.$minor.$micro" +} + +bool() { + case "$1" in + 1|y|Y|yes|Yes|YES|true|True|TRUE) + return 0 + ;; + 0|n|N|no|No|NO|false|False|FALSE) + return 1 + ;; + *) + local re='^[0-9]+$' + [[ $1 =~ $re ]] && test "$1" -gt 0 && return 0 + [ "$#" -le "1" ] && return 1 + shift + bool "$@" + return $? + ;; + esac +} + +bool_true() { + if bool "$@"; then + echo true + else + echo false + fi +} + +bool_not_true() { + if bool "$@"; then + echo false + else + echo true + fi +} + +bool_enable() { + if bool "$@"; then + echo enable + else + echo disable + fi +} + +bool_not_enable() { + if bool "$@"; then + echo disable + else + echo enable + fi +} + +bool_yes() { + if bool "$@"; then + echo yes + else + echo no + fi +} + +bool_not_yes() { + if bool "$@"; then + echo no + else + echo yes + fi +} + +args_enable() { + local cond="$1" + local a + shift + if bool "$cond" ; then + for a; do + printf "%q\n" "$a" + done + fi +} + +show_cmd() { + local a + local sep= + + for a; do + printf '%s%q' "$sep" "$a" + sep=' ' + done + printf '\n' +} + +SHOW_CMD= + +P_NOBUILD="${NOBUILD-0}" + +P_DEBUG="${DEBUG-1}" + +P_BUILD_TYPE="${BUILD_TYPE-}" +P_CFLAGS="${CFLAGS-}" +P_CC="${CC-$((! command -v gcc && command -v clang) &>/dev/null && echo clang || echo gcc)}" + +P_RHEL="${RHEL-}" +P_FEDORA="${FEDORA-}" + +P_CONFIG_PLUGINS_DEFAULT_IFCFG_RH="${CONFIG_PLUGINS_DEFAULT_IFCFG_RH-}" +P_CRYPTO="${CRYPTO-}" +P_DBUS_SYS_DIR="${DBUS_SYS_DIR-}" +P_DHCP_DEFAULT="${DHCP_DEFAULT-}" +P_DNS_RC_MANAGER_DEFAULT="${DNS_RC_MANAGER_DEFAULT-}" +P_EBPF_ENABLED="${EBPF_ENABLED-no}" +P_FIREWALLD_ZONE="${FIREWALLD_ZONE-}" +P_IWD="${IWD-}" +P_LOGGING_BACKEND_DEFAULT="${LOGGING_BACKEND_DEFAULT-}" +P_LTO="${LTO-0}" +P_MODEM_MANAGER_1="${MODEM_MANAGER_1-}" +P_TEST="${TEST-1}" +P_SILENT_RULES="${SILENT_RULES-1}" + +P_VERSION="${VERSION:-$(get_version)}" +P_RELEASE="${RELEASE:-$(git rev-list HEAD | wc -l).test}" + +P_REGEN_DOCS="${REGEN_DOCS-1}" +P_SANITIZER="${SANITIZER-0}" + +P_WIFI="${WIFI-1}" +P_WWAN="${WWAN-1}" +P_TEAM="${TEAM-1}" +P_BLUETOOTH="${BLUETOOTH-1}" +P_NMTUI="${NMTUI-1}" +P_NM_CLOUD_SETUP="${NM_CLOUD_SETUP-1}" +P_OVS="${OVS-1}" +P_PPP="${PPP-1}" + +P_PPP_VERSION="${PPP_VERSION-}" + +D_PREFIX="$(rpm --eval "%{_prefix}")" +D_BINDIR="$(rpm --eval "%{_bindir}")" +D_SBINDIR="$(rpm --eval "%{_sbindir}")" +D_LIBDIR="$(rpm --eval "%{_libdir}")" +D_LIBEXECDIR="$(rpm --eval "%{_libexecdir}")" +D_INCLUDEDIR="$(rpm --eval "%{_includedir}")" +D_DATADIR="$(rpm --eval "%{_datadir}")" +D_RUNDIR="$(rpm --eval "%{_rundir}")" +D_MANDIR="$(rpm --eval "%{_mandir}")" +D_INFODIR="$(rpm --eval "%{_infodir}")" +D_SYSCONFDIR="$(rpm --eval "%{_sysconfdir}")" +D_LOCALSTATEDIR="$(rpm --eval "%{_localstatedir}")" +D_SHAREDSTATEDIR="$(rpm --eval "%{_sharedstatedir}")" + +#PVARS + +if [ -z "$P_FEDORA" -a -z "$P_RHEL" ] ; then + x="$(grep -q "ID=fedora" /etc/os-release && sed -n 's/VERSION_ID=//p' /etc/os-release)" + if test "$x" -gt 0 ; then + P_FEDORA="$x" + P_RHEL=0 + else + x="$(grep -q "ID=fedora" /etc/os-release && sed -n 's/VERSION_ID=//p' /etc/os-release)" + if test "$x" -gt 0 ; then + P_FEDORA=0 + P_RHEL="$x" + fi + fi +fi +test -z "$P_FEDORA" && P_FEDORA=0 +test -z "$P_RHEL" && P_RHEL=0 + +test "$P_FEDORA" -gt 0 -o "$P_RHEL" -gt 0 || die "FEDORA/RHEL variables unset" + +if [ -z "$P_PPP_VERSION" ] ; then + P_PPP_VERSION="$(sed -n 's/^#define\s*VERSION\s*"\([^\s]*\)"$/\1/p' "$D_INCLUDEDIR/pppd/patchlevel.h" 2>/dev/null | grep . || echo bad)" +fi + +if [ -z "$P_CRYPTO" ] ; then + if [ "$P_FEDORA" -ge 29 -o "$P_RHEL" -ge 8 ] ; then + P_CRYPTO=gnutls + else + P_CRYPTO=nss + fi +fi + +if [ -z "$P_CONFIG_PLUGINS_DEFAULT_IFCFG_RH" ] ; then + if [ "$P_FEDORA" -ge 33 -o "$P_RHEL" -ge 9 ] ; then + P_CONFIG_PLUGINS_DEFAULT_IFCFG_RH=0 + else + P_CONFIG_PLUGINS_DEFAULT_IFCFG_RH=1 + fi +fi + + +if [ -z "$P_DBUS_SYS_DIR" ] ; then + if [ "$P_FEDORA" -ge 1 -o "$P_RHEL" -ge 8 ] ; then + P_DBUS_SYS_DIR="$D_DATADIR/dbus-1/system.d" + else + P_DBUS_SYS_DIR="$D_SYSCONFDIR/dbus-1/system.d" + fi +fi + +if [ -z "$P_DNS_RC_MANAGER_DEFAULT" ] ; then + if [ "$P_FEDORA" -ge 1 -o "$P_RHEL" -ge 9 ] ; then + P_DNS_RC_MANAGER_DEFAULT=auto + elif [ "$P_FEDORA" -ge 1 -o "$P_RHEL" -ge 8 ] ; then + P_DNS_RC_MANAGER_DEFAULT=symlink + else + P_DNS_RC_MANAGER_DEFAULT=file + fi +fi + +if [ -z "$P_LOGGING_BACKEND_DEFAULT" ] ; then + if [ "$P_FEDORA" -ge 1 -o "$P_RHEL" -ge 8 ] ; then + P_LOGGING_BACKEND_DEFAULT=journal + else + P_LOGGING_BACKEND_DEFAULT=syslog + fi +fi + +if [ -z "$P_DHCP_DEFAULT" ] ; then + if [ "$P_FEDORA" -ge 31 -o "$P_RHEL" -ge 8 ] ; then + P_DHCP_DEFAULT=internal + else + P_DHCP_DEFAULT=dhclient + fi +fi + +if [ -z "$P_FIREWALLD_ZONE" ] ; then + if [ "$P_FEDORA" -ge 32 -o "$P_RHEL" -ge 8 ] ; then + P_FIREWALLD_ZONE=1 + else + P_FIREWALLD_ZONE=0 + fi +fi + +if [ -z "$P_IWD" ] ; then + if [ "$P_RHEL" -ge 1 ] ; then + P_IWD=0 + else + P_IWD=1 + fi +fi + +if [ -z "$P_MODEM_MANAGER_1" ] ; then + if bool "$P_BLUETOOTH" || bool "$P_WWAN" ; then + P_MODEM_MANAGER_1=1 + else + P_MODEM_MANAGER_1=0 + fi +fi + +if bool "$P_DEBUG" ; then + P_CFLAGS="-g -Og -fexceptions${P_CFLAGS:+ }$P_CFLAGS" +else + P_CFLAGS="-g -O2 -fexceptions${P_CFLAGS:+ }$P_CFLAGS" +fi + +if [ -z "$P_BUILD_TYPE" ] ; then + if [ -d ./build -a ! -f ./configure ] ; then + P_BUILD_TYPE=meson + elif [ ! -d ./build -a -f ./configure ] ; then + P_BUILD_TYPE=autotools + else + P_BUILD_TYPE=autotools + fi +fi + +while [[ $# -gt 0 ]] ; do + A="$1" + shift + case "$A" in + --meson|-m) + P_BUILD_TYPE=meson + ;; + --autotools|-a) + P_BUILD_TYPE=autotools + ;; + -s|--show) + SHOW_CMD=show_cmd + ;; + -h|help|-help|--help) + usage + exit 0 + ;; + -B|--no-build) + P_NOBUILD=1 + ;; + *) + usage + exit 1 + ;; + esac +done + +vars_with_vals + +if [ "$P_BUILD_TYPE" == meson ] ; then + MESON_RECONFIGURE= + if test -d "./build/" ; then + MESON_RECONFIGURE="--reconfigure" + fi + + $SHOW_CMD \ + env \ + CC="$P_CC" \ + CFLAGS="$P_CFLAGS" \ + meson \ + --buildtype=plain \ + --prefix="$D_PREFIX" \ + --libdir="$D_LIBDIR" \ + --libexecdir="$D_LIBEXECDIR" \ + --bindir="$D_BINDIR" \ + --sbindir="$D_SBINDIR" \ + --includedir="$D_INCLUDEDIR" \ + --datadir="$D_DATADIR" \ + --mandir="$D_MANDIR" \ + --infodir="$D_INFODIR" \ + --localedir="$D_DATADIR"/locale \ + --sysconfdir="$D_SYSCONFDIR" \ + --localstatedir="$D_LOCALSTATEDIR" \ + --sharedstatedir="$D_SHAREDSTATEDIR" \ + --wrap-mode=nodownload \ + --auto-features=enabled \ + \ + build \ + \ + $MESON_RECONFIGURE \ + \ + -Db_ndebug=false \ + --warnlevel 2 \ + $(args_enable "$P_TEST" --werror) \ + -Dnft="${D_SBINDIR}/nft" \ + -Diptables="${D_SBINDIR}/iptables" \ + -Ddhclient="${D_SBINDIR}/dhclient" \ + -Ddhcpcanon=no \ + -Ddhcpcd=no \ + -Dconfig_dhcp_default="$P_DHCP_DEFAULT" \ + "-Dcrypto=$P_CRYPTO" \ + $(args_enable "$P_DEBUG" -Dmore_logging=true -Dmore_asserts=10000) \ + $(args_enable "$(bool_not_true "$P_DEBUG")" -Dmore_logging=false -Dmore_asserts=0 ) \ + -Dld_gc=true \ + -Db_lto="$(bool_true "$P_LTO")" \ + -Dlibaudit=yes-disabled-by-default \ + -Dmodem_manager="$(bool_true "$P_MODEM_MANAGER_1")" \ + $(args_enable "$P_WIFI" -Dwifi=true -Dwext="$(bool_true "$P_FEDORA")") \ + $(args_enable "$(bool_not_true "$P_WIFI")" -Dwifi=false ) \ + -Diwd="$(bool_true "$P_IWD")" \ + -Dbluez5_dun="$(bool_true "$P_BLUETOOTH")" \ + -Dnmtui="$(bool_true "$P_NMTUI")" \ + -Dnm_cloud_setup="$(bool_true "$P_NM_CLOUD_SETUP")" \ + -Dvapi=true \ + -Dintrospection=true \ + -Ddocs="$(bool_true "$P_REGEN_DOCS")" \ + -Dteamdctl="$(bool_true "$P_TEAM")" \ + -Dovs="$(bool_true "$P_OVS")" \ + -Dselinux=true \ + -Dpolkit=true \ + -Dconfig_auth_polkit_default=true \ + -Dmodify_system=true \ + -Dconcheck=true \ + -Dlibpsl="$(bool_true "$P_FEDORA")" \ + -Debpf="$(bool_true "$P_EBPF_ENABLED")" \ + -Dsession_tracking=systemd \ + -Dsuspend_resume=systemd \ + -Dsystemdsystemunitdir=/usr/lib/systemd/system \ + -Dsystem_ca_path=/etc/pki/tls/cert.pem \ + -Ddbus_conf_dir="$P_DBUS_SYS_DIR" \ + -Dtests=yes \ + -Dvalgrind=no \ + -Difcfg_rh=true \ + -Difupdown=false \ + $(args_enable "$P_PPP" -Dppp=true -Dpppd="$D_SBINDIR/pppd" -Dpppd_plugin_dir="$D_LIBDIR/pppd/$P_PPP_VERSION") \ + $(args_enable "$(bool_not_true "$P_PPP")" -Dppp=false ) \ + -Dfirewalld_zone="$(bool_true "$P_FIREWALLD_ZONE}")" \ + -Ddist_version="$P_VERSION-$P_RELEASE" \ + $(args_enable "$P_CONFIG_PLUGINS_DEFAULT_IFCFG_RH" -Dconfig_plugins_default=ifcfg-rh) \ + -Dresolvconf=no \ + -Dnetconfig=no \ + -Dconfig_dns_rc_manager_default="$P_DNS_RC_MANAGER_DEFAULT" \ + -Dconfig_logging_backend_default="$P_LOGGING_BACKEND_DEFAULT" \ + ; +else + if ! test -x ./configure ; then + if [ -z "$SHOW_CMD" ]; then + NOCONFIGURE=yes ./autogen.sh + fi + fi + $SHOW_CMD \ + ./configure \ + --build=x86_64-redhat-linux-gnu \ + --host=x86_64-redhat-linux-gnu \ + --program-prefix= \ + --prefix="$D_PREFIX" \ + --exec-prefix=/usr \ + --bindir="$D_BINDIR" \ + --sbindir="$D_SBINDIR" \ + --sysconfdir="$D_SYSCONFDIR" \ + --datadir="$D_DATADIR" \ + --includedir="$D_INCLUDEDIR" \ + --libdir="$D_LIBDIR" \ + --libexecdir="$D_LIBEXECDIR" \ + --localstatedir="$D_LOCALSTATEDIR" \ + --sharedstatedir="$D_SHAREDSTATEDIR" \ + --mandir="$D_MANDIR" \ + --infodir="$D_INFODIR" \ + \ + CC="$P_CC" \ + CFLAGS="$P_CFLAGS" \ + \ + --enable-dependency-tracking=yes \ + \ + --with-runstatedir="$D_RUNDIR" \ + --enable-silent-rules="$(bool_yes "$P_SILENT_RULES")" \ + --enable-static=no \ + --with-nft="${D_SBINDIR}/nft" \ + --with-iptables="${D_SBINDIR}/iptables" \ + --with-dhclient="${D_SBINDIR}/dhclient" \ + --with-dhcpcd=no \ + --with-dhcpcanon=no \ + --with-config-dhcp-default="$P_DHCP_DEFAULT" \ + --with-crypto="$P_CRYPTO" \ + $(args_enable "$P_SANITIZER" --with-address-sanitizer=exec --enable-undefined-sanitizer="$( (bool "$P_FEDORA" || test "$P_RHEL" -ge 8) && echo yes || echo no)" ) \ + $(args_enable "$(bool_not_true "$P_SANITIZER")" --with-address-sanitizer=no --enable-undefined-sanitizer=no ) \ + $(args_enable "$P_DEBUG" --enable-more-logging=yes --with-more-asserts=10000) \ + $(args_enable "$(bool_not_true "$P_DEBUG")" --enable-more-logging=no --with-more-asserts=0 ) \ + --enable-ld-gc=yes \ + --enable-lto="$(bool_yes "$P_LTO")" \ + --with-libaudit=yes-disabled-by-default \ + --with-modem-manager-1="$(bool_yes "$P_MODEM_MANAGER_1")" \ + $(args_enable "$P_WIFI" --enable-wifi=yes --with-wext="$(bool_yes "$P_FEDORA")") \ + $(args_enable "$(bool_not_true "$P_WIFI")" --enable-wifi=no ) \ + --with-iwd="$(bool_yes "$P_IWD")" \ + --enable-bluez5-dun="$(bool_yes "$P_BLUETOOTH")" \ + --with-nmtui="$(bool_yes "$P_NMTUI")" \ + --with-nm-cloud-setup="$(bool_yes "$P_NM_CLOUD_SETUP")" \ + --enable-vala=yes \ + --enable-introspection=yes \ + --enable-gtk-doc="$(bool_yes "$P_REGEN_DOCS")" \ + --enable-teamdctl="$(bool_yes "$P_TEAM")" \ + --enable-ovs="$(bool_yes "$P_OVS")" \ + --with-selinux=yes \ + --enable-polkit=yes \ + --enable-modify-system=yes \ + --enable-concheck=yes \ + --with-libpsl="$(bool_yes "$P_FEDORA")" \ + --with-ebpf="$(bool_yes "$P_EBPF_ENABLED")" \ + --with-session-tracking=systemd \ + --with-suspend-resume=systemd \ + --with-systemdsystemunitdir=/usr/lib/systemd/system \ + --with-system-ca-path=/etc/pki/tls/cert.pem \ + --with-dbus-sys-dir="$P_DBUS_SYS_DIR" \ + --with-tests=yes \ + --enable-more-warnings="$(bool "$P_TEST" && echo error || echo yes)" \ + --with-valgrind=no \ + --enable-ifcfg-rh=yes \ + --enable-ifupdown=no \ + $(args_enable "$P_PPP" --enable-ppp=yes --with-pppd="$D_SBINDIR/pppd" --with-pppd-plugin-dir="$D_LIBDIR/pppd/$P_PPP_VERSION") \ + $(args_enable "$(bool_not_true "$P_PPP")" --enable-ppp=no ) \ + --enable-firewalld-zone="$(bool_yes "$P_FIREWALLD_ZONE")" \ + --with-dist-version="$P_VERSION-$P_RELEASE" \ + $(args_enable "$P_CONFIG_PLUGINS_DEFAULT_IFCFG_RH" --with-config-plugins-default=ifcfg-rh) \ + --with-resolvconf=no \ + --with-netconfig=no \ + --with-config-dns-rc-manager-default="$P_DNS_RC_MANAGER_DEFAULT" \ + --with-config-logging-backend-default="$P_LOGGING_BACKEND_DEFAULT" \ + ; +fi + +if ! bool "$P_NOBUILD" ; then + if [ "$P_BUILD_TYPE" == meson ] ; then + $SHOW_CMD ninja -C build + else + $SHOW_CMD make -j 10 + fi +fi diff --git a/contrib/fedora/rpm/mockbuild.sh b/contrib/fedora/rpm/mockbuild.sh new file mode 100755 index 00000000..785aa254 --- /dev/null +++ b/contrib/fedora/rpm/mockbuild.sh @@ -0,0 +1,20 @@ +#!/bin/sh +# +# mockbuild.sh +# +# Generate SRPM from git tree and rebuild it using mock. + +SCRIPTDIR="$(dirname "$(readlink -f "$0")")" +FEDORAVER=$(sed -E 's/.*([0-9]{2}).*/\1/g' /etc/fedora-release) +ARCH=$(uname -m) +SRPM=${SCRIPTDIR}/latest/SRPMS/NetworkManager*.src.rpm + +alias mock="mock -r fedora-${FEDORAVER}-${ARCH}" + +# Generate SRPM +${SCRIPTDIR}/build_clean.sh --srpm --git + +# Rebuild SRPM +mock --rebuild ${SRPM} + +exit diff --git a/contrib/fedora/rpm/readme-ifcfg-rh-migrated.txt b/contrib/fedora/rpm/readme-ifcfg-rh-migrated.txt new file mode 100644 index 00000000..aabbcc86 --- /dev/null +++ b/contrib/fedora/rpm/readme-ifcfg-rh-migrated.txt @@ -0,0 +1,84 @@ +NetworkManager was built to automatically migrate connection profiles in +this directory to equivalent ones in keyfile format in directory +/etc/NetworkManager/system-connections. + +You can check whether the migration is enabled via: + + $ NetworkManager --print-config | grep migrate-ifcfg-rh + +In case it is enabled, all files in this directory are migrated at startup. + +To inspect where your connection files are currently stored use: + + $ nmcli -f name,uuid,filename connection + +Background +========== + +The ifcfg format is deprecated and will be removed in future releases. For +more information see: + +https://lists.freedesktop.org/archives/networkmanager/2023-May/000103.html + +Connection profiles in keyfile format have many benefits. For example, this +format is INI file-based and can easily be parsed and generated. + +Each section in NetworkManager keyfiles corresponds to a NetworkManager +setting name as described in the nm-settings(5) and nm-settings-keyfile(5) +man pages. Each key-value pair in a section is one of the properties listed +in the settings specification of the man page. + +How to keep using ifcfg +======================= + +If you want to keep using connection profiles in ifcfg format, you need to: + + - disable the automatic migration to keyfile by setting + "migrate-ifcfg-rh=false" in the [main] section of NetworkManager + configuration; + + - optionally, set "plugins=ifcfg-rh" in the [main] section of + NetworkManager configuration so that new profiles are created in ifcfg + format. + +At this point, you can migrate all your files back via + + nmcli connection migrate --plugin ifcfg-rh + +Or, if you prefer to migrate only specific connections: + + nmcli connection migrate --plugin ifcfg-rh <profile_name|UUID> + +Note that some connection types are not supported by the ifcfg plugin. + +Interface renaming +================== + +Connection profiles stored in ifcfg-rh format support the renaming of +interfaces via udev. This is done via a helper tool +/usr/lib/udev/rename_device that is invoked by udev to parse the files +in /etc/sysconfig/network-scripts; when the HWADDR and DEVICE +variables are set, the interface that matches the MAC address in +HWADDR is renamed to the name specified in DEVICE. + +Connections in keyfile format don't provide the same integration with +udev. The renaming of interfaces must be configured directly in udev, +for example by creating a file: + + /etc/systemd/network/70-rename.link + +with content: + + [Match] + MACAddress=00:11:22:33:44:56 + + [Link] + Name=ethernet1 + +Alternatively, a udev rule can also be used, such as: + + /etc/udev/rules.d/70-interface-names.rules + +with content: + + SUBSYSTEM=="net",ACTION=="add",ATTR{address}=="00:11:22:33:44:56",ATTR{type}=="1",NAME="ethernet1" diff --git a/contrib/fedora/rpm/readme-ifcfg-rh.txt b/contrib/fedora/rpm/readme-ifcfg-rh.txt new file mode 100644 index 00000000..56c373d4 --- /dev/null +++ b/contrib/fedora/rpm/readme-ifcfg-rh.txt @@ -0,0 +1,63 @@ +NetworkManager stores new network profiles in keyfile format in the +/etc/NetworkManager/system-connections/ directory. + +Previously, NetworkManager stored network profiles in ifcfg format +in this directory (/etc/sysconfig/network-scripts/). However, the ifcfg +format is deprecated. By default, NetworkManager no longer creates +new profiles in this format. + +Connection profiles in keyfile format have many benefits. For example, +this format is INI file-based and can easily be parsed and generated. + +Each section in NetworkManager keyfiles corresponds to a NetworkManager +setting name as described in the nm-settings(5) and nm-settings-keyfile(5) +man pages. Each key-value-pair in a section is one of the properties +listed in the settings specification of the man page. + +If you still use network profiles in ifcfg format, consider migrating +them to keyfile format. To migrate all profiles at once, enter: + +# nmcli connection migrate + +This command migrates all profiles from ifcfg format to keyfile +format and stores them in /etc/NetworkManager/system-connections/. + +Alternatively, to migrate only a specific profile, enter: + +# nmcli connection migrate <profile_name|UUID|D-Bus_path> + +For further details, see: +* nm-settings-keyfile(5) +* nmcli(1) + +Interface renaming +================== + +Connection profiles stored in ifcfg-rh format support the renaming of +interfaces via udev. This is done via a helper tool +/usr/lib/udev/rename_device that is invoked by udev to parse the files +in /etc/sysconfig/network-scripts; when the HWADDR and DEVICE +variables are set, the interface that matches the MAC address in +HWADDR is renamed to the name specified in DEVICE. + +Connections in keyfile format don't provide the same integration with +udev. The renaming of interfaces must be configured directly in udev, +for example by creating a file: + + /etc/systemd/network/70-rename.link + +with content: + + [Match] + MACAddress=00:11:22:33:44:56 + + [Link] + Name=ethernet1 + +Alternatively, a udev rule can also be used, such as: + + /etc/udev/rules.d/70-interface-names.rules + +with content: + + SUBSYSTEM=="net",ACTION=="add",ATTR{address}=="00:11:22:33:44:56",ATTR{type}=="1",NAME="ethernet1" diff --git a/contrib/fedora/rpm/release.sh b/contrib/fedora/rpm/release.sh new file mode 100755 index 00000000..809810f0 --- /dev/null +++ b/contrib/fedora/rpm/release.sh @@ -0,0 +1,604 @@ +#!/bin/bash + +# Script for doing NetworkManager releases. +# +# Run with --help for usage. +# +# There are 6 modes: +# +# - "devel" : on main branch to tag a devel release (e.g. "1.25.2-dev"). +# - "rc1" : the first release candidate on "main" branch which branches off +# a new "nm-1-X" branch (e.g. tag "1.26-rc1" (1.25.90) and branch +# off "nm-1-26"). On main this also bumps the version number +# and creates a new devel release (e.g. "1.27.0-dev"). +# - "rc" : further release candidates on RC branch (e.g. from "nm-1-26" branch +# tag "1.26-rc2" with version number 1.25.91). +# - "major" : on stable branch do a major release (e.g. on "nm-1-26" branch +# release "1.26.0", followed by "1.26.1-dev"). +# You should do a "major-post" release right a "major" release. +# - "major-post": after a "major" release, merge the release branch with main and +# do another devel snapshot on main (e.g. do "1.27.1-dev" release). +# - "minor" : on a stable branch do a minor release (e.g. "1.26.4" on "nm-1-26" +# branch and bump to "1.26.5-dev"). +# +# Requisites: +# +# * You need to start with a clean working directory (git clean -fdx) +# +# * Run in a "clean" environment, i.e. no unusual environment variables set, on a recent +# Fedora, with suitable dependencies installed. +# +# * First, ensure that you have ssh keys for "master.gnome.org" installed (and ssh-agent running). +# Also, ensure you have a GPG key that you want to use for signing. Also, have gpg-agent running +# and possibly configure `git config --get user.signingkey` for the proper key. +# +# * Your git repository needs a remote "origin" that points to the upstream git repository +# (or set $ORIGIN) and use the standard git refs/remotes/$ORIGIN/ branch names. +# +# * All your (relevant) local branches (main and nm-1-*) must be up to date with their +# remote tracking branches for origin. +# +# Run with --no-test to do the actual release. + +die() { + echo -n "FAIL: " + echo_color 31 "$@" + exit 1 +} + +echo_color() { + local color="$1" + shift + echo -e -n "\033[0;${color}m" + echo "$@" + echo -e -n '\033[0m' +} + +print_usage() { + echo "Usage:" + echo " $BASH_SOURCE [devel|rc1|rc|major|major-post|minor]" + echo " [--no-test] \\" + echo " [--no-find-backports] \\" + echo " [--no-cleanup] \\" + echo " [--allow-local-branches] \\" + echo " [--no-check-gitlab] \\" + echo " [--no-check-news] \\" + echo " [--no-warn-publish-docs] \\" +} + +die_help() { + print_usage + echo + sed -e '/^# /,/# Run with --no-test/!d' -e 's/^#\($\| \)/ /' "$BASH_SOURCE" + exit 0 +} + +die_usage() { + echo -n "FAIL: " + echo_color 31 "$@" + echo + print_usage + exit 1 +} + +do_command() { + local color=36 + if [ "$DRY_RUN" = 0 ]; then + color=31 + fi + echo -n "COMMAND: " + echo_color $color -n "$@" + echo + if [ "$DRY_RUN" = 0 ]; then + "$@" + fi +} + +parse_version() { + local MAJ="$(sed -n '1,20 s/^m4_define(\[nm_major_version\], \[\([0-9]\+\)\])$/\1/p' ./configure.ac)" + local MIN="$(sed -n '1,20 s/^m4_define(\[nm_minor_version\], \[\([0-9]\+\)\])$/\1/p' ./configure.ac)" + local MIC="$(sed -n '1,20 s/^m4_define(\[nm_micro_version\], \[\([0-9]\+\)\])$/\1/p' ./configure.ac)" + + re='^(0|[1-9][0-9]*) (0|[1-9][0-9]*) (0|[1-9][0-9]*)$' + [[ "$MAJ $MIN $MIC" =~ $re ]] || return 1 + echo "$MAJ $MIN $MIC" +} + +number_is_even() { + local re='^[0-9]*[02468]$' + [[ "$1" =~ $re ]] +} + +number_is_odd() { + local re='^[0-9]*[13579]$' + [[ "$1" =~ $re ]] +} + +git_same_ref() { + local a="$(git rev-parse "$1" 2>/dev/null)" || return 1 + local b="$(git rev-parse "$2" 2>/dev/null)" || return 1 + [ "$a" = "$b" ] +} + +check_gitlab_pipeline() { + local BRANCH="$1" + local SHA="$2" + local PIPELINE_ID + + PIPELINE_ID="$(curl --no-progress-meter "https://gitlab.freedesktop.org/api/v4/projects/411/pipelines?ref=$BRANCH&sha=$SHA&order_by=id" 2>/dev/null | jq '.[0].id')" + if ! [[ $PIPELINE_ID =~ [0-9]+ ]] ; then + echo "Cannot find pipeline for branch $BRANCH. Check \"https://gitlab.freedesktop.org/NetworkManager/NetworkManager/pipelines?page=1&scope=branches&ref=$BRANCH\"" + return 1 + fi + + PIPELINE_STATUSES="$(curl --no-progress-meter "https://gitlab.freedesktop.org/api/v4/projects/411/pipelines/$PIPELINE_ID/jobs?per_page=100" 2>/dev/null | jq '.[] | select(.stage!="prep" and .stage!="tier3") | .status')" + + if ! echo "$PIPELINE_STATUSES" | grep -q '^"success"$' ; then + echo "Cannot find successful jobs for branch $BRANCH. Check \"https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/pipelines/$PIPELINE_ID\"" + return 1 + fi + if echo "$PIPELINE_STATUSES" | grep -q -v '^"success"$' ; then + echo "Seems not all jobs for $BRANCH ran (or were successfull). Check \"https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/pipelines/$PIPELINE_ID\"" + return 1 + fi + + return 0 +} + +set_version_number_autotools() { + sed -i \ + -e '1,20 s/^m4_define(\[nm_major_version\], \[\([0-9]\+\)\])$/m4_define([nm_major_version], ['"$1"'])/' \ + -e '1,20 s/^m4_define(\[nm_minor_version\], \[\([0-9]\+\)\])$/m4_define([nm_minor_version], ['"$2"'])/' \ + -e '1,20 s/^m4_define(\[nm_micro_version\], \[\([0-9]\+\)\])$/m4_define([nm_micro_version], ['"$3"'])/' \ + ./configure.ac +} + +set_version_number_meson() { + sed -i \ + -e '1,20 s/^\( *version: *'\''\)[0-9]\+\.[0-9]\+\.[0-9]\+\('\'',\)$/\1'"$1.$2.$3"'\2/' \ + meson.build +} + +set_version_number() { + set_version_number_autotools "$@" && + set_version_number_meson "$@" +} + +check_news() { + local mode="$1" + shift + local ver_arr=("$@") + + case "$mode" in + major|minor) + if git grep -q 'NOT RECOMMENDED FOR PRODUCTION USE' -- ./NEWS ; then + return 1 + fi + ;; + *) + ;; + esac + return 0 +} + +DO_CLEANUP=1 +CLEANUP_CHECKOUT_BRANCH= +CLEANUP_REFS=() +cleanup() { + if [ $DO_CLEANUP = 1 ]; then + [ -n "$CLEANUP_CHECKOUT_BRANCH" ] && git checkout -f "$CLEANUP_CHECKOUT_BRANCH" + for c in "${CLEANUP_REFS[@]}"; do + echo "delete reference. Restore with $(echo_color 36 -n git update-ref \"$c\" $(git rev-parse "$c"))" + git update-ref -d "$c" + done + fi +} + +trap cleanup EXIT + +DIR="$(git rev-parse --show-toplevel)" + +ORIGIN=origin + +BASH_SOURCE_ABSOLUTE="$(readlink -f "$BASH_SOURCE")" + +test -d "$DIR" && +cd "$DIR" && +test -f ./contrib/fedora/rpm/build_clean.sh || die "cannot find NetworkManager base directory" + +RELEASE_MODE="" +DRY_RUN=1 +FIND_BACKPORTS=1 +ALLOW_LOCAL_BRANCHES=0 +HELP_AND_EXIT=1 +CHECK_GITLAB=1 +WARN_PUBLISH_DOCS=1 +CHECK_NEWS=1 +while [ "$#" -ge 1 ]; do + A="$1" + shift + HELP_AND_EXIT=0 + case "$A" in + --no-test) + DRY_RUN=0 + ;; + --no-find-backports) + FIND_BACKPORTS=0 + ;; + --no-cleanup) + DO_CLEANUP=0 + ;; + --allow-local-branches) + # by default, the script errors out if the relevant branch (main, nm-1-Y) are not the same + # as the remote branch on origin. You should not do a release if you have local changes + # that differ from upstream. Set this flag to override that check. + ALLOW_LOCAL_BRANCHES=1 + ;; + --no-check-gitlab) + CHECK_GITLAB=0 + ;; + --no-warn-publish-docs) + WARN_PUBLISH_DOCS=0 + ;; + --no-check-news) + CHECK_NEWS=0 + ;; + --help|-h) + die_help + ;; + devel|rc1|rc|major|major-post|minor) + [ -z "$RELEASE_MODE" ] || die_usage "duplicate release-mode" + RELEASE_MODE="$A" + ;; + *) + die_usage "unknown argument \"$A\"" + ;; + esac +done +[ "$HELP_AND_EXIT" = 1 ] && die_help + +[ -n "$RELEASE_MODE" ] || die_usage "specify the desired release mode" + +VERSION_ARR=( $(parse_version) ) || die "cannot detect NetworkManager version" +VERSION_STR="$(IFS=.; echo "${VERSION_ARR[*]}")" + +echo "Current version before release: $VERSION_STR (do \"$RELEASE_MODE\" release)" + +grep -q "version: '${VERSION_ARR[0]}.${VERSION_ARR[1]}.${VERSION_ARR[2]}'," ./meson.build || die "meson.build does not have expected version" + +TMP="$(git status --porcelain)" || die "git status failed" +test -z "$TMP" || die "git working directory is not clean (git status --porcelain)" + +TMP="$(LANG=C git clean -ndx)" || die "git clean -ndx failed" +test -z "$TMP" || die "git working directory is not clean? (git clean -ndx)" + +CUR_BRANCH="$(git rev-parse --abbrev-ref HEAD)" +CUR_HEAD="$(git rev-parse HEAD)" +TMP_BRANCH=release-branch + +if [ "$CUR_BRANCH" = main ]; then + number_is_odd "${VERSION_ARR[1]}" || die "Unexpected version number on main. Should be an odd development version" + [ "$RELEASE_MODE" = devel -o "$RELEASE_MODE" = rc1 -o "$RELEASE_MODE" = major-post ] || die "Unexpected branch name \"$CUR_BRANCH\" for \"$RELEASE_MODE\"" +else + re='^nm-[0-9]+-[0-9]+$' + [[ "$CUR_BRANCH" =~ $re ]] || die "Unexpected current branch $CUR_BRANCH. Should be main or nm-?-??" + if number_is_odd "${VERSION_ARR[1]}"; then + # we are on a release candiate branch. + [ "$RELEASE_MODE" = rc -o "$RELEASE_MODE" = major ] || die "Unexpected branch name \"$CUR_BRANCH\" for \"$RELEASE_MODE\"" + [ "$CUR_BRANCH" == "nm-${VERSION_ARR[0]}-$((${VERSION_ARR[1]} + 1))" ] || die "Unexpected current branch $CUR_BRANCH. Should be nm-${VERSION_ARR[0]}-$((${VERSION_ARR[1]} + 1))" + else + [ "$RELEASE_MODE" = minor ] || die "Unexpected branch name \"$CUR_BRANCH\" for \"$RELEASE_MODE\"" + [ "$CUR_BRANCH" == "nm-${VERSION_ARR[0]}-${VERSION_ARR[1]}" ] || die "Unexpected current branch $CUR_BRANCH. Should be nm-${VERSION_ARR[0]}-${VERSION_ARR[1]}" + fi +fi + +RC_VERSION= +RELEASE_BRANCH= +case "$RELEASE_MODE" in + minor) + number_is_even "${VERSION_ARR[1]}" && + number_is_odd "${VERSION_ARR[2]}" || die "cannot do minor release on top of version $VERSION_STR" + [ "$CUR_BRANCH" != main ] || die "cannot do a minor release on main" + ;; + devel) + number_is_odd "${VERSION_ARR[1]}" || die "cannot do devel release on top of version $VERSION_STR" + [ "$((${VERSION_ARR[2]} + 1))" -lt 90 ] || die "devel release must have a micro version smaller than 90 but current version is $VERSION_STR" + [ "$CUR_BRANCH" == main ] || die "devel release can only be on main" + ;; + rc) + number_is_odd "${VERSION_ARR[1]}" || die "cannot do rc release on top of version $VERSION_STR" + [ "${VERSION_ARR[2]}" -ge 90 ] || die "rc release must have a micro version larger than ${VERSION_ARR[0]}.90 but current version is $VERSION_STR" + RC_VERSION="$((${VERSION_ARR[2]} - 88))" + [ "$CUR_BRANCH" == "nm-${VERSION_ARR[0]}-$((${VERSION_ARR[1]} + 1))" ] || die "devel release can only be on \"nm-${VERSION_ARR[0]}-$((${VERSION_ARR[1]} + 1))\" branch" + ;; + rc1) + number_is_odd "${VERSION_ARR[1]}" || die "cannot do rc release on top of version $VERSION_STR" + [ "${VERSION_ARR[2]}" -lt 90 ] || die "rc release must have a micro version smaller than ${VERSION_ARR[0]}.${VERSION_ARR[1]}.90 but current version is $VERSION_STR" + [ "$CUR_BRANCH" == main ] || die "rc1 release can only be on main" + RELEASE_BRANCH="nm-${VERSION_ARR[0]}-$((${VERSION_ARR[1]} + 1))" + ;; + major) + number_is_odd "${VERSION_ARR[1]}" || die "cannot do major release on top of version $VERSION_STR" + [ "${VERSION_ARR[2]}" -ge 90 ] || die "parent version for major release must have a micro version larger than ${VERSION_ARR[0]}.90 but current version is $VERSION_STR" + [ "$CUR_BRANCH" == "nm-${VERSION_ARR[0]}-$((${VERSION_ARR[1]} + 1))" ] || die "major release can only be on \"nm-${VERSION_ARR[0]}-$((${VERSION_ARR[1]} + 1))\" branch" + ;; + major-post) + number_is_odd "${VERSION_ARR[1]}" || die "cannot do major-post release on top of version $VERSION_STR" + [ "$((${VERSION_ARR[2]} + 1))" -lt 90 ] || die "major-post release must have a micro version smaller than 90 but current version is $VERSION_STR" + [ "$CUR_BRANCH" == main ] || die "major-post release can only be on main" + ;; + *) + die "Release mode $RELEASE_MODE not yet implemented" + ;; +esac + +git fetch "$ORIGIN" || die "git fetch failed" + +if [ "$ALLOW_LOCAL_BRANCHES" != 1 ]; then + git_same_ref "$CUR_BRANCH" "refs/heads/$CUR_BRANCH" || die "Current branch $CUR_BRANCH is not a branch??" + git_same_ref "$CUR_BRANCH" "refs/remotes/$ORIGIN/$CUR_BRANCH" || die "Current branch $CUR_BRANCH seems not up to date with refs/remotes/$ORIGIN/$CUR_BRANCH. Git pull or --allow-local-branches?" +fi + +NEWER_BRANCHES=() +if [ "$CUR_BRANCH" != main ]; then + i="${VERSION_ARR[1]}" + while : ; do + i=$((i + 2)) + b="nm-${VERSION_ARR[0]}-$i" + if ! git show-ref --verify --quiet "refs/remotes/$ORIGIN/$b"; then + git show-ref --verify --quiet "refs/heads/$b" && die "unexpectedly branch $b exists" + break + fi + if [ "$ALLOW_LOCAL_BRANCHES" != 1 ]; then + git_same_ref "$b" "refs/heads/$b" || die "branch $b is not a branch??" + git_same_ref "$b" "refs/remotes/$ORIGIN/$b" || die "branch $b seems not up to date with refs/remotes/$ORIGIN/$b. Git pull or --allow-local-branches?" + fi + NEWER_BRANCHES+=("refs/heads/$b") + done + b=main + if [ "$ALLOW_LOCAL_BRANCHES" != 1 ]; then + git_same_ref "$b" "refs/heads/$b" || die "branch $b is not a branch??" + git_same_ref "$b" "refs/remotes/$ORIGIN/$b" || die "branch $b seems not up to date with refs/remotes/$ORIGIN/$b. Git pull or --allow-local-branches?" + fi +fi + +if [ -n "$RELEASE_BRANCH" ]; then + git show-ref --verify --quiet "refs/remotes/$ORIGIN/$RELEASE_BRANCH" && die "release branch refs/remotes/$ORIGIN/$RELEASE_BRANCH unexpectedly exists already" + git show-ref --verify --quiet "refs/heads/$RELEASE_BRANCH" && die "release branch refs/heads/$RELEASE_BRANCH unexpectedly exists already" +fi + +if [ "$ALLOW_LOCAL_BRANCHES" != 1 ]; then + cmp <(git show "$ORIGIN/main:contrib/fedora/rpm/release.sh") "$BASH_SOURCE_ABSOLUTE" || die "$BASH_SOURCE is not identical to \`git show \"$ORIGIN/main:contrib/fedora/rpm/release.sh\"\`" +fi + +if ! check_news "$RELEASE_MODE" "@{VERSION_ARR[@]}" ; then + if [ "$CHECK_NEWS" == 1 ]; then + die "NEWS file needs update to mention stable release (skip check with --no-check-news)" + fi + echo "WARNING: NEWS file needs update to mention stable release (test skipped with --no-check-news)" +fi + +if [ "$RELEASE_MODE" = major -o "$RELEASE_MODE" = minor ]; then + echo + latest= + if [ "$RELEASE_MODE" = major ]; then + echo "Note that after the new major you have to publish the new documentation on" + latest=" -l" + else + echo "Note that after the stable release you maybe should publish the new documentation on" + latest=" [-l]" + fi + echo "$(echo_color 36 -n "https://gitlab.freedesktop.org/NetworkManager/networkmanager.pages.freedesktop.org.git") by running" + if [ "$RELEASE_MODE" = major ]; then + v="${VERSION_ARR[0]}.$((${VERSION_ARR[1]} + 1)).0" + else + v="${VERSION_ARR[0]}.${VERSION_ARR[1]}.$((${VERSION_ARR[2]} + 1))" + fi + echo " \`$(echo_color 36 -n "./scripts/import-docs.sh $v$latest")\`" + echo + if [ $WARN_PUBLISH_DOCS = 1 ]; then + echo "Avoid this prompt via \"--no-warn-publish-docs\"" + read -p "Please confirm that you know [ENTER] " + fi +fi + +if [ $FIND_BACKPORTS = 1 ]; then + git show "$ORIGIN/main:contrib/scripts/find-backports" > ./.git/nm-find-backports \ + && chmod +x ./.git/nm-find-backports \ + || die "cannot get contrib/scripts/find-backports" + + TMP="$(./.git/nm-find-backports "$CUR_BRANCH" main "${NEWER_BRANCHES[@]}" 2>/dev/null)" || die "nm-find-backports failed" + test -z "$TMP" || die "nm-find-backports returned patches that need to be backported (ignore with --no-find-backports): ./.git/nm-find-backports \"$CUR_BRANCH\" main ${NEWER_BRANCHES[@]}" +fi + +if [ $CHECK_GITLAB = 1 ]; then + if ! check_gitlab_pipeline "$CUR_BRANCH" "$CUR_HEAD" ; then + echo "Check the pipelines for branch \"$CUR_BRANCH\" at https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/pipelines?ref=$CUR_BRANCH" + echo "Wait for pipeline with \`ci-fairy wait-for-pipeline --project NetworkManager/NetworkManager --sha \"$CUR_HEAD\"\`" + die "It seems not all gitlab-ci jobs were running/succeeding. Skip this check with --no-check-gitlab" + fi +fi + +BRANCHES=() +BUILD_TAG= + +CLEANUP_CHECKOUT_BRANCH="$CUR_BRANCH" + +git checkout -B "$TMP_BRANCH" +CLEANUP_REFS+=("refs/heads/$TMP_BRANCH") + +case "$RELEASE_MODE" in + minor) + set_version_number "${VERSION_ARR[0]}" "${VERSION_ARR[1]}" $(("${VERSION_ARR[2]}" + 1)) + git commit -m "release: bump version to ${VERSION_ARR[0]}.${VERSION_ARR[1]}.$(("${VERSION_ARR[2]}" + 1))" -a || die "failed to commit release" + set_version_number "${VERSION_ARR[0]}" "${VERSION_ARR[1]}" $(("${VERSION_ARR[2]}" + 2)) + git commit -m "release: bump version to ${VERSION_ARR[0]}.${VERSION_ARR[1]}.$(("${VERSION_ARR[2]}" + 2)) (development)" -a || die "failed to commit devel version bump" + + b="${VERSION_ARR[0]}.${VERSION_ARR[1]}.$(("${VERSION_ARR[2]}" + 1))" + git tag -s -a -m "Tag $b" "$b" HEAD~ || die "failed to tag release" + BRANCHES+=("$b") + CLEANUP_REFS+=("refs/tags/$b") + BUILD_TAG="$b" + b="${VERSION_ARR[0]}.${VERSION_ARR[1]}.$(("${VERSION_ARR[2]}" + 2))" + git tag -s -a -m "Tag $b (development)" "$b-dev" HEAD || die "failed to tag devel version" + BRANCHES+=("$b-dev") + CLEANUP_REFS+=("refs/tags/$b-dev") + TAR_VERSION="$BUILD_TAG" + ;; + devel) + set_version_number "${VERSION_ARR[0]}" "${VERSION_ARR[1]}" $(("${VERSION_ARR[2]}" + 1)) + git commit -m "release: bump version to ${VERSION_ARR[0]}.${VERSION_ARR[1]}.$(("${VERSION_ARR[2]}" + 1)) (development)" -a || die "failed to commit devel version bump" + + b="${VERSION_ARR[0]}.${VERSION_ARR[1]}.$(("${VERSION_ARR[2]}" + 1))" + git tag -s -a -m "Tag $b (development)" "$b-dev" HEAD || die "failed to tag release" + BRANCHES+=("$b-dev") + CLEANUP_REFS+=("refs/tags/$b-dev") + BUILD_TAG="$b-dev" + TAR_VERSION="$b" + ;; + rc) + b="${VERSION_ARR[0]}.${VERSION_ARR[1]}.$(("${VERSION_ARR[2]}" + 1))" + t="${VERSION_ARR[0]}.$(("${VERSION_ARR[1]}" + 1))-rc$RC_VERSION" + set_version_number "${VERSION_ARR[0]}" "${VERSION_ARR[1]}" $(("${VERSION_ARR[2]}" + 1)) + git commit -m "release: bump version to $b ($t) (development)" -a || die "failed to commit rc version bump" + + git tag -s -a -m "Tag $b ($t) (development)" "$t" HEAD || die "failed to tag release" + BRANCHES+=("$t") + CLEANUP_REFS+=("refs/tags/$t") + BUILD_TAG="$t" + TAR_VERSION="$b" + ;; + rc1) + set_version_number "${VERSION_ARR[0]}" "${VERSION_ARR[1]}" 90 + b="${VERSION_ARR[0]}.${VERSION_ARR[1]}.90" + t="${VERSION_ARR[0]}.$(("${VERSION_ARR[1]}" + 1))-rc1" + git commit -m "release: bump version to $b ($t)" -a || die "failed to commit rc1 version bump" + + git tag -s -a -m "Tag $b ($t) (development)" "$t" HEAD || die "failed to tag release $t" + BRANCHES+=("$t") + CLEANUP_REFS+=("refs/tags/$t") + BUILD_TAG="$t" + TAR_VERSION="$b" + ;; + major) + b="${VERSION_ARR[0]}.$((${VERSION_ARR[1]} + 1)).0" + b2="${VERSION_ARR[0]}.$((${VERSION_ARR[1]} + 1)).1" + + set_version_number "${VERSION_ARR[0]}" "$((${VERSION_ARR[1]} + 1))" 0 + git commit -m "release: bump version to $b" -a || die "failed to commit major version bump" + git tag -s -a -m "Tag $b" "$b" HEAD || die "failed to tag release" + BRANCHES+=("$b") + CLEANUP_REFS+=("refs/tags/$b") + + set_version_number "${VERSION_ARR[0]}" "$((${VERSION_ARR[1]} + 1))" 1 + git commit -m "release: bump version to $b2 (development)" -a || die "failed to commit another bump after major version bump" + git tag -s -a -m "Tag $b (development)" "$b2-dev" HEAD || die "failed to tag release" + BRANCHES+=("$b2-dev") + CLEANUP_REFS+=("refs/tags/$b2-dev") + + BUILD_TAG="$b" + TAR_VERSION="$b" + ;; + major-post) + # We create a merge commit with the content of current "main", with two + # parent commits $THE_RELEASE and "main". But we want that the first parent + # is the release, so that `git log --first-parent` follows the path with the + # release candidates, and not the devel part during that time. Hence this + # switcheroo here. + git checkout -B "$TMP_BRANCH" "${VERSION_ARR[0]}.$((${VERSION_ARR[1]} - 1)).0" || die "merge0" + git merge -Xours --commit -m tmp main || die "merge1" + git rm --cached -r . || die "merge2" + git checkout main -- . || die "merge3" + b="${VERSION_ARR[0]}.${VERSION_ARR[1]}.$((${VERSION_ARR[2]} + 1))" + git commit --amend -m tmp -a || die "failed to commit major version bump" + test x = "x$(git diff main HEAD)" || die "there is a diff after merge!" + + set_version_number "${VERSION_ARR[0]}" "${VERSION_ARR[1]}" "$((${VERSION_ARR[2]} + 1))" + git commit --amend -m "release: bump version to $b (development)" -a || die "failed to commit major version bump" + git tag -s -a -m "Tag $b (development)" "$b-dev" HEAD || die "failed to tag release" + BRANCHES+=("$b-dev") + CLEANUP_REFS+=("refs/tags/$b-dev") + BUILD_TAG="$b-dev" + TAR_VERSION="$b" + ;; + *) + die "Release mode $RELEASE_MODE not yet implemented" + ;; +esac + +build_tag() { + git checkout "$BUILD_TAG" || die "failed to checkout $BUILD_TAG" + + ./contrib/fedora/rpm/build_clean.sh -r || die "build release failed" + + test -f "./build/meson-dist/$RELEASE_FILE" \ + || die "release file \"./build/meson-dist/$RELEASE_FILE\" not found" + + cp "./build/meson-dist/$RELEASE_FILE" /tmp/ || die "failed to copy release tarball to /tmp" + + if test -f "./build/meson-dist/$RELEASE_FILE.sig" ; then + cp "./build/meson-dist/$RELEASE_FILE.sig" /tmp/ || die "failed to copy signature for tarball to /tmp" + fi + + git clean -fdx +} + +RELEASE_FILES=() +if [ -n "$BUILD_TAG" ]; then + RELEASE_FILE="NetworkManager-$TAR_VERSION.tar.xz" + RELEASE_FILES+=("$RELEASE_FILE") + build_tag +fi +git checkout -B "$CUR_BRANCH" "$TMP_BRANCH" || die "cannot checkout $CUR_BRANCH" + +BRANCHES+=( "$CUR_BRANCH" ) + +if [ "$RELEASE_MODE" = rc1 ]; then + git branch "$RELEASE_BRANCH" "$TMP_BRANCH" || die "cannot checkout $CUR_BRANCH" + BRANCHES+=( "$RELEASE_BRANCH" ) + CLEANUP_REFS+=( "refs/heads/$RELEASE_BRANCH" ) +fi + +if [ "$RELEASE_MODE" = rc1 ]; then + git checkout "$TMP_BRANCH" + b="${VERSION_ARR[0]}.$((${VERSION_ARR[1]} + 2)).0" + set_version_number "${VERSION_ARR[0]}" "$((${VERSION_ARR[1]} + 2))" 0 + git commit -m "release: bump version to $b (development)" -a || die "failed to commit devel version bump" + git tag -s -a -m "Tag $b (development)" "$b-dev" HEAD || die "failed to tag release" + BRANCHES+=("$b-dev") + CLEANUP_REFS+=("refs/tags/$b-dev") + BUILD_TAG="$b-dev" + TAR_VERSION="$b" + RELEASE_FILE="NetworkManager-$TAR_VERSION.tar.xz" + RELEASE_FILES+=("$RELEASE_FILE") + build_tag + git checkout -B "$CUR_BRANCH" "$TMP_BRANCH" || die "cannot checkout $CUR_BRANCH" +fi + +if ! [ "$DRY_RUN" = 0 ]; then + ssh master.gnome.org true || die "failed to \`ssh master.gnome.org\`" +fi + +for r in "${RELEASE_FILES[@]}"; do + do_command rsync -va --append-verify -P "/tmp/$r" master.gnome.org: || die "failed to rsync \"/tmp/$r\"" +done + +do_command git push "$ORIGIN" "${BRANCHES[@]}" || die "failed to to push branches ${BRANCHES[@]} to $ORIGIN" + +FAIL=0 +for r in "${RELEASE_FILES[@]}"; do + do_command ssh master.gnome.org ftpadmin install --unattended "$r" || FAIL=1 +done +if [ "$FAIL" = 1 ]; then + die "ftpadmin install failed. This was the last step. Invoke the command manually" +fi + +CLEANUP_CHECKOUT_BRANCH= +if [ "$DRY_RUN" = 0 ]; then + CLEANUP_REFS=() + git branch -D "$TMP_BRANCH" +else + H="$(git rev-parse "$CUR_BRANCH")" + git checkout -B "$CUR_BRANCH" "$CUR_HEAD" || die "cannot reset $CUR_BRANCH to $CUR_HEAD" + echo "delete reference. Restore with $(echo_color 36 -n git checkout -B "\"$CUR_BRANCH\"" "$H")" +fi diff --git a/contrib/fedora/utils/makerepo.sh b/contrib/fedora/utils/makerepo.sh new file mode 100755 index 00000000..266aac8f --- /dev/null +++ b/contrib/fedora/utils/makerepo.sh @@ -0,0 +1,698 @@ +#!/bin/bash + +# +# The script is ugly but is here to help to create a git-repository +# based on dist-git. +# +# * Works with fedpkg and rhpkg +# * Different packages are supported. See detect_build_type below. +# * Creates first an initial commit of the source directory (after "fedpkg prep") +# * Excludes files and creates a gitignore file. It does so by .git/makerepo.gitignore +# which can be edited manually. Also, after a `$0 local`, it will record all files +# with modifications to be ignored in the future. +# * Revert each patch from the spec file +# * Reapply each patch until you are where were originally (sans ignored files) +# * Restore again the original state, i.e. replying the patches (including ignored +# files -- that are no longer part of master-tip). +# * Fetch from upstream origin (and add as remote) +# * Fetch from a local git repository (and add as remote) +# * It can detect the parent commit where the package branched of +# and rebase the created history on top of that. +# * optionally, do `fedpkg local`. +# +# ONE-TIME SETUP: +# - clone the dist-git package +# $ PACKAGE=libnl3 +# $ fedpkg clone $PACKAGE +# $ cd $PACKAGE +# +# - configure local git-repository (optional) +# $ ln -s /path/to/local/clone .git/local +# +# - create initial gitignore file (optional) +# $ edit .git/makerepo.gitignore +# or +# $ edit .git/makerepo.gitignore.$BRANCHNAME +# +# USAGE: +# $ cd $PACKAGE +# $ makerepo.sh +# $ makerepo.sh local +# + + +#set -vx + +die() { + echo "$@" >&2 + exit 1 +} + +containsElement () { + local e + local name="$1" + shift + local i=0 + + for e in "${@:2}"; do + if [[ "$e" == "$1" ]]; then + eval "$name=$i" + return 0; + fi + i=$((i+1)) + done + return 1 +} + +git_remote_add_gnome() { + git remote add "${2-origin}" "https://gitlab.gnome.org/GNOME/$1.git" && \ + git remote 'set-url' --push "${2-origin}" "git@gitlab.gnome.org:GNOME/$1.git" +} + +git_remote_add_github() { + git remote add "${2-origin}" "https://github.com/$1.git" + git remote 'set-url' --push "${2-origin}" "git@github.com:$1.git" +} + +srcdir="$(readlink -f "$(git rev-parse --show-toplevel 2>/dev/null)")" +[[ "x$srcdir" != x ]] || die "Could not detect dist-git directory (are you inside the git working directory?)" +cd "$srcdir" || die "Could not switch to dist-git directory" + + +if [[ "x$(ls -1d ./*.spec 2>/dev/null)" == x || ! -f "./sources" ]]; then + die "**Error**: Directory "\`$srcdir\'" does not look like the dist-git pkg dir." +fi + +if [[ "$FEDPKG" == "" ]]; then + REMOTE="$(git config --get "branch.$(git branch --show-current).remote" 2>/dev/null)" + URL="$(git config --get "remote.$REMOTE.url")" + if [[ "$URL" = *'pkgs.devel.redhat.com'* ]]; then + FEDPKG=rhpkg + elif [[ "$URL" = *'gitlab.com'*'redhat/centos-stream'* ]]; then + FEDPKG=centpkg + elif [[ "$URL" = *'pkgs.fedoraproject.org/'* || "$URL" = *'src.fedoraproject.org/'* ]]; then + FEDPKG=fedpkg + else + die "not inside dist-git repository? Check out a branch that has the dist-git remote tracking branch >>$PWD<<" + fi +fi + +split_patch() { + # patches created with git-format-patch that contain more then one + # commit, cannot be easily reverted with patch, because patch works + # the patches from top down. In case of -R however, we have to apply + # the latest patches first. + + read -r -d '' PERL_PROG <<-'EOF' + use strict; + use warnings; + + open FILE, $ARGV[0] or die "Can't open $ARGV[0] for reading: $!\n"; + + local $/ = undef; + my $file = <FILE>; + close FILE; + + my @patches = split(/\n\nFrom /,$file); + + my $i = $#patches + 1; + my $patch; + my $first = 1; + foreach $patch (@patches){ + if ($first) { + $first = 0; + } else { + $patch = "From $patch" + } + my $o = sprintf("%s%s%03d", $ARGV[0], $ARGV[1], $i); + open(my $OUT, ">", $o) or die "Can't open $o for writing: $!"; + $i--; + + print $OUT "$patch"; + + close $OUT; + } + EOF + + perl -e "$PERL_PROG" "$1" "$2" +} + +spec_parse_patch_p() { + local SPEC="$1" + local NUM="$2" + + local P="$(sed -n "s/^%\<patch$NUM\>.* -p\([0-9]\+\) .*$/\1/p" "$SPEC")" + + echo "${P:-1}" +} + +get_patch_origin() { + local PATCH="$1" + + ( + cd "$srcdir" + + local HASH="$(git log -n1 --format="%H" HEAD -- "$PATCH")" + + if [[ "$HASH" == "" ]]; then + return + fi + + printf "\n\nPatch \"%s\" was last modified in commit:\n\n" "$PATCH" + git log -n1 "$HASH" | sed 's/^[^ ]/ \0/' + ) +} + +print_synopsis() { + echo "SYNOPSIS: $(basename "$0") [--dist|-d DIST] [local|--local|-l] [-?|-h|--help|help] [NUM]" + echo " - If [NUM] is omitted, it will revert all patches from the spec file," + echo " otherwise only the last NUM patches." + echo " - When specifying 'local', it will also call \`$FEDPKG local\` to configure" + echo " and build the output directory." + echo " - '--dist' implies '--local'. This argument is passed to ${FEDPKG}." + echo " TIP: symlink your local git clone of upstream to './.git/local'." +} + +unset REVERT_COUNT +LOCAL=0 +DIST="" +while [ $# -ne 0 ]; do + ARG="$1" + shift + case "$ARG" in + -h|'-?'|help|--help) + print_synopsis + exit 0 + ;; + local|--local|-l) + LOCAL=1 + ;; + --dist|-d) + DIST="$1" + shift + if [ "x$DIST" = x ]; then + print_synopsis + die "--dist needs an argument" + fi + ;; + *) + if [ -n "${REVERT_COUNT+x}" ]; then + print_synopsis + die "invalid argument \"$ARG\"" + fi + case "$ARG" in + ''|*[!0-9]*) + print_synopsis + die "invalid argument \"$ARG\": should be an integer (number of patches to revert)" + ;; + esac + REVERT_COUNT="$ARG" + ;; + esac +done + +if [ "x$DIST" != x ]; then + DIST=" --dist $DIST" +fi + +# generate the clean dir +$FEDPKG $DIST prep || die "error while \`$FEDPKG$DIST prep\`" + +detect_build_type() { + local TEST_DIR="./$1/" + local TEST_SPEC="$2" + local TEST_BUILD_TYPE="$3" + local DIRNAME + + if [[ -n "$BUILD_TYPE" || -z "$1" || "x$(ls -1d $TEST_DIR 2>/dev/null)" == x || ! -f "$TEST_SPEC" ]]; then + return 1 + fi + + DIRNAME="$(ls -1d $TEST_DIR)" || die "could not find directory" + DIRNAME="$(basename "$DIRNAME")" + SPEC="$TEST_SPEC" + + if [[ -n "$TEST_BUILD_TYPE" ]]; then + BUILD_TYPE="$TEST_BUILD_TYPE" + else + BUILD_TYPE="${TEST_SPEC%.spec}" + fi +} + +detect_dirname() { + local BUILD_TYPE="$1" + local DIRS=() + local SOURCES + local D suffix T + + SOURCES="$(sed 's/^\(SHA512 (\(.*\)) = [0-9a-f]\{128\}\|\([0-9a-f]\{32\} \+\(.*\)\)\)$/\2\4/' ./sources 2>/dev/null)" + + for suffix in .tar.gz .tar.bz .tar.xz .tgz .tar.bz2 ; do + for T in ${SOURCES[@]}; do + if [[ "$T" == *$suffix ]]; then + D="${T%$suffix}" + [[ -d "$D" ]] && DIRS=("${DIRS[@]}" "$D") + D="$(tar -tf "$T" | sed 's#/.*##' | sort | uniq)" + [[ -d "$D" ]] && DIRS=("${DIRS[@]}" "$D") + fi + done + + # iterate over all tarballs that start with "$BUILD_TYPE" and + # see if there exists a directory with the same name as + # the unpacked tarball (that is, stripping the suffix). + for T in $(ls -1 "$BUILD_TYPE"*"$suffix" 2>/dev/null); do + D="${T%$suffix}" + [[ -d "$D" ]] && DIRS=("${DIRS[@]}" "$D") + done + done + + D= + if [[ ${#DIRS[@]} -ge 1 ]]; then + # return the newest directory. + D="$(ls -1d --sort=time --time=ctime "${DIRS[@]}" 2>/dev/null | head -n1)" + fi + if [[ "$D" != "" ]]; then + printf "%s" "$D" + return 0 + fi + return 1 +} + +BUILD_TYPE= +detect_build_type 'NetworkManager-[0-9]*' NetworkManager.spec +detect_build_type 'network-manager-applet-[0-9]*' network-manager-applet.spec +detect_build_type 'libnl-[0-9]*' libnl3.spec +detect_build_type 'NetworkManager-openvpn-[0-9]*' NetworkManager-openvpn.spec +detect_build_type 'NetworkManager-openswan-[0-9]*' NetworkManager-openswan.spec +detect_build_type 'NetworkManager-libreswan-[0-9]*' NetworkManager-libreswan.spec +detect_build_type 'NetworkManager-vpnc-[0-9]*' NetworkManager-vpnc.spec +detect_build_type 'ModemManager-[0-9]*' ModemManager.spec +detect_build_type 'wireless_tools.[0-9]*' wireless-tools.spec +detect_build_type 'umip-[0-9]*' mipv6-daemon.spec +detect_build_type 'initscripts-[0-9]*' initscripts.spec +detect_build_type 'libqmi-[0-9]*' libqmi.spec +detect_build_type 'libibverbs-[0-9]*' libibverbs.spec +detect_build_type 'iproute2-*' iproute.spec +detect_build_type 'glib-2*' glib2.spec +detect_build_type 'vpnc-*' vpnc.spec +detect_build_type 'gnome-control-center-*' control-center.spec gnome-control-center + +if [[ -z "$BUILD_TYPE" ]]; then + SPEC="$(ls -1 *.spec 2>/dev/null | head -n1)" + BUILD_TYPE="${SPEC%.spec}" + [[ -n "$BUILD_TYPE" ]] || die "Failed to detect repository type (no spec file)" + + [[ -f sources ]] || die "Failed to detect repository type (no sources file)" +fi + +DIRNAME="$(detect_dirname "$BUILD_TYPE")" || die "Failed to detect repository type (no directory)." + +CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null)" +if [[ "x$CURRENT_BRANCH" != x && -f "./.git/makerepo.gitignore-$CURRENT_BRANCH" ]]; then + MAKEREPO_GIT_IGNORE_MY="makerepo.gitignore-$CURRENT_BRANCH" +elif [[ -f ./.git/makerepo.gitignore ]]; then + MAKEREPO_GIT_IGNORE_MY=makerepo.gitignore +else + MAKEREPO_GIT_IGNORE_MY="" +fi +MAKEREPO_GIT_IGNORE_LAST="makerepo.gitignore.last-$CURRENT_BRANCH" + +get_local_mirror() { + local URL="$1" + local DIRNAME + local FULLNAME + + if [[ -z "$URL" ]]; then + return + fi + + [[ -n "$NO_REMOTE" ]] && return + + DIRNAME="${URL##*/}" + DIRNAME="${DIRNAME%.git}" + FULLNAME="$srcdir/.git/.makerepo-${DIRNAME}.git" + + if [ ! -d "$FULLNAME" ] && [ -d "$FULLNAME.git" ]; then + # due to a bug, old versions of the script might have created "*.git.git/" directories. + # rename. + mv "$FULLNAME.git" "$FULLNAME" + fi + + if [[ ! -d "$FULLNAME" ]]; then + if [[ -f "$FULLNAME" ]]; then + # create a file with name $FULLNAME, to suppress local mirroring + return + fi + git clone --mirror --bare "$URL" "$FULLNAME/" + fi + ( + cd "$FULLNAME" + git fetch origin --prune + git gc + ) + echo "$FULLNAME" +} + +pushd "$DIRNAME" + git init . + # if you have a local clone of upstream, symlink it as ../.git/local. + if [[ "$BUILD_TYPE" == "NetworkManager" ]]; then + git remote add origin "https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git" + git remote 'set-url' --push origin "git@gitlab.freedesktop.org:NetworkManager/NetworkManager.git" + git config notes.displayRef refs/notes/bugs + git config --add remote.origin.fetch refs/tags/*:refs/tags/* + git config --add remote.origin.fetch refs/notes/bugs:refs/notes/bugs + elif [[ "$BUILD_TYPE" == "ModemManager" ]]; then + git remote add origin "git://anongit.freedesktop.org/ModemManager/ModemManager" + git remote 'set-url' --push origin "ssh://$USER@git.freedesktop.org/git/ModemManager/ModemManager" + git config --add remote.origin.fetch refs/tags/*:refs/tags/* + elif [[ "$BUILD_TYPE" == "libnl3" ]]; then + git_remote_add_github thom311/libnl + elif [[ "$BUILD_TYPE" == "network-manager-applet" || + "$BUILD_TYPE" == "gnome-control-center" || + "$BUILD_TYPE" == "libnma" || + "$BUILD_TYPE" == "NetworkManager-fortisslvpn" || + "$BUILD_TYPE" == "NetworkManager-libreswan" || + "$BUILD_TYPE" == "NetworkManager-openconnect" || + "$BUILD_TYPE" == "NetworkManager-openvpn" || + "$BUILD_TYPE" == "NetworkManager-pptp" || + "$BUILD_TYPE" == "NetworkManager-vpnc" ]]; then + git_remote_add_gnome "$BUILD_TYPE" + elif [[ "$BUILD_TYPE" == "glib2" ]]; then + git_remote_add_gnome glib + elif [[ "$BUILD_TYPE" == "NetworkManager-openswan" ]]; then + git remote add origin "git://git.gnome.org/network-manager-openswan"; + git remote 'set-url' --push origin "ssh://$USER@git.gnome.org/git/network-manager-openswan" + elif [[ "$BUILD_TYPE" == "wpa_supplicant" ]]; then + git remote add origin "git://w1.fi/hostap.git" + git_remote_add_github NetworkManager/hostap nm + elif [[ "$BUILD_TYPE" == "mipv6-daemon" ]]; then + git remote add origin "git://git.umip.org/umip.git"; + elif [[ "$BUILD_TYPE" == "libqmi" ]]; then + git remote add origin 'git://anongit.freedesktop.org/libqmi'; + elif [[ "$BUILD_TYPE" == "libibverbs" ]]; then + git remote add origin 'git://git.kernel.org/pub/scm/libs/infiniband/libibverbs.git'; + elif [[ "$BUILD_TYPE" == "initscripts" ]]; then + git remote add origin "https://git.fedorahosted.org/git/initscripts.git"; + elif [[ "$BUILD_TYPE" == "iproute" ]]; then + git remote add origin "git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git" + elif [[ "$BUILD_TYPE" == "dracut" ]]; then + git remote add origin "https://github.com/dracutdevs/dracut.git" + elif [[ "$BUILD_TYPE" == "systemd" ]]; then + git remote add origin "https://github.com/systemd/systemd.git" + elif [[ "$BUILD_TYPE" == "vpnc" ]]; then + git_remote_add_github ndpgroup/vpnc + elif [[ "$BUILD_TYPE" == "cloud-init" ]]; then + git remote add origin "https://git.launchpad.net/cloud-init" + elif [[ "$BUILD_TYPE" == "firewalld" ]]; then + git remote add origin "https://github.com/firewalld/firewalld.git" + elif [[ "$BUILD_TYPE" == "nftables" ]]; then + git remote add origin "git://git.netfilter.org/nftables" + elif [[ "$BUILD_TYPE" == "ulogd" ]]; then + git remote add origin "https://git.netfilter.org/ulogd2" + elif [[ "$BUILD_TYPE" == "libnetfilter_log" ]]; then + git remote add origin "https://git.netfilter.org/$BUILD_TYPE" + fi + LOCAL_MIRROR_URL="$(LANG=C git remote -v | sed -n 's/^origin\t*\([^\t].*\) (fetch)/\1/p')" + LOCAL_MIRROR="$(get_local_mirror "$LOCAL_MIRROR_URL")" + if [[ -n "$LOCAL_MIRROR" ]]; then + git remote add local-mirror "$LOCAL_MIRROR" + git fetch local-mirror + fi + LOCAL_GIT="$(readlink -f ../.git/local/)" + if [[ -d "$LOCAL_GIT" ]]; then + git remote add local "$LOCAL_GIT/" + git fetch local + fi + if [[ "$(git remote | grep '^origin$')x" != x && -z "$NO_REMOTE" ]]; then + git fetch origin + if [[ -n "$LOCAL_MIRROR" ]]; then + git remote rm local-mirror + fi + fi + git commit --allow-empty -m '*** empty initial commit' # useful, to rebase the following commit + git add -f -A . + git commit -m '*** add all' + git tag -f ALL + ORIG_HEAD="`git rev-parse HEAD`" + if [[ "x$RELEASE_BASE_COMMIT" == x ]]; then + # if RELEASE_BASE_COMMIT is not set, try detecting the BASE_COMMIT... + + if [[ "$BUILD_TYPE" == "NetworkManager" || + "$BUILD_TYPE" == "NetworkManager-fortisslvpn" || + "$BUILD_TYPE" == "NetworkManager-libreswan" || + "$BUILD_TYPE" == "NetworkManager-pptp" || + "$BUILD_TYPE" == "NetworkManager-openconnect" || + "$BUILD_TYPE" == "NetworkManager-vpnc" ]]; then + RELEASE_BASE_COMMIT="$(sed -n 's/^NM_GIT_SHA=\(.*\)/\1/p' configure 2>/dev/null)" + elif [[ "$BUILD_TYPE" == "libnl3" ]]; then + RELEASE_BASE_COMMIT="$(sed -n 's/^LIBNL_GIT_SHA=\(.*\)/\1/p' configure 2>/dev/null)" + if [[ "$RELEASE_BASE_COMMIT" == "23c44dad998f72f39fd1fc24aa9579fd0a7f05c0" ]]; then + RELEASE_BASE_COMMIT="e01b9df629e2f4f833fdc4fe0bda460bb738d136" + fi + elif [[ "$BUILD_TYPE" == "network-manager-applet" || + "$BUILD_TYPE" == "libnma" ]]; then + RELEASE_BASE_COMMIT="$(sed -n 's/^NMA_GIT_SHA=\(.*\)/\1/p' configure 2>/dev/null)" + if [[ "$RELEASE_BASE_COMMIT" == "8d8e34f22d5fae476eda96cf36d828c3ae8b63d3" ]]; then + RELEASE_BASE_COMMIT="a2377d7534780b96a32405cce2e5548e81bbd081" + fi + elif [[ "$BUILD_TYPE" == "glib2" ]]; then + RELEASE_BASE_COMMIT="$(git rev-parse --verify -q "$(sed 's/.*\<glib-\([0-9]\+\.[0-9]\+\.[0-9]\+\)\.[a-z0-9_.]\+\>.*$/\1/' ../sources)^{commit}" 2>/dev/null)" + elif [[ "$BUILD_TYPE" == "iproute" ]]; then + RELEASE_BASE_COMMIT="$(git rev-parse --verify -q "$(sed 's/.*\<iproute2-\([0-9]\+\.[0-9]\+\.[0-9]\+\)\..*/v\1/' ../sources)^{commit}" 2>/dev/null)" + elif [[ "$BUILD_TYPE" == "NetworkManager-openvpn" ]]; then + RELEASE_BASE_COMMIT="$(sed -n 's/^NM_GIT_SHA=\(.*\)/\1/p' configure 2>/dev/null)" + if [[ "x$RELEASE_BASE_COMMIT" == x ]]; then + DATE="$(sed -n 's/%global snapshot .git\(20[0-3][0-9]\)\([0-1][0-9]\)\([0-3][0-9]\)/\1-\2-\3/p' "../$SPEC")" + if [[ "x$DATE" != x ]]; then + RELEASE_BASE_COMMIT="$(git rev-list -n1 --date-order --before="$DATE" origin/master 2>/dev/null)" + fi + fi + fi + if [[ "x$RELEASE_BASE_COMMIT" == x ]]; then + KNOWN_BASE_COMMITS="$(cat <<EOF +# NetworkManager +08670c9163a5d0f15c57c7891ef899eb125d9423 7251704430cb206f2c29bfebc45bd0fb *NetworkManager-0.9.9.0.git20131003.tar.bz2 + +# ModemManager +397761c9758c3a8c2d130afaf36dab645d6e0ecf d9d93d2961ee35b4cd8a75a6a8631cb4 ModemManager-1.6.0.tar.xz +b23413a064f03fb2f2214fb32164bcb4b7037c45 67160b94c0eda90ebf95d1b620229ca1 ModemManager-1.6.10.tar.xz +526ec556bdf440fce3c48d3127836cf9d0b4501b SHA512 (ModemManager-1.10.8.tar.xz) = c021939322be39e102371219e648d6acb3bc5b48cf570e02113ce559321155bfe5476b4012fd95f878c0a5c5d3b9d88fb19e95adec16a5b62a01581915a39f71 + +# libnl3 +1a510c57e905c4beb06122b9688162c82d9b044f d1111959652bd6ad87b2071f61c8c20c *libnl-doc-3.2.24.tar.gz +83c762d7cf6a6c54831e8d684b22804f497704c4 6fe7136558a9071e70673dcda38545b3 *libnl-3.2.21.tar.gz +c4d846f239036c05f516c1c71789e980b64b1e70 2e1c889494d274aca24ce5f6a748e66e *libnl-3.2.22.tar.gz +0446731124bea8c1b447cc52a5ad5ae5750810ff 636769646f5b81b0caead81eab151b45 *libnl-3.2.25-rc1.tar.gz +bd0e87b3d81d2498c3f35d5497771828bf04e017 e34999eaa184c84b315a8dff8afa4219 libnl-3.2.28-rc1.tar.gz +656f381ccf58785319bb0236595c896125d33ed0 bab12db1eb94a42129f712a44be91a67 libnl-3.2.28.tar.gz + +# NetworkManager-applet +5d4f17e205f71972d4143f9760426a366b4129d7 9cc0e383c216d4bc31622a0cfb53aaa7 *network-manager-applet-0.9.9.0.git20140123.5d4f17e.tar.bz2 +36c868498f09eacafcdce9d6b68ca5aeffaae899 3146f3ac3c30996a96cd2c602fbc81e1 *network-manager-applet-0.9.10.3.git20150511.36c8684.tar.bz2 +2d5b36cf69ea6d5e11726d479012c8ad7d6fd9fc 7fc2ed3f0c46ed41ddabe99d51513b1c *network-manager-applet-1.0.4.tar.xz + +# NetworkManager-libreswan, NetworkManager-openswan +64c90fd50e57854a3fff3784b92814ffa8159b05 6a373868f85ac3b7c953f7fd6c76e637 *NetworkManager-openswan-0.9.8.0.tar.xz +78555150e4df29eb39fa4a105f884f53b0f4523f df9144805f37dc30dfaeab8da762f615 *NetworkManager-openswan-1.0.6.tar.xz +3ef831cf25e86675f9838bf58b1cd6e592c6e14f 01248eb95a1e1d647057a45aed85a3af *NetworkManager-libreswan-1.2.4.tar.xz + +# NetworkManager-vpnc +89bdcd324f2e257eca59168a7d0be5608438aab0 abb26a6c3c8d6c1d91c78471aff86b3a *NetworkManager-vpnc-0.9.8.2.tar.xz +c37a79d43ebe1192ba8dcc5036cd668631b6473e d87db7021629cef7c110a371dd42b7a8 *NetworkManager-vpnc-0.9.9.0.git20140131.tar.bz2 +68ca41550f9289835ea9d80e1ee059322ebe749a 4c16379738264a117d09c171c645ff23 *NetworkManager-vpnc-1.2.2.tar.xz + +# NetworkManager-openvpn +1f159f30617e4a3b8121074b8bf238312941370d 511eae0d4ac17c6d2659a3da2646296f *NetworkManager-openvpn-1.0.2.tar.xz +75585a94b394c04e45a28d2b032fe83dcdaeebee ee4c09a8896eab3e1740f7c7bc1434f9 NetworkManager-openvpn-1.2.4.tar.xz + +# mipv6-daemon +428974c2d0d8e75a2750a3ab0488708c5dfdd8e3 8e3ebd242e7926822bbdf5ce77c1d076 *mipv6-daemon-1.0.tar.gz + +# libqmi +7d688f382f9756027bf92338e413e425365d2835 17d6c2b404ee1eb4d1e60050fef64491 *libqmi-1.6.0.tar.xz +49abf405f5e9f16542476dceeb20de6029edcf1c SHA512 (libqmi-1.24.0.tar.xz) = e899765e67c1db0f758030e78b296015c476f938bb2afa01594b3e71a0b8d5fc2237c8272497aec891d5555523ecf0fecd69c4d0e14165c07072780621b3b502 + +# gnome-control-center +e87e0361b117f055ace2aa47cdddd0dc62a852f9 da949e268254af6aafdda0e8c1702384 *gnome-control-center-3.22.1.tar.xz + +# wpa_supplicant +22760dd94722a61175ff90c59d88c4cda1ed5e23 3be2ebfdcced52e00eda0afe2889839d *wpa_supplicant-2.0.tar.gz + +# libibverbs +990ca025d0ad967b6f266bae700bf82a4ceaff1a 1fe85889c8bbc4968b1feba6524ca408 *libibverbs-1.1.8.tar.gz + +# initscripts +cc304f05edab6c408a0f061eb1a104f9f06b8587 86ef789876b65c61751ce854835b91d4 initscripts-9.49.35.tar.bz2 + +# dracut +00efe708cab023bfe6eaf530d8ac8ea97b440de2 SHA512 (dracut-050.tar.xz) = 9d9a66acfd6b9d2fd50855a59a2393e0602c2ef97119db046f68d6167ea84d1423fa465b8b4d96339febb38d5a96df26dec7862c4b3397c3d726db18d280eee4 + +# systemd +903dd65b5eb63257393955cb79777beb8c71afc1 SHA512 (systemd-253-rc1.tar.gz) = aaf0a6bf21bbc50a42015c9cb17f69d1aaf6cab6cabfba5140a94212fb864e38d638dace9a70447f62b4d2a817a0d3bd6f4ae8d9b3c2e741cdeb1cb332f70b65 + +# libnetfilter_log +97866a0a7482ca518bad39536c7c667bfb9604b2 2a4bb0654ae675a52d2e8d1c06090b94 libnetfilter_log-1.0.1.tar.bz2 +b0e4be94c0b8f68d4e912402b93a130063c34e17 SHA512 (libnetfilter_log-1.0.2.tar.bz2) = 6b33718b1dd7f4504bceae14001da3a652cec46a6725a5dee83a7b55028cfa8e768cba917f968a5d5b60fd9ff04edf6040ef271a68e5fb65858bf73f4f9ccf23 + +# ulogd +79aa980f2df9dda0c097e8f883a62f414b9e5138 SHA512 (ulogd-2.0.8.tar.bz2) = 9f99f6f35bad5da4559d788dc3ba3dae17d4ae972737cae3313ecf68f08eaf5f55514fce6f30503437e4158fd30a06438b9249d5d20f6343964cbf690f87309d +EOF +)" + OLDIFS="$IFS" + IFS=$'\n' + for KNOWN_BASE_COMMIT in $KNOWN_BASE_COMMITS; do + MATCH="$(echo "$KNOWN_BASE_COMMIT" | sed -n 's/^[0-9a-f]\{40\} \+\(.*\)$/\1/p')" + if [[ "x$MATCH" == x ]]; then + continue + fi + if grep -q "$MATCH" ../sources; then + RELEASE_BASE_COMMIT="$(echo "$KNOWN_BASE_COMMIT" | awk '{print $1}')" + break + fi + done + IFS="$OLDIFS" + fi + fi + if [[ x != "x$RELEASE_BASE_COMMIT" ]]; then + if [[ "$RELEASE_BASE_COMMIT" == "-" ]]; then + # you can disable detection of the RELEASE_BASE_COMMIT by setting it to '-' + RELEASE_BASE_COMMIT= + else + # verify the base commit... + RELEASE_BASE_COMMIT2="$(git rev-parse --verify -q "$RELEASE_BASE_COMMIT^{commit}" 2>/dev/null)" + [[ x == "x$RELEASE_BASE_COMMIT2" ]] && test -z "$NO_REMOTE" && die "error detecting RELEASE_BASE_COMMIT=$RELEASE_BASE_COMMIT" + RELEASE_BASE_COMMIT="$RELEASE_BASE_COMMIT2" + fi + fi + if [[ x != "x$RELEASE_BASE_COMMIT" ]]; then + git checkout -B master "$RELEASE_BASE_COMMIT" || die "could not checkout master" + git tag -f BASE + git rm --cached -r :/ + git checkout "$ORIG_HEAD" -- :/ + git clean -fdx :/ + git commit -m '*** add all' + git tag -f ALL + [[ x == "x$(git diff HEAD "$ORIG_HEAD")" ]] || die "error recreating initial tarball" + fi + ( + if [[ -n "$MAKEREPO_GIT_IGNORE_MY" ]]; then + cat "../.git/$MAKEREPO_GIT_IGNORE_MY" + fi + if [[ -f "../.git/$MAKEREPO_GIT_IGNORE_LAST" ]]; then + cat "../.git/$MAKEREPO_GIT_IGNORE_LAST" + fi + sed -n 's/^%patch\([0-9]\+\) \+.*-b \+\([^ ]\+\).*$/*\2/p' ../"$SPEC"; + echo '*.[0-9][0-9][0-9][0-9][-.]*.orig' + ) | LANG=C sort | LANG=C uniq > .gitignore + + git rm --cached -r . + git add --all . + git commit -m "*** clean state (ignored files removed)" + git tag -f CLEAN + + if [[ "$REVERT_COUNT" == "" || $REVERT_COUNT -gt 0 ]]; then + + # parse the list of patches + IFS=$'\n' read -rd '' -a PATCH_LIST <<<"$(sed -n 's/^Patch\([0-9]\+\):[ ]\+\(.*\)$/\1 \2/p' ../"$SPEC" | sort -n)" + + if [[ "$BUILD_TYPE" == "NetworkManager" ]]; then + if containsElement idx "123 rh1085015-applet-translations.patch" "${PATCH_LIST[@]}"; then + # for rhel-6, NetworkManager contains some patches that break the script. In this + # case, truncate the list of what we would normally revert. + PATCH_LIST=("${PATCH_LIST[@]:$((idx+1))}") + fi + fi + + # truncate the list of patches to revert/reapply + if [[ "$REVERT_COUNT" == "" || "$REVERT_COUNT" -gt ${#PATCH_LIST[@]} ]]; then + echo "revert all ${#PATCH_LIST[@]} patches" + else + echo "revert the last $REVERT_COUNT patches of ${#PATCH_LIST[@]}" + PATCH_LIST=("${PATCH_LIST[@]:$((${#PATCH_LIST[@]} - $REVERT_COUNT))}") + fi + + # split the list in index and patch file name + PATCH_LIST_N=() + for i in ${!PATCH_LIST[@]}; do + LAST_PATCH_N[$i]=$(echo "${PATCH_LIST[$i]}" | sed -n 's/^\([0-9]\+\) \+.*$/\1/p') + LAST_PATCH[$i]=$( echo "${PATCH_LIST[$i]}" | sed -n 's/^\([0-9]\+\) \+\(.*\)$/\2/p') + done + + # revert and patches in reverse order... + BASECOMMIT=("`git rev-parse HEAD`") + for j in "${!PATCH_LIST[@]}"; do + i=$((${#PATCH_LIST[@]} - $j - 1)) + echo "revert Patch${LAST_PATCH_N[$i]} \"${LAST_PATCH[$i]}\"..." + PNUM="$(spec_parse_patch_p "../$SPEC" "${LAST_PATCH_N[$i]}")" + patch -f --no-backup-if-mismatch -R "-p$PNUM" < "../${LAST_PATCH[$i]}" || ( + # error applying patch. Maybe we have a multi line patch... + + rm -f "../${LAST_PATCH[$i]}".makerepo-split.* + split_patch "../${LAST_PATCH[$i]}" ".makerepo-split." + + git reset --hard + git clean -fdx + for p in "../${LAST_PATCH[$i]}".makerepo-split.*; do + echo ">>> try split part $p for ${LAST_PATCH[$i]}" + patch --no-backup-if-mismatch -R "-p$PNUM" < "$p" || die "error reverting Patch${LAST_PATCH_N[$i]} ${LAST_PATCH[$i]}" + done + ) + git add --all . + git commit --allow-empty -a -m "<< revert Patch${LAST_PATCH_N[$i]} \"${LAST_PATCH[$i]}\"$(get_patch_origin "${LAST_PATCH[$i]}")" + BASECOMMIT=("`git rev-parse HEAD`" "${BASECOMMIT[@]}") + git tag -f REVERT"${LAST_PATCH_N[$i]}" + done + + # reapply the patches + for i in ${!PATCH_LIST[@]}; do + echo "reapply Patch${LAST_PATCH_N[$i]} \"${LAST_PATCH[$i]}\"..." + + # create an empty commit, indicating the commit before starting to reapply + BASECOMMIT_REVERT="${BASECOMMIT[$((i))]}" + COMMIT_MSG="$(git log -n1 --format='%s%n%n%b' "$BASECOMMIT_REVERT" | sed '1s/<< revert \(Patch.*"\)$/-- before reapplying \1/')" + git commit --allow-empty -m "$COMMIT_MSG" + git tag -f "BEFORE_PATCH${LAST_PATCH_N[$i]}" + git tag -f "LAST0" + + # first try git-am to preserve the commit message, otherwise just revert the last commit + if git am "../${LAST_PATCH[$i]}"; then + # The tree to the version before should be identical after reapplying the patch. + # Just to be sure, reset the commit. + git reset "${BASECOMMIT[$((i+1))]}" -- . + COMMIT_MSG="$(git log -n1 --format='%s%n%n%b' "$BASECOMMIT_REVERT" | sed '1s/<< revert \(Patch.*"\)$/-- after reapplying \1\n\ngit-am did not fully restore the previous state/')" + git commit -m "$COMMIT_MSG" || echo "NOTHING TO COMMIT" + else + git am --abort + git reset "${BASECOMMIT[$((i+1))]}" -- . + COMMIT_MSG="$(git log -n1 --format='%s%n%n%b' "$BASECOMMIT_REVERT" | sed '1s/<< revert \(Patch.*"\)$/>> reapply \1/')" + git commit --allow-empty -m "$COMMIT_MSG" + fi + git reset --hard HEAD + git clean -fdx + [[ x = "x$(git diff "${BASECOMMIT[$((i+1))]}" HEAD)" ]] || die "error reverting patch" + git tag -f PATCH"${LAST_PATCH_N[$i]}" + done + git tag -f LAST + fi + git checkout "$ORIG_HEAD" -- . + git checkout HEAD~ -- .gitignore + git reset + + git gc +popd + +if [[ $LOCAL != 0 ]]; then + rm -rf ./.makerepo.git/ + mv "$DIRNAME/.git" ./.makerepo.git/ + $FEDPKG $DIST local -- --noclean + mv ./.makerepo.git/ "$DIRNAME/.git" + pushd "$DIRNAME" + git checkout -- .gitignore + + # write git-ignore file... + git status --porcelain | sed 's/^...//' >> "../.git/$MAKEREPO_GIT_IGNORE_LAST" + popd +fi + +echo SUCCESS; |