From aa1b57c59d530694a4b9c0321797b6b3e5d51551 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Apr 23 2020 22:47:32 +0000 Subject: import nmstate-0.2.6-6.el8 --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..15ecebb --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +SOURCES/gpgkey-F7910D93CA83D77348595C0E899014C0463C12BB.gpg +SOURCES/nmstate-0.2.6.tar.gz diff --git a/.nmstate.metadata b/.nmstate.metadata new file mode 100644 index 0000000..75ddca6 --- /dev/null +++ b/.nmstate.metadata @@ -0,0 +1,2 @@ +7bcc63976a8d449b3adc57f40d7a476106889042 SOURCES/gpgkey-F7910D93CA83D77348595C0E899014C0463C12BB.gpg +9da848bd1955e436235fa89239e3f55535593211 SOURCES/nmstate-0.2.6.tar.gz diff --git a/SOURCES/BZ_1806249-ActiveConnection-Handle-uninitialized-device.patch b/SOURCES/BZ_1806249-ActiveConnection-Handle-uninitialized-device.patch new file mode 100644 index 0000000..604032f --- /dev/null +++ b/SOURCES/BZ_1806249-ActiveConnection-Handle-uninitialized-device.patch @@ -0,0 +1,93 @@ +From 60dd21358c94c7bae08410100af99cd5eb34ecc6 Mon Sep 17 00:00:00 2001 +From: Fernando Fernandez Mancera +Date: Mon, 2 Mar 2020 14:30:09 +0100 +Subject: [PATCH] ActiveConnection: Handle uninitialized device + +Handle `ActiveConnection._nmdev` being None. This should fix a Traceback +when the openvswitch service is not running: + +Traceback (most recent call last): + File "/usr/lib/python3.6/site-packages/libnmstate/nm/connection.py", line 226, in _active_connection_callback + ac.devname, ac.reason + File "/usr/lib/python3.6/site-packages/libnmstate/nm/active_connection.py", line 171, in devname + return self._nmdev.get_iface() +AttributeError: 'NoneType' object has no attribute 'get_iface' + +Signed-off-by: Fernando Fernandez Mancera +--- + libnmstate/nm/active_connection.py | 16 +++++++++------- + libnmstate/nm/connection.py | 2 +- + 2 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/libnmstate/nm/active_connection.py b/libnmstate/nm/active_connection.py +index 7b70b2a..c81ee2b 100644 +--- a/libnmstate/nm/active_connection.py ++++ b/libnmstate/nm/active_connection.py +@@ -1,5 +1,5 @@ + # +-# Copyright (c) 2019 Red Hat, Inc. ++# Copyright (c) 2019-2020 Red Hat, Inc. + # + # This file is part of nmstate + # +@@ -86,7 +86,7 @@ class ActiveConnection: + if self._mainloop.is_action_canceled(e): + logging.debug( + "Connection deactivation aborted on %s: error=%s", +- self._nmdev.get_iface(), ++ self.devname, + e, + ) + else: +@@ -105,20 +105,19 @@ class ActiveConnection: + else: + self._mainloop.quit( + "Connection deactivation failed on {}: " +- "error={}".format(self._nmdev.get_iface(), e) ++ "error={}".format(self.devname, e) + ) + return + + if success: + logging.debug( +- "Connection deactivation succeeded on %s", +- self._nmdev.get_iface(), ++ "Connection deactivation succeeded on %s", self.devname, + ) + self._mainloop.execute_next_action() + else: + self._mainloop.quit( + "Connection deactivation failed on %s: error=unknown" +- % self._nmdev.get_iface() ++ % self.devname + ) + + @property +@@ -168,7 +167,10 @@ class ActiveConnection: + + @property + def devname(self): +- return self._nmdev.get_iface() ++ if self._nmdev: ++ return self._nmdev.get_iface() ++ else: ++ return None + + @property + def nmdevice(self): +diff --git a/libnmstate/nm/connection.py b/libnmstate/nm/connection.py +index 3dc1ee1..2076734 100644 +--- a/libnmstate/nm/connection.py ++++ b/libnmstate/nm/connection.py +@@ -223,7 +223,7 @@ class ConnectionProfile: + else: + self._mainloop.quit( + "Connection activation failed on {}: reason={}".format( +- ac.devname, ac.reason ++ devname, ac.reason + ) + ) + +-- +2.24.1 + diff --git a/SOURCES/BZ_1809330-Bond-mode-change.patch b/SOURCES/BZ_1809330-Bond-mode-change.patch new file mode 100644 index 0000000..195677a --- /dev/null +++ b/SOURCES/BZ_1809330-Bond-mode-change.patch @@ -0,0 +1,135 @@ +From b78579503ac16b9f7c71a023532fcb5f1586bc1d Mon Sep 17 00:00:00 2001 +From: Gris Ge +Date: Mon, 9 Mar 2020 22:16:18 +0800 +Subject: [PATCH] nm applier: only create ethernet when explicitly + +Creating ethernet configuration when user not requested will +cause two major problems: + * Adding slave to newly create bridge will cause bridge link down. + * Cannot switch bond mode from 1(active-backup) to 5(balance-tlb). + +To fix the problem, only create ethernet/wired setting when user +explicitly requested. + +Remove the xfail of test case for changing bond mode from 1(active-backup) +to 5(balance-tlb). + +Remove the workaround in test case for adding slave to newly created +bridge without link state down. + +Add test case showing old ethernet configuration will not be removed when +desire state does not include so. + +Signed-off-by: Gris Ge +--- + libnmstate/netapplier.py | 8 +++++--- + libnmstate/nm/applier.py | 31 ++++++++++++++++++++++++++----- + 2 files changed, 31 insertions(+), 8 deletions(-) + +diff --git a/libnmstate/netapplier.py b/libnmstate/netapplier.py +index cc6b6e3..d9d10cf 100644 +--- a/libnmstate/netapplier.py ++++ b/libnmstate/netapplier.py +@@ -152,7 +152,9 @@ def _apply_ifaces_state( + state2edit = _create_editable_desired_state( + desired_state, current_state, new_interfaces + ) +- ifaces2edit, ifaces_edit_configs = _edit_interfaces(state2edit) ++ ifaces2edit, ifaces_edit_configs = _edit_interfaces( ++ state2edit, original_desired_state ++ ) + nm.applier.set_ifaces_admin_state( + ifaces2add + ifaces2edit, + con_profiles=ifaces_add_configs + ifaces_edit_configs, +@@ -231,7 +233,7 @@ def _add_interfaces(new_interfaces, desired_state): + return (ifaces2add, ifaces_configs) + + +-def _edit_interfaces(state2edit): ++def _edit_interfaces(state2edit, original_desired_state): + logging.debug("Editing interfaces: %s", list(state2edit.interfaces)) + + ifaces2edit = list(state2edit.interfaces.values()) +@@ -244,7 +246,7 @@ def _edit_interfaces(state2edit): + ) + proxy_ifaces = nm.applier.prepare_proxy_ifaces_desired_state(iface2prepare) + ifaces_configs = nm.applier.prepare_edited_ifaces_configuration( +- iface2prepare + proxy_ifaces ++ iface2prepare + proxy_ifaces, original_desired_state + ) + nm.applier.edit_existing_ifaces(ifaces_configs) + +diff --git a/libnmstate/nm/applier.py b/libnmstate/nm/applier.py +index 77e869e..8d31e35 100644 +--- a/libnmstate/nm/applier.py ++++ b/libnmstate/nm/applier.py +@@ -69,7 +69,10 @@ def prepare_new_ifaces_configuration(ifaces_desired_state): + ) + + return [ +- _build_connection_profile(iface_desired_state) ++ _build_connection_profile( ++ iface_desired_state, ++ original_desired_iface_state=iface_desired_state, ++ ) + for iface_desired_state in ifaces_desired_state + ] + +@@ -89,7 +92,9 @@ def edit_existing_ifaces(con_profiles): + connection_profile.add(save_to_disk=True) + + +-def prepare_edited_ifaces_configuration(ifaces_desired_state): ++def prepare_edited_ifaces_configuration( ++ ifaces_desired_state, original_desired_state ++): + con_profiles = [] + + for iface_desired_state in ifaces_desired_state: +@@ -101,8 +106,13 @@ def prepare_edited_ifaces_configuration(ifaces_desired_state): + if nmdev: + cur_con_profile = connection.ConnectionProfile() + cur_con_profile.import_by_device(nmdev) ++ original_desired_iface_state = original_desired_state.interfaces.get( ++ ifname, {} ++ ) + new_con_profile = _build_connection_profile( +- iface_desired_state, base_con_profile=cur_con_profile ++ iface_desired_state, ++ base_con_profile=cur_con_profile, ++ original_desired_iface_state=original_desired_iface_state, + ) + if not new_con_profile.devname: + set_conn = new_con_profile.profile.get_setting_connection() +@@ -366,7 +376,14 @@ def _generate_hash_iface_name(name): + return name_[:MAXIMUM_INTERFACE_LENGTH].decode() + + +-def _build_connection_profile(iface_desired_state, base_con_profile=None): ++def _build_connection_profile( ++ iface_desired_state, ++ base_con_profile=None, ++ original_desired_iface_state=None, ++): ++ if original_desired_iface_state is None: ++ original_desired_iface_state = {} ++ + iface_type = translator.Api2Nm.get_iface_type( + iface_desired_state[Interface.TYPE] + ) +@@ -401,7 +418,11 @@ def _build_connection_profile(iface_desired_state, base_con_profile=None): + con_setting.set_master(master, master_type) + settings.append(con_setting.setting) + +- wired_setting = wired.create_setting(iface_desired_state, base_profile) ++ # Only apply wired/ethernet configuration based on original desire ++ # state rather than the merged one. ++ wired_setting = wired.create_setting( ++ original_desired_iface_state, base_profile ++ ) + if wired_setting: + settings.append(wired_setting) + +-- +2.18.2 + diff --git a/SOURCES/BZ_1809330-Fix-bond-regression.patch b/SOURCES/BZ_1809330-Fix-bond-regression.patch new file mode 100644 index 0000000..698f258 --- /dev/null +++ b/SOURCES/BZ_1809330-Fix-bond-regression.patch @@ -0,0 +1,96 @@ +From 58ea1d895fbc7bf474153274a05cc4fad8fa44f4 Mon Sep 17 00:00:00 2001 +From: Gris Ge +Date: Wed, 11 Mar 2020 10:37:03 +0800 +Subject: [PATCH] nm bond: workaround on miimon=100 option + +The NM will ignore the `miimon=100`(the default option) when +wired/ethernet setting not included due to bug: + https://bugzilla.redhat.com/show_bug.cgi?id=1806549 + +This cause verification error when user try to set `miimon=100` on +existing bond. + +To workaround that, always include `miimon` option when querying bond +options. + +Integration test case included. + +Signed-off-by: Gris Ge + +In addition: + +nm applier: Sort interface creation/modification order + +The bond or bridge will take its first slave's MAC address, hence +NetworkManager by default will activate the slaves in the order of its +interface name. + +When nmstate create or editing bond/bridge, the `autoconnect` feature +will cause NetworkManager activating the slaves in unexpected order +which then generate different MAC address of bond and bridge. + +To fix this problem, sort the interface creation and modification order. + +Signed-off-by: Gris Ge +--- + libnmstate/nm/applier.py | 13 +++++++++++-- + libnmstate/nm/bond.py | 3 +++ + tests/integration/bond_test.py | 8 ++++++++ + tests/lib/nm/applier_test.py | 24 +++++++++++++++++------- + 4 files changed, 39 insertions(+), 9 deletions(-) + +diff --git a/libnmstate/nm/applier.py b/libnmstate/nm/applier.py +index 8d31e35..1291469 100644 +--- a/libnmstate/nm/applier.py ++++ b/libnmstate/nm/applier.py +@@ -20,6 +20,7 @@ + import base64 + import hashlib + import itertools ++from operator import attrgetter + + from libnmstate.error import NmstateValueError + from libnmstate.schema import Interface +@@ -57,7 +58,11 @@ IFACE_NAME_METADATA = "_iface_name" + + + def create_new_ifaces(con_profiles): +- for connection_profile in con_profiles: ++ # By default, NetworkManager will activate the slave profiles in the order ++ # of sorted interface name. To make sure user get the same MAC address ++ # after reboot for bond/bridge/etc, sort the interfaces to be created ++ # as autoconnect=True will activate the profile at the creation time. ++ for connection_profile in sorted(con_profiles, key=attrgetter("con_id")): + connection_profile.add(save_to_disk=True) + + +@@ -78,7 +83,11 @@ def prepare_new_ifaces_configuration(ifaces_desired_state): + + + def edit_existing_ifaces(con_profiles): +- for connection_profile in con_profiles: ++ # By default, NetworkManager will activate the slave profiles in the order ++ # of sorted interface name. To make sure user get the same MAC address ++ # after reboot for bond/bridge/etc, sort the interfaces to be updated ++ # as autoconnect=True will activate the profile at the profile update time. ++ for connection_profile in sorted(con_profiles, key=attrgetter("con_id")): + devname = connection_profile.devname + nmdev = device.get_device_by_name(devname) + cur_con_profile = None +diff --git a/libnmstate/nm/bond.py b/libnmstate/nm/bond.py +index b1291c4..310ef6e 100644 +--- a/libnmstate/nm/bond.py ++++ b/libnmstate/nm/bond.py +@@ -86,6 +86,9 @@ def _get_options(nm_device): + if option == "arp_ip_target": + value = value.replace(" ", ",") + options[option] = value ++ # Workaround of https://bugzilla.redhat.com/show_bug.cgi?id=1806549 ++ if "miimon" not in options: ++ options["miimon"] = bond_setting.get_option_default("miimon") + return options + + +-- +2.24.1 + diff --git a/SOURCES/BZ_1815112-Support-static-dns-on-DHCP.patch b/SOURCES/BZ_1815112-Support-static-dns-on-DHCP.patch new file mode 100644 index 0000000..41e960c --- /dev/null +++ b/SOURCES/BZ_1815112-Support-static-dns-on-DHCP.patch @@ -0,0 +1,103 @@ +From fd503cdcfb8138b1c181916050c4c0d5cc826ae7 Mon Sep 17 00:00:00 2001 +From: Gris Ge +Date: Thu, 19 Mar 2020 22:14:12 +0800 +Subject: [PATCH] dns: support static DNS with dynamic IP + +Added the support of static DNS configuration with dynamic IP interface as +long as specified interface has `InterfaceIP.AUTO_DNS` set to False. + +When choosing interface to storing DNS configuration, the interface with +static address and gateway is preferred over dynamic interface with +`InterfaceIP.AUTO_DNS` set to False. + +Added Unit test cases and integration test cases. + +Signed-off-by: Gris Ge +--- + libnmstate/metadata.py | 6 +----- + libnmstate/nm/dns.py | 34 +++++++++++++++++++++++++++++----- + 2 files changed, 30 insertions(+), 10 deletions(-) + +diff --git a/libnmstate/metadata.py b/libnmstate/metadata.py +index 37d6b96..b268ba3 100644 +--- a/libnmstate/metadata.py ++++ b/libnmstate/metadata.py +@@ -242,12 +242,8 @@ def _generate_dns_metadata(desired_state, current_state): + if _dns_config_not_changed(desired_state, current_state): + _preserve_current_dns_metadata(desired_state, current_state) + else: +- ifaces_routes = { +- ifname: [r.to_dict() for r in routes] +- for ifname, routes in desired_state.config_iface_routes.items() +- } + ipv4_iface, ipv6_iface = nm.dns.find_interfaces_for_name_servers( +- ifaces_routes ++ desired_state + ) + _save_dns_metadata( + desired_state, +diff --git a/libnmstate/nm/dns.py b/libnmstate/nm/dns.py +index 008b034..0ab28e4 100644 +--- a/libnmstate/nm/dns.py ++++ b/libnmstate/nm/dns.py +@@ -27,6 +27,8 @@ from libnmstate.nm import active_connection as nm_ac + from libnmstate.nm import route as nm_route + from libnmstate.schema import DNS + from libnmstate.schema import Interface ++from libnmstate.schema import InterfaceIP ++from libnmstate.schema import InterfaceIPv6 + + + DNS_DEFAULT_PRIORITY_VPN = 50 +@@ -123,17 +125,26 @@ def get_dns_config_iface_names(acs_and_ipv4_profiles, acs_and_ipv6_profiles): + return iface_names + + +-def find_interfaces_for_name_servers(iface_routes): ++def find_interfaces_for_name_servers(desired_state): + """ + Find interfaces to store the DNS configurations: + * Interface with static gateway configured. ++ * Interface with dynamic IP and auto-dns: False. + Return two interface names for IPv4 and IPv6 name servers. + The interface name will be None if failed to find proper interface. + """ +- return ( +- nm_route.get_static_gateway_iface(Interface.IPV4, iface_routes), +- nm_route.get_static_gateway_iface(Interface.IPV6, iface_routes), +- ) ++ iface_routes = { ++ ifname: [r.to_dict() for r in routes] ++ for ifname, routes in desired_state.config_iface_routes.items() ++ } ++ ipv4_iface = nm_route.get_static_gateway_iface( ++ Interface.IPV4, iface_routes ++ ) or _get_auto_dns_false_iface(Interface.IPV4, desired_state.interfaces) ++ ++ ipv6_iface = nm_route.get_static_gateway_iface( ++ Interface.IPV6, iface_routes ++ ) or _get_auto_dns_false_iface(Interface.IPV6, desired_state.interfaces) ++ return ipv4_iface, ipv6_iface + + + def get_indexed_dns_config_by_iface( +@@ -179,3 +190,16 @@ def _get_ip_profile_dns_config(ip_profile): + DNS.SEARCH: ip_profile.props.dns_search, + DNS_METADATA_PRIORITY: ip_profile.props.dns_priority, + } ++ ++ ++def _get_auto_dns_false_iface(family, iface_states): ++ for iface_name, iface_state in iface_states.items(): ++ ip_state = iface_state.get(family, {}) ++ if ip_state.get(InterfaceIP.ENABLED) and not ip_state.get( ++ InterfaceIP.AUTO_DNS ++ ): ++ if ip_state.get(InterfaceIP.DHCP) or ip_state.get( ++ InterfaceIPv6.AUTOCONF ++ ): ++ return iface_name ++ return None +-- +2.18.2 + diff --git a/SOURCES/BZ_1816043_Support_3_nameserver.patch b/SOURCES/BZ_1816043_Support_3_nameserver.patch new file mode 100644 index 0000000..8307d8f --- /dev/null +++ b/SOURCES/BZ_1816043_Support_3_nameserver.patch @@ -0,0 +1,45 @@ +From e4bfd9436500aa26dcc82d346039e8b1b886d64c Mon Sep 17 00:00:00 2001 +From: Gris Ge +Date: Wed, 25 Mar 2020 11:27:55 +0800 +Subject: [PATCH] dns: Enable support of 3+ unmixed DNS name server + +Support 3 or more IPv4/IPv6 only DNS name servers. +Still not supported 3+ IPv4 and IPv6 mixed name servers. + +A warning will be emitted when 4 or more DNS name severs defined. + +Integration test cases added. + +Signed-off-by: Gris Ge +--- + libnmstate/validator.py | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/libnmstate/validator.py b/libnmstate/validator.py +index a817930..0e61858 100644 +--- a/libnmstate/validator.py ++++ b/libnmstate/validator.py +@@ -166,9 +166,18 @@ def validate_dns(state): + dns_servers = ( + state.get(DNS.KEY, {}).get(DNS.CONFIG, {}).get(DNS.SERVER, []) + ) +- if len(dns_servers) > 2: ++ if len(dns_servers) > 3: ++ logging.warning( ++ "The libc resolver may not support more than 3 nameservers." ++ ) ++ if ( ++ len(dns_servers) > 2 ++ and any(is_ipv6_address(n) for n in dns_servers) ++ and any(not is_ipv6_address(n) for n in dns_servers) ++ ): + raise NmstateNotImplementedError( +- "Nmstate only support at most 2 DNS name servers" ++ "Three or more nameservers are only supported when using " ++ "either IPv4 or IPv6 nameservers but not both." + ) + + +-- +2.18.2 + diff --git a/SOURCES/nmstate-0.2.6.tar.gz.asc b/SOURCES/nmstate-0.2.6.tar.gz.asc new file mode 100644 index 0000000..80b3de2 --- /dev/null +++ b/SOURCES/nmstate-0.2.6.tar.gz.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2.0.22 (GNU/Linux) + +iQIcBAABAgAGBQJeVA3fAAoJEImQFMBGPBK7ZckQAJ3jBlRhfrcx/3c6W/oHdxNG +KK5k1pgWFbrYlNtg8KG7Oey19EBaZCtGKTo76nwYqW0826bFpX2XaEpYwtesD445 +aAKCa09PfTTHKI1fL1M86I8qUHuMNLnT2bYvVZRgyAIp4RV+6rc+1F20bVSf0diy +UX6n+J3bBOZQ+Vlr4YP6RVAf0JW+KFTXgQC4O7ssHxGHOAQAUTiwhO6dOqDlvI/0 +RkDXg2axyYHJCoh8pH4hXC6j6N9D63xjl7tlNCqICYyens+A+PRWgVDXkwoxQRB1 +b3pLwN8Cm9VClzB5EQmhoEQOyVfR0B2+y+QMr9wqPfDlW5r81Blvg/ZZ7/ahlVUI +fcY1J7/nMcHCMBFtnXAYlgpexYrZ/GGb7zKGAMczQMYhIoz07dyG0F7Ltk1+8g50 +RJP0fvmxDDmnhDwEWr8Sac+PmV8TAqkyNi1/54yL6ajZ1Vk1S+0Yg11vMT+IW6Q5 +SZv1udqombL7Yo3W7ta+ynP8ncZoS3Y9bHQito7O7N93wZrUFTc/X8UxhI/7Nrgv +YtQD2FT8FqTkSUK28TQyx0I51VG8PnXeeOAFgNwih30k6OoXtvHFDXLnAc+RlNBD +XxSbfPSuFxPzaexcxmdLfZKq+xcJqS7osEs0PFkOCPNuS4uDymEEsv7aC4GexWuS +bam/Yy2TBZtkDRZE3QEE +=o/C+ +-----END PGP SIGNATURE----- diff --git a/SPECS/nmstate.spec b/SPECS/nmstate.spec new file mode 100644 index 0000000..66686ff --- /dev/null +++ b/SPECS/nmstate.spec @@ -0,0 +1,182 @@ +%?python_enable_dependency_generator +%define srcname nmstate +%define libname libnmstate + +Name: nmstate +Version: 0.2.6 +Release: 6%{?dist} +Summary: Declarative network manager API +License: LGPLv2+ +URL: https://github.com/%{srcname}/%{srcname} +Source0: %{url}/releases/download/v%{version}/%{srcname}-%{version}.tar.gz +Source1: %{url}/releases/download/v%{version}/%{srcname}-%{version}.tar.gz.asc +Source2: gpgkey-F7910D93CA83D77348595C0E899014C0463C12BB.gpg +Patch1: BZ_1806249-ActiveConnection-Handle-uninitialized-device.patch +Patch2: BZ_1809330-Bond-mode-change.patch +Patch3: BZ_1809330-Fix-bond-regression.patch +Patch4: BZ_1815112-Support-static-dns-on-DHCP.patch +Patch5: BZ_1816043_Support_3_nameserver.patch +BuildArch: noarch +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: gnupg2 +Requires: python3-setuptools +Requires: python3-%{libname} = %{?epoch:%{epoch}:}%{version}-%{release} + +%description +Nmstate is a library with an accompanying command line tool that manages host +networking settings in a declarative manner and aimed to satisfy enterprise +needs to manage host networking through a northbound declarative API and multi +provider support on the southbound. + + +%package -n python3-%{libname} +Summary: nmstate Python 3 API library +Requires: NetworkManager-libnm >= 1:1.22 +# Use Recommends for NetworkManager because only access to NM DBus is required, +# but NM could be running on a different host +Recommends: NetworkManager +# Avoid automatically generated profiles +Recommends: NetworkManager-config-server +# Use Suggests for NetworkManager-ovs and NetworkManager-team since it is only +# required for OVS and team support +Suggests: NetworkManager-ovs +Suggests: NetworkManager-team + + +%description -n python3-%{libname} +This package contains the Python 3 library for nmstate. + +%prep +gpgv2 --keyring %{SOURCE2} %{SOURCE1} %{SOURCE0} +%autosetup -p1 + +%build +%py3_build + +%install +%py3_install + +%files +%doc README.md +%doc examples/ +%{_mandir}/man8/nmstatectl.8* +%{python3_sitelib}/nmstatectl +%{_bindir}/nmstatectl + +%files -n python3-%{libname} +%license LICENSE +%{python3_sitelib}/%{libname} +%{python3_sitelib}/%{srcname}-*.egg-info/ + +%changelog +* Wed Mar 25 2020 Gris Ge - 0.2.6-6 +- Support 3+ DNS name server(IPv4 only or IPv6 only). RHBZ #1816043 + +* Fri Mar 20 2020 Gris Ge - 0.2.6-5 +- Support static DNS with DHCP. RHBZ #1815112 + +* Thu Mar 12 2020 Fernando Fernandez Mancera - 0.2.6-4.8 +- Fix bond mac and options regression. RHBZ #1809330 + +* Mon Mar 09 2020 Gris Ge - 0.2.6-3.8 +- Fix change bond mode. RHBZ #1809330 + +* Mon Mar 02 2020 Fernando Fernandez Mancera - 0.2.6-2.7 +- Fix cmd stuck when trying to create ovs-bond. RHBZ #1806249. + +* Tue Feb 25 2020 Gris Ge - 0.2.6-1 +- Upgrade to 0.2.6 + +* Thu Feb 20 2020 Gris Ge - 0.2.5-1 +- Upgrade to 0.2.5 + +* Thu Feb 13 2020 Gris Ge - 0.2.4-2 +- Fix failure when editing existing OVS interface. RHBZ #1786935 + +* Thu Feb 13 2020 Gris Ge - 0.2.4-1 +- Upgrade to 0.2.4 + +* Wed Feb 05 2020 Fernando Fernandez Mancera - 0.2.3-1 +- Upgrade to 0.2.3 + +* Tue Feb 04 2020 Fernando Fernandez Mancera - 0.2.2-3 +- Fix the incorrect source + +* Tue Feb 04 2020 Fernando Fernandez Mancera - 0.2.2-2 +- Upgrade to 0.2.2 + +* Wed Jan 22 2020 Gris Ge - 0.2.0-3.1 +- Fix the memeory leak of NM.Client. RHBZ #1784707 + +* Mon Dec 02 2019 Gris Ge - 0.2.0-2 +- Fix the incorrect source tarbal. + +* Mon Dec 02 2019 Gris Ge - 0.2.0-1 +- Upgrade to nmstate 0.2.0 + +* Mon Dec 02 2019 Gris Ge - 0.1.1-4 +- Fix the problem found by CI gating. + +* Mon Dec 02 2019 Gris Ge - 0.1.1-3 +- Bump dist number as RHEL 8.1.1 took 0.1.1-2. + +* Mon Dec 02 2019 Gris Ge - 0.1.1-2 +- Upgrade to nmstate 0.1.1. + +* Tue Sep 10 2019 Gris Ge - 0.0.8-15 +- Detach slaves without deleting them: RHBZ #1749632 + +* Fri Sep 06 2019 Gris Ge - 0.0.8-14 +- Preserve (dynamic) IPv6 address base on MAC address: RHBZ #1748825 + +* Fri Sep 06 2019 Gris Ge - 0.0.8-13 +- Prioritize master interfaces activaction: RHBZ #1749314 + +* Mon Sep 02 2019 Gris Ge - 0.0.8-12 +- Fix slave activatoin race: RHBZ #1741440 + +* Mon Sep 02 2019 Gris Ge - 0.0.8-10 +- Fix RHBZ #1740125 + +* Wed Aug 14 2019 Gris Ge - 0.0.8-9 +- Fix RHBZ #1741049 + +* Wed Aug 14 2019 Gris Ge - 0.0.8-8 +- Fix RHBZ #1740584 + +* Tue Aug 13 2019 Gris Ge - 0.0.8-7 +- Fix RHBZ #1740554 + +* Tue Aug 13 2019 Gris Ge - 0.0.8-6 +- Bump release tag as CNV took the -5. + +* Tue Aug 13 2019 Gris Ge - 0.0.8-5 +- Bump release tag as CNV took the -4. + +* Tue Aug 13 2019 Gris Ge - 0.0.8-4 +- Disable reapply on ipv6 to fix bug 1738101. + +* Fri Jul 26 2019 Gris Ge - 0.0.8-3 +- Fix the license to meet Fedora/RHEL guideline. + +* Fri Jul 26 2019 Gris Ge - 0.0.8-2 +- Relicense to LGPL2.1+. + +* Fri Jul 26 2019 Gris Ge - 0.0.8-1 +- Upgrade to 0.0.8. + +* Fri Jun 14 2019 Gris Ge - 0.0.7-1 +- Upgrade to 0.0.7. + +* Mon Apr 22 2019 Gris Ge - 0.0.5-3 +- Add missing runtime dependency. + +* Thu Mar 21 2019 Gris Ge - 0.0.5-2 +- Rebuild to enable CI testing. + +* Mon Mar 18 2019 Gris Ge - 0.0.5-1 +- Initial release