From 4e4f28b3c37d4adfce6a161fa31d8cf8466d6a7a Mon Sep 17 00:00:00 2001 From: eabdullin Date: Wed, 27 Sep 2023 13:45:35 +0000 Subject: [PATCH] import CS nmstate-1.4.4-3.el8 --- .gitignore | 5 +- .nmstate.metadata | 5 +- ...when-creating-profile-if-not-desired.patch | 66 -- SOURCES/BZ_2160416-fix-SRIOV.patch | 206 ------ ...ip-Support-static-route-with-auto-ip.patch | 183 +++++ SOURCES/Enable_clib_yml_api.patch | 636 ------------------ SOURCES/nmstate-1.4.2.tar.gz.asc | 16 - SOURCES/nmstate-1.4.4.tar.gz.asc | 16 + SOURCES/nmstate.gpg | 51 ++ SPECS/nmstate.spec | 20 +- 10 files changed, 269 insertions(+), 935 deletions(-) delete mode 100644 SOURCES/BZ_2160416-Ignore-error-when-creating-profile-if-not-desired.patch delete mode 100644 SOURCES/BZ_2160416-fix-SRIOV.patch create mode 100644 SOURCES/BZ_2203277-ip-Support-static-route-with-auto-ip.patch delete mode 100644 SOURCES/Enable_clib_yml_api.patch delete mode 100644 SOURCES/nmstate-1.4.2.tar.gz.asc create mode 100644 SOURCES/nmstate-1.4.4.tar.gz.asc create mode 100644 SOURCES/nmstate.gpg diff --git a/.gitignore b/.gitignore index c4e9e56..82c44e1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ -SOURCES/nmstate-1.4.2.tar.gz -SOURCES/nmstate-vendor-1.4.2.tar.xz -SOURCES/nmstate.gpg +SOURCES/nmstate-1.4.4.tar.gz +SOURCES/nmstate-vendor-1.4.4.tar.xz diff --git a/.nmstate.metadata b/.nmstate.metadata index 4736678..e49bbc8 100644 --- a/.nmstate.metadata +++ b/.nmstate.metadata @@ -1,3 +1,2 @@ -165eba0069da41758442f1d2efa8cae180417882 SOURCES/nmstate-1.4.2.tar.gz -0815a374c7acca14db28b47347e43797d4b3d570 SOURCES/nmstate-vendor-1.4.2.tar.xz -5c1d9d65f9db4fedc9dc96e0fb6cac0a86749c88 SOURCES/nmstate.gpg +17340fe66e024e69e4c051e6a1bbd3d1974ca4ed SOURCES/nmstate-1.4.4.tar.gz +91a01d73ca8db5e882defaabc7529e97f4dd596a SOURCES/nmstate-vendor-1.4.4.tar.xz diff --git a/SOURCES/BZ_2160416-Ignore-error-when-creating-profile-if-not-desired.patch b/SOURCES/BZ_2160416-Ignore-error-when-creating-profile-if-not-desired.patch deleted file mode 100644 index f7aa1d6..0000000 --- a/SOURCES/BZ_2160416-Ignore-error-when-creating-profile-if-not-desired.patch +++ /dev/null @@ -1,66 +0,0 @@ -From d7d732332e486cd8969ff4b5ef95a24cb68b5441 Mon Sep 17 00:00:00 2001 -From: Gris Ge -Date: Mon, 27 Feb 2023 12:17:05 +0800 -Subject: [PATCH] nm: Ignore error when creating profile if not desired - -When a undesired interface holding `autoconf: true` and `dhcp: false` -for IPv6, nmstate will fail with error: - - Autoconf without DHCP is not supported yet - -This is caused by `nm/connection.py` try to create `NM.SimpleConnection` -for every interface even not desired. - -This patch changed to: - * Only create new `NM.SimpleConnection` when desired or changed. - * Use current profile if exists when not desired or changed. - * Ignore error if not desired/changed. - -Integration test case included. - -Signed-off-by: Gris Ge ---- - libnmstate/nm/profile.py | 20 +++++++++++++++++--- - 1 file changed, 17 insertions(+), 3 deletions(-) - -diff --git a/libnmstate/nm/profile.py b/libnmstate/nm/profile.py -index ad1ad19f..1119cd1a 100644 ---- a/libnmstate/nm/profile.py -+++ b/libnmstate/nm/profile.py -@@ -24,6 +24,7 @@ from distutils.version import StrictVersion - import logging - import time - -+from libnmstate.error import NmstateError - from libnmstate.error import NmstateInternalError - from libnmstate.error import NmstateLibnmError - from libnmstate.error import NmstateNotSupportedError -@@ -321,9 +322,22 @@ class NmProfile: - # TODO: Use applied config as base profile - # Or even better remove the base profile argument as top level - # of nmstate should provide full/merged configure. -- self._nm_simple_conn = create_new_nm_simple_conn( -- self._iface, self._nm_profile -- ) -+ if self._iface.is_changed or self._iface.is_desired: -+ self._nm_simple_conn = create_new_nm_simple_conn( -+ self._iface, self._nm_profile -+ ) -+ elif self._nm_profile: -+ self._nm_simple_conn = NM.SimpleConnection.new_clone( -+ self._nm_profile -+ ) -+ else: -+ try: -+ self._nm_simple_conn = create_new_nm_simple_conn( -+ self._iface, self._nm_profile -+ ) -+ # No error for undesired interface -+ except NmstateError: -+ pass - - def save_config(self, save_to_disk): - self._check_sriov_support() --- -2.39.2 - diff --git a/SOURCES/BZ_2160416-fix-SRIOV.patch b/SOURCES/BZ_2160416-fix-SRIOV.patch deleted file mode 100644 index 30d63d2..0000000 --- a/SOURCES/BZ_2160416-fix-SRIOV.patch +++ /dev/null @@ -1,206 +0,0 @@ -From d410b928c8f2a22d42d1974b62ab5b3164861184 Mon Sep 17 00:00:00 2001 -From: Gris Ge -Date: Thu, 23 Feb 2023 13:06:01 +0800 -Subject: [PATCH] nm: Fix error on SR-IOV - -When SR-IOV VF naming scheme is like `ens1f0v0`, nmstate will delete -the VF NM connection when applying this state: - -```yml ---- -interfaces: -- name: ens1f0 - type: ethernet - state: up - ethernet: - sr-iov: - total-vfs: 1 -- name: ens1f0v0 - type: ethernet - state: up - ipv4: - enabled: false - ipv6: - enabled: false -``` - -This is because `delete_other_profiles()` is checking -`self._nm_profile()` from active NM profile instead of newly created -one. The fix is using newly created profile `self._nm_simple_conn`. - -We also have race problem when activating PF along with VF, PF -activation might delete VF NIC which cause VF activation failed. To -workaround that, we activate PF first via `NmProfile.ACTION_SRIOV_PF` -and wait on it before start VF activation. - -Also problem found during SR-IOV investigations is we do extra -un-required modification to `NM.SettingOvsExternalIDs` even it is not -mentioned in desired. We skip overriding `NM.SettingOvsExternalIDs` when -not desired. - -Existing test case can cover the use cases. - -Signed-off-by: Gris Ge ---- - libnmstate/ifaces/ifaces.py | 18 +++++++++++++++++- - libnmstate/netapplier.py | 20 +++++++++++--------- - libnmstate/nm/connection.py | 2 +- - libnmstate/nm/profile.py | 12 ++++++++++-- - 4 files changed, 39 insertions(+), 13 deletions(-) - -diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py -index 828ff578..470dc0e6 100644 ---- a/libnmstate/ifaces/ifaces.py -+++ b/libnmstate/ifaces/ifaces.py -@@ -157,6 +157,23 @@ class Ifaces: - def has_vf_count_change_and_missing_eth(self): - return self._has_vf_count_change() and self._has_missing_veth() - -+ def has_sriov_iface(self): -+ for iface in self.all_kernel_ifaces.values(): -+ if (iface.is_desired or iface.is_changed) and iface.is_up: -+ cur_iface = self._cur_kernel_ifaces.get(iface.name) -+ if ( -+ cur_iface -+ and cur_iface.raw.get(Ethernet.CONFIG_SUBTREE, {}).get( -+ Ethernet.SRIOV_SUBTREE, {} -+ ) -+ ) or iface.original_desire_dict.get( -+ Ethernet.CONFIG_SUBTREE, {} -+ ).get( -+ Ethernet.SRIOV_SUBTREE, {} -+ ): -+ return True -+ return False -+ - def _has_vf_count_change(self): - for iface in self.all_kernel_ifaces.values(): - cur_iface = self._cur_kernel_ifaces.get(iface.name) -@@ -664,7 +681,6 @@ class Ifaces: - return None - - def get_cur_iface(self, iface_name, iface_type): -- - iface = self._cur_kernel_ifaces.get(iface_name) - if iface and iface_type in (None, InterfaceType.UNKNOWN, iface.type): - return iface -diff --git a/libnmstate/netapplier.py b/libnmstate/netapplier.py -index ae909126..50a70a9c 100644 ---- a/libnmstate/netapplier.py -+++ b/libnmstate/netapplier.py -@@ -104,7 +104,7 @@ def apply( - pf_net_state, - verify_change, - save_to_disk, -- has_sriov_pf=True, -+ VERIFY_RETRY_COUNT_SRIOV, - ) - # Refresh the current state - current_state = show_with_plugins( -@@ -120,8 +120,16 @@ def apply( - current_state, - save_to_disk, - ) -+ -+ if net_state.ifaces.has_sriov_iface(): -+ # If SR-IOV is present, the verification timeout is being increased -+ # to avoid timeouts due to slow drivers like i40e. -+ verify_retry = VERIFY_RETRY_COUNT_SRIOV -+ else: -+ verify_retry = VERIFY_RETRY_COUNT -+ - _apply_ifaces_state( -- plugins, net_state, verify_change, save_to_disk, has_sriov_pf=False -+ plugins, net_state, verify_change, save_to_disk, verify_retry - ) - if commit: - destroy_checkpoints(plugins, checkpoints) -@@ -154,7 +162,7 @@ def rollback(*, checkpoint=None): - - - def _apply_ifaces_state( -- plugins, net_state, verify_change, save_to_disk, has_sriov_pf=False -+ plugins, net_state, verify_change, save_to_disk, verify_retry - ): - for plugin in plugins: - # Do not allow plugin to modify the net_state for future verification -@@ -163,12 +171,6 @@ def _apply_ifaces_state( - - verified = False - if verify_change: -- if has_sriov_pf: -- # If SR-IOV is present, the verification timeout is being increased -- # to avoid timeouts due to slow drivers like i40e. -- verify_retry = VERIFY_RETRY_COUNT_SRIOV -- else: -- verify_retry = VERIFY_RETRY_COUNT - for _ in range(verify_retry): - try: - _verify_change(plugins, net_state) -diff --git a/libnmstate/nm/connection.py b/libnmstate/nm/connection.py -index 1fbb380b..6448e372 100644 ---- a/libnmstate/nm/connection.py -+++ b/libnmstate/nm/connection.py -@@ -240,7 +240,7 @@ def create_new_nm_simple_conn(iface, nm_profile): - InterfaceType.OVS_PORT, - ) - or iface.type == InterfaceType.OVS_BRIDGE -- ): -+ ) and OvsDB.OVS_DB_SUBTREE in iface.original_desire_dict: - nm_setting = create_ovsdb_external_ids_setting( - iface_info.get(OvsDB.OVS_DB_SUBTREE, {}) - ) -diff --git a/libnmstate/nm/profile.py b/libnmstate/nm/profile.py -index 53eaebed..ad1ad19f 100644 ---- a/libnmstate/nm/profile.py -+++ b/libnmstate/nm/profile.py -@@ -56,6 +56,7 @@ ROUTE_REMOVED = "_route_removed" - class NmProfile: - # For unmanged iface and desired to down - ACTION_ACTIVATE_FIRST = "activate_first" -+ ACTION_SRIOV_PF = "activate_sriov_pf" - ACTION_DEACTIVATE = "deactivate" - ACTION_DEACTIVATE_FIRST = "deactivate_first" - ACTION_DELETE_DEVICE = "delete_device" -@@ -77,6 +78,7 @@ class NmProfile: - ACTION_ACTIVATE_FIRST, - ACTION_DEACTIVATE_FIRST, - ACTION_TOP_CONTROLLER, -+ ACTION_SRIOV_PF, - ACTION_NEW_IFACES, - ACTION_OTHER_CONTROLLER, - ACTION_NEW_OVS_PORT, -@@ -181,6 +183,11 @@ class NmProfile: - else: - self._add_action(NmProfile.ACTION_NEW_IFACES) - else: -+ if ( -+ self._nm_dev.props.capabilities -+ & NM.DeviceCapabilities.SRIOV -+ ): -+ self._add_action(NmProfile.ACTION_SRIOV_PF) - if self._iface.type == InterfaceType.OVS_PORT: - self._add_action(NmProfile.ACTION_MODIFIED_OVS_PORT) - if self._iface.type == InterfaceType.OVS_INTERFACE: -@@ -462,6 +469,7 @@ class NmProfile: - - def do_action(self, action): - if action in ( -+ NmProfile.ACTION_SRIOV_PF, - NmProfile.ACTION_MODIFIED, - NmProfile.ACTION_MODIFIED_OVS_PORT, - NmProfile.ACTION_MODIFIED_OVS_IFACE, -@@ -559,8 +567,8 @@ class NmProfile: - or nm_profile.get_connection_type() == self._nm_iface_type - ) - and ( -- self._nm_profile is None -- or nm_profile.get_uuid() != self._nm_profile.get_uuid() -+ self._nm_simple_conn is None -+ or nm_profile.get_uuid() != self._nm_simple_conn.get_uuid() - ) - ): - ProfileDelete( --- -2.39.2 - diff --git a/SOURCES/BZ_2203277-ip-Support-static-route-with-auto-ip.patch b/SOURCES/BZ_2203277-ip-Support-static-route-with-auto-ip.patch new file mode 100644 index 0000000..44b8fd5 --- /dev/null +++ b/SOURCES/BZ_2203277-ip-Support-static-route-with-auto-ip.patch @@ -0,0 +1,183 @@ +0001-covscan-Remove-dead-code.patch +0002-Run-cargo-clippy.patch +0003-ip-Support-static-route-with-auto-ip.patch +0004-test-Refresh-the-expired-CA-keys.patch +From 6ea4790a368260b43c207d19f20c728698ac2184 Mon Sep 17 00:00:00 2001 +From: Gris Ge +Date: Tue, 25 Apr 2023 14:52:59 +0800 +Subject: [PATCH 1/4] covscan: Remove dead code + +Removing the dead code found by covscan. + +Signed-off-by: Gris Ge +--- + libnmstate/dns.py | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/libnmstate/dns.py b/libnmstate/dns.py +index 853ece80..043c74a5 100644 +--- a/libnmstate/dns.py ++++ b/libnmstate/dns.py +@@ -173,7 +173,6 @@ class DnsState: + }, + }, + } +- return {} + + def _find_ifaces_for_name_servers( + self, ifaces, route_state, ignored_dns_ifaces +-- +2.40.1 + + +From 0329b87b7856e244a4a2d34864a6e6eefa49b226 Mon Sep 17 00:00:00 2001 +From: Gris Ge +Date: Fri, 19 May 2023 17:57:51 +0800 +Subject: [PATCH 2/4] Run cargo clippy + +Signed-off-by: Gris Ge +--- + rust/src/lib/nispor/linux_bridge.rs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/rust/src/lib/nispor/linux_bridge.rs b/rust/src/lib/nispor/linux_bridge.rs +index c03f03d6..c4cd104b 100644 +--- a/rust/src/lib/nispor/linux_bridge.rs ++++ b/rust/src/lib/nispor/linux_bridge.rs +@@ -63,7 +63,7 @@ pub(crate) fn append_bridge_port_config( + port_confs.push(port_conf); + } + +- if let Some(mut br_conf) = br_iface.bridge.as_mut() { ++ if let Some(br_conf) = br_iface.bridge.as_mut() { + br_conf.port = Some(port_confs); + } + } +-- +2.40.1 + + +From 7c80a3acdb67eb09c3dcbeee7138315b3f855c7f Mon Sep 17 00:00:00 2001 +From: Gris Ge +Date: Fri, 19 May 2023 18:12:54 +0800 +Subject: [PATCH 3/4] ip: Support static route with auto ip + +Supporting assigning static route to interface with auto ip. For +example: + +```yml +--- +interfaces: + - name: eth1 + type: ethernet + state: up + ipv4: + dhcp: true + enabled: true + ipv6: + dhcp: true + autoconf: true + enabled: true +routes: + config: + - destination: 198.51.100.0/24 + metric: 150 + next-hop-address: 192.0.2.1 + next-hop-interface: eth1 + table-id: 254 + - destination: 2001:db8:2::/64 + metric: 151 + next-hop-address: 2001:db8:1::2 + next-hop-interface: eth1 +``` + +Integration test case included and been marked as tier1. + +Signed-off-by: Gris Ge +--- + libnmstate/route.py | 52 ++++++------- + tests/integration/dynamic_ip_test.py | 105 +++++++++++++++++++-------- + tests/lib/route_test.py | 28 +------ + 3 files changed, 105 insertions(+), 80 deletions(-) + +diff --git a/libnmstate/route.py b/libnmstate/route.py +index d3734279..c92cbbb6 100644 +--- a/libnmstate/route.py ++++ b/libnmstate/route.py +@@ -1,21 +1,4 @@ +-# +-# Copyright (c) 2020 Red Hat, Inc. +-# +-# This file is part of nmstate +-# +-# This program is free software: you can redistribute it and/or modify +-# it under the terms of the GNU Lesser General Public License as published by +-# the Free Software Foundation, either version 2.1 of the License, or +-# (at your option) any later version. +-# +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU Lesser General Public License for more details. +-# +-# You should have received a copy of the GNU Lesser General Public License +-# along with this program. If not, see . +-# ++# SPDX-License-Identifier: LGPL-2.1-or-later + + from collections import defaultdict + import logging +@@ -146,13 +129,6 @@ class RouteEntry(StateEntry): + f"Route {self.to_dict()} next hop to down/absent interface" + ) + return False +- if iface.is_dynamic( +- Interface.IPV6 if self.is_ipv6 else Interface.IPV4 +- ): +- self._invalid_reason = ( +- f"Route {self.to_dict()} next hop to interface with dynamic IP" +- ) +- return False + if self.is_ipv6: + if not iface.is_ipv6_enabled(): + self._invalid_reason = ( +@@ -194,7 +170,10 @@ class RouteState: + rt = RouteEntry(entry) + self._cur_routes[rt.next_hop_interface].add(rt) + if not ifaces or rt.is_valid(ifaces): +- self._routes[rt.next_hop_interface].add(rt) ++ # When user converting static IP to auto IP, we should ++ # not merge current static routes besides desired ones. ++ if not iface_switch_from_static_to_auto_ip(ifaces, rt): ++ self._routes[rt.next_hop_interface].add(rt) + else: + logging.debug( + f"The current route {entry} has been discarded due" +@@ -299,3 +278,24 @@ class RouteState: + {Route.KEY: {Route.CONFIG: cur_routes_info}}, + ) + ) ++ ++ ++def iface_switch_from_static_to_auto_ip(ifaces, rt): ++ iface_name = rt.next_hop_interface ++ if not iface_name or not ifaces: ++ return False ++ ++ if is_ipv6_address(rt.destination): ++ family = Interface.IPV6 ++ else: ++ family = Interface.IPV4 ++ ++ cur_iface = ifaces.get_cur_iface(iface_name, None) ++ des_iface = ifaces.get_iface(iface_name, None) ++ if ( ++ cur_iface ++ and des_iface ++ and not cur_iface.is_dynamic(family) ++ and des_iface.is_dynamic(family) ++ ): ++ return True +-- +2.40.1 + diff --git a/SOURCES/Enable_clib_yml_api.patch b/SOURCES/Enable_clib_yml_api.patch deleted file mode 100644 index ed8cf9f..0000000 --- a/SOURCES/Enable_clib_yml_api.patch +++ /dev/null @@ -1,636 +0,0 @@ -From ad2bfa136290e72cdfd4b7877b49b3fc07203f9c Mon Sep 17 00:00:00 2001 -From: Gris Ge -Date: Tue, 21 Feb 2023 16:26:22 +0800 -Subject: [PATCH] clib: Introduce YAML support - -Allowing both YAML and JSON input, the output format will matching input -format. - -For `nmstate_net_state_retrieve()`, user can use -`NMSTATE_FLAG_YAML_OUTPUT` flag to instruct the output to be YAML -format. - -Signed-off-by: Gris Ge ---- - rust/src/clib/Cargo.toml | 1 + - rust/src/clib/apply.rs | 2 +- - rust/src/clib/gen_conf.rs | 52 +++++++----- - rust/src/clib/nmstate.h.in | 55 +++++++------ - rust/src/clib/policy.rs | 57 ++++++++----- - rust/src/clib/query.rs | 49 ++++++++---- - .../{nmpolicy_test.c => nmpolicy_json_test.c} | 5 ++ - rust/src/clib/test/nmpolicy_yaml_test.c | 80 +++++++++++++++++++ - .../{nmstate_test.c => nmstate_json_test.c} | 5 ++ - rust/src/clib/test/nmstate_yaml_test.c | 34 ++++++++ - rust/src/lib/Cargo.toml | 3 + - rust/src/lib/net_state.rs | 14 +++- - 12 files changed, 274 insertions(+), 83 deletions(-) - rename rust/src/clib/test/{nmpolicy_test.c => nmpolicy_json_test.c} (96%) - create mode 100644 rust/src/clib/test/nmpolicy_yaml_test.c - rename rust/src/clib/test/{nmstate_test.c => nmstate_json_test.c} (87%) - create mode 100644 rust/src/clib/test/nmstate_yaml_test.c - -diff --git a/rust/src/clib/Cargo.toml b/rust/src/clib/Cargo.toml -index 97e4128c..ed391b3a 100644 ---- a/rust/src/clib/Cargo.toml -+++ b/rust/src/clib/Cargo.toml -@@ -16,6 +16,7 @@ crate-type = ["cdylib", "staticlib"] - nmstate = { path = "../lib", default-features = false } - libc = "0.2.74" - serde_json = "1.0" -+serde_yaml = "0.9" - log = "0.4.17" - serde = { version = "1.0.137", features = ["derive"] } - once_cell = "1.12.0" -diff --git a/rust/src/clib/apply.rs b/rust/src/clib/apply.rs -index 9a0d6fbc..67d39730 100644 ---- a/rust/src/clib/apply.rs -+++ b/rust/src/clib/apply.rs -@@ -74,7 +74,7 @@ pub extern "C" fn nmstate_net_state_apply( - }; - - let mut net_state = -- match nmstate::NetworkState::new_from_json(net_state_str) { -+ match nmstate::NetworkState::new_from_yaml(net_state_str) { - Ok(n) => n, - Err(e) => { - unsafe { -diff --git a/rust/src/clib/gen_conf.rs b/rust/src/clib/gen_conf.rs -index f63fb7b0..1ad7156b 100644 ---- a/rust/src/clib/gen_conf.rs -+++ b/rust/src/clib/gen_conf.rs -@@ -68,7 +68,7 @@ pub extern "C" fn nmstate_generate_configurations( - } - }; - -- let net_state = match nmstate::NetworkState::new_from_json(net_state_str) { -+ let net_state = match nmstate::NetworkState::new_from_yaml(net_state_str) { - Ok(n) => n, - Err(e) => { - unsafe { -@@ -80,28 +80,44 @@ pub extern "C" fn nmstate_generate_configurations( - } - }; - -+ let input_is_json = -+ serde_json::from_str::(net_state_str).is_ok(); - let result = net_state.gen_conf(); - unsafe { - *log = CString::new(logger.drain(now)).unwrap().into_raw(); - } - match result { -- Ok(s) => match serde_json::to_string(&s) { -- Ok(cfgs) => unsafe { -- *configs = CString::new(cfgs).unwrap().into_raw(); -- NMSTATE_PASS -- }, -- Err(e) => unsafe { -- *err_msg = -- CString::new(format!("serde_json::to_string failure: {e}")) -- .unwrap() -- .into_raw(); -- *err_kind = -- CString::new(format!("{}", nmstate::ErrorKind::Bug)) -- .unwrap() -- .into_raw(); -- NMSTATE_FAIL -- }, -- }, -+ Ok(s) => { -+ let serialize = if input_is_json { -+ serde_json::to_string(&s).map_err(|e| { -+ nmstate::NmstateError::new( -+ nmstate::ErrorKind::Bug, -+ format!("Failed to convert state {s:?} to JSON: {e}"), -+ ) -+ }) -+ } else { -+ serde_yaml::to_string(&s).map_err(|e| { -+ nmstate::NmstateError::new( -+ nmstate::ErrorKind::Bug, -+ format!("Failed to convert state {s:?} to YAML: {e}"), -+ ) -+ }) -+ }; -+ -+ match serialize { -+ Ok(cfgs) => unsafe { -+ *configs = CString::new(cfgs).unwrap().into_raw(); -+ NMSTATE_PASS -+ }, -+ Err(e) => unsafe { -+ *err_msg = -+ CString::new(e.msg().to_string()).unwrap().into_raw(); -+ *err_kind = -+ CString::new(e.kind().to_string()).unwrap().into_raw(); -+ NMSTATE_FAIL -+ }, -+ } -+ } - Err(e) => { - unsafe { - *err_msg = CString::new(e.msg()).unwrap().into_raw(); -diff --git a/rust/src/clib/nmstate.h.in b/rust/src/clib/nmstate.h.in -index 0879d47e..391477fd 100644 ---- a/rust/src/clib/nmstate.h.in -+++ b/rust/src/clib/nmstate.h.in -@@ -1,19 +1,4 @@ --/* -- * Copyright 2021 Red Hat -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- -+// SPDX-License-Identifier: Apache-2.0 - - #ifndef _LIBNMSTATE_H_ - #define _LIBNMSTATE_H_ -@@ -44,6 +29,7 @@ extern "C" { - #define NMSTATE_FLAG_NO_COMMIT 1 << 5 - #define NMSTATE_FLAG_MEMORY_ONLY 1 << 6 - #define NMSTATE_FLAG_RUNNING_CONFIG_ONLY 1 << 7 -+#define NMSTATE_FLAG_YAML_OUTPUT 1 << 8 - - /** - * nmstate_net_state_retrieve - Retrieve network state -@@ -52,7 +38,7 @@ extern "C" { - * 0.1 - * - * Description: -- * Retrieve network state in the format of JSON. -+ * Retrieve network state in the format of JSON or YAML. - * - * @flags: - * Flags for special use cases: -@@ -60,6 +46,13 @@ extern "C" { - * No flag - * * NMSTATE_FLAG_KERNEL_ONLY - * Do not use external plugins, show kernel status only. -+ * * NMSTATE_FLAG_INCLUDE_SECRETS -+ * No not hide sercerts like password. -+ * * NMSTATE_FLAG_RUNNING_CONFIG_ONLY -+ * Only include running config excluding running status like auto -+ * IP addresses and routes, LLDP neighbors. -+ * * NMSTATE_FLAG_YAML_OUTPUT -+ * Show the state in YAML format - * @state: - * Output pointer of char array for network state in json format. - * The memory should be freed by nmstate_net_state_free(). -@@ -90,7 +83,7 @@ int nmstate_net_state_retrieve(uint32_t flags, char **state, char **log, - * 0.1 - * - * Description: -- * Apply network state in the format of JSON. -+ * Apply network state in the format of JSON or YAML. - * - * @flags: - * Flags for special use cases: -@@ -98,8 +91,12 @@ int nmstate_net_state_retrieve(uint32_t flags, char **state, char **log, - * No flag - * * NMSTATE_FLAG_KERNEL_ONLY - * Do not use external plugins, apply to kernel only. -+ * * NMSTATE_FLAG_NO_VERIFY -+ * Do not verify state after applied - * * NMSTATE_FLAG_NO_COMMIT - * Do not commit new state after verification -+ * * NMSTATE_FLAG_MEMORY_ONLY -+ * No not store network state to persistent. - * @state: - * Pointer of char array for network state in json format. - * @log: -@@ -119,7 +116,8 @@ int nmstate_net_state_retrieve(uint32_t flags, char **state, char **log, - * * NMSTATE_FAIL - * On failure. - */ --int nmstate_net_state_apply(uint32_t flags, const char *state, uint32_t rollback_timeout, char **log, -+int nmstate_net_state_apply(uint32_t flags, const char *state, -+ uint32_t rollback_timeout, char **log, - char **err_kind, char **err_msg); - - /** -@@ -151,8 +149,8 @@ int nmstate_net_state_apply(uint32_t flags, const char *state, uint32_t rollback - * * NMSTATE_FAIL - * On failure. - */ --int nmstate_checkpoint_commit(const char *checkpoint, char **log, char **err_kind, -- char **err_msg); -+int nmstate_checkpoint_commit(const char *checkpoint, char **log, -+ char **err_kind, char **err_msg); - - /** - * nmstate_checkpoint_rollback - Rollback the checkpoint -@@ -183,8 +181,8 @@ int nmstate_checkpoint_commit(const char *checkpoint, char **log, char **err_kin - * * NMSTATE_FAIL - * On failure. - */ --int nmstate_checkpoint_rollback(const char *checkpoint, char **log, char **err_kind, -- char **err_msg); -+int nmstate_checkpoint_rollback(const char *checkpoint, char **log, -+ char **err_kind, char **err_msg); - - /** - * nmstate_generate_configurations - Generate network configurations -@@ -199,9 +197,10 @@ int nmstate_checkpoint_rollback(const char *checkpoint, char **log, char **err_k - * as value. - * - * @state: -- * Pointer of char array for network state in json format. -+ * Pointer of char array for network state in JSON or YAML format. - * @configs: -- * Output pointer of char array for network configures in json format. -+ * Output pointer of char array for network configures in JSON or -+ * YAML(depend on which format you use in @state) format. - * The memory should be freed by nmstate_net_state_free(). - * @log: - * Output pointer of char array for logging. -@@ -231,14 +230,14 @@ int nmstate_generate_configurations(const char *state, char **configs, - * 2.2 - * - * Description: -- * Generate new network state from policy again specifed state -+ * Generate new network state from policy again specified state - * - * @policy: -- * Pointer of char array for network policy in json format. -+ * Pointer of char array for network policy in JSON/YAML format. - * @current_state: - * Pointer of char array for current network state. - * @state: -- * Output pointer of char array for network state in json format. -+ * Output pointer of char array for network state in JSON/YAML format. - * The memory should be freed by nmstate_net_state_free(). - * @log: - * Output pointer of char array for logging. -diff --git a/rust/src/clib/policy.rs b/rust/src/clib/policy.rs -index ec8c46c1..ea7dd036 100644 ---- a/rust/src/clib/policy.rs -+++ b/rust/src/clib/policy.rs -@@ -67,6 +67,13 @@ pub extern "C" fn nmstate_net_state_from_policy( - } - }; - -+ let input_is_json = -+ if let Ok(policy_str) = unsafe { CStr::from_ptr(policy) }.to_str() { -+ serde_json::from_str::(policy_str).is_ok() -+ } else { -+ false -+ }; -+ - let mut policy = match deserilize_from_c_char::( - policy, err_kind, err_msg, - ) { -@@ -86,23 +93,37 @@ pub extern "C" fn nmstate_net_state_from_policy( - } - - match result { -- Ok(s) => match serde_json::to_string(&s) { -- Ok(state_str) => unsafe { -- *state = CString::new(state_str).unwrap().into_raw(); -- NMSTATE_PASS -- }, -- Err(e) => unsafe { -- *err_msg = -- CString::new(format!("serde_json::to_string failure: {e}")) -- .unwrap() -- .into_raw(); -- *err_kind = -- CString::new(format!("{}", nmstate::ErrorKind::Bug)) -- .unwrap() -- .into_raw(); -- NMSTATE_FAIL -- }, -- }, -+ Ok(s) => { -+ let serialize = if input_is_json { -+ serde_json::to_string(&s).map_err(|e| { -+ nmstate::NmstateError::new( -+ nmstate::ErrorKind::Bug, -+ format!("Failed to convert state {s:?} to JSON: {e}"), -+ ) -+ }) -+ } else { -+ serde_yaml::to_string(&s).map_err(|e| { -+ nmstate::NmstateError::new( -+ nmstate::ErrorKind::Bug, -+ format!("Failed to convert state {s:?} to YAML: {e}"), -+ ) -+ }) -+ }; -+ -+ match serialize { -+ Ok(state_str) => unsafe { -+ *state = CString::new(state_str).unwrap().into_raw(); -+ NMSTATE_PASS -+ }, -+ Err(e) => unsafe { -+ *err_msg = -+ CString::new(e.msg().to_string()).unwrap().into_raw(); -+ *err_kind = -+ CString::new(e.kind().to_string()).unwrap().into_raw(); -+ NMSTATE_FAIL -+ }, -+ } -+ } - Err(e) => { - unsafe { - *err_msg = CString::new(e.msg()).unwrap().into_raw(); -@@ -144,7 +165,7 @@ where - } - }; - -- match serde_json::from_str(content_str) { -+ match serde_yaml::from_str(content_str) { - Ok(n) => Some(n), - Err(e) => { - unsafe { -diff --git a/rust/src/clib/query.rs b/rust/src/clib/query.rs -index a24b9c83..12e44d05 100644 ---- a/rust/src/clib/query.rs -+++ b/rust/src/clib/query.rs -@@ -14,6 +14,7 @@ pub(crate) const NMSTATE_FLAG_INCLUDE_SECRETS: u32 = 1 << 4; - pub(crate) const NMSTATE_FLAG_NO_COMMIT: u32 = 1 << 5; - pub(crate) const NMSTATE_FLAG_MEMORY_ONLY: u32 = 1 << 6; - pub(crate) const NMSTATE_FLAG_RUNNING_CONFIG_ONLY: u32 = 1 << 7; -+pub(crate) const NMSTATE_FLAG_YAML_OUTPUT: u32 = 1 << 8; - - #[allow(clippy::not_unsafe_ptr_arg_deref)] - #[no_mangle] -@@ -72,23 +73,37 @@ pub extern "C" fn nmstate_net_state_retrieve( - } - - match result { -- Ok(s) => match serde_json::to_string(&s) { -- Ok(state_str) => unsafe { -- *state = CString::new(state_str).unwrap().into_raw(); -- NMSTATE_PASS -- }, -- Err(e) => unsafe { -- *err_msg = -- CString::new(format!("serde_json::to_string failure: {e}")) -- .unwrap() -- .into_raw(); -- *err_kind = -- CString::new(format!("{}", nmstate::ErrorKind::Bug)) -- .unwrap() -- .into_raw(); -- NMSTATE_FAIL -- }, -- }, -+ Ok(s) => { -+ let serialize = if (flags & NMSTATE_FLAG_YAML_OUTPUT) > 0 { -+ serde_yaml::to_string(&s).map_err(|e| { -+ nmstate::NmstateError::new( -+ nmstate::ErrorKind::Bug, -+ format!("Failed to convert state {s:?} to YAML: {e}"), -+ ) -+ }) -+ } else { -+ serde_json::to_string(&s).map_err(|e| { -+ nmstate::NmstateError::new( -+ nmstate::ErrorKind::Bug, -+ format!("Failed to convert state {s:?} to JSON: {e}"), -+ ) -+ }) -+ }; -+ -+ match serialize { -+ Ok(state_str) => unsafe { -+ *state = CString::new(state_str).unwrap().into_raw(); -+ NMSTATE_PASS -+ }, -+ Err(e) => unsafe { -+ *err_msg = -+ CString::new(e.msg().to_string()).unwrap().into_raw(); -+ *err_kind = -+ CString::new(e.kind().to_string()).unwrap().into_raw(); -+ NMSTATE_FAIL -+ }, -+ } -+ } - Err(e) => { - unsafe { - *err_msg = CString::new(e.msg()).unwrap().into_raw(); -diff --git a/rust/src/clib/test/nmpolicy_test.c b/rust/src/clib/test/nmpolicy_json_test.c -similarity index 96% -rename from rust/src/clib/test/nmpolicy_test.c -rename to rust/src/clib/test/nmpolicy_json_test.c -index 7a71a5f5..8a0444d4 100644 ---- a/rust/src/clib/test/nmpolicy_test.c -+++ b/rust/src/clib/test/nmpolicy_json_test.c -@@ -1,3 +1,6 @@ -+// SPDX-License-Identifier: Apache-2.0 -+ -+#include - #include - #include - #include -@@ -91,6 +94,8 @@ int main(void) { - rc = EXIT_FAILURE; - } - -+ assert(state[0] == '{'); -+ - nmstate_cstring_free(state); - nmstate_cstring_free(err_kind); - nmstate_cstring_free(err_msg); -diff --git a/rust/src/clib/test/nmpolicy_yaml_test.c b/rust/src/clib/test/nmpolicy_yaml_test.c -new file mode 100644 -index 00000000..7984f509 ---- /dev/null -+++ b/rust/src/clib/test/nmpolicy_yaml_test.c -@@ -0,0 +1,80 @@ -+// SPDX-License-Identifier: Apache-2.0 -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+int main(void) { -+ int rc = EXIT_SUCCESS; -+ const char *policy = "\ -+capture:\n\ -+ default-gw: override me with the cache\n\ -+ base-iface: >\n\ -+ interfaces.name == capture.default-gw.routes.running.0.next-hop-interface\n\ -+ base-iface-routes: >\n\ -+ routes.running.next-hop-interface ==\n\ -+ capture.default-gw.routes.running.0.next-hop-interface\n\ -+ bridge-routes: >\n\ -+ capture.base-iface-routes | routes.running.next-hop-interface:=\"br1\"\n\ -+desired:\n\ -+ interfaces:\n\ -+ - name: br1\n\ -+ description: Linux bridge with base interface as a port\n\ -+ type: linux-bridge\n\ -+ state: up\n\ -+ bridge:\n\ -+ options:\n\ -+ stp:\n\ -+ enabled: false\n\ -+ port:\n\ -+ - name: '{{ capture.base-iface.interfaces.0.name }}'\n\ -+ ipv4: '{{ capture.base-iface.interfaces.0.ipv4 }}'\n\ -+ routes:\n\ -+ config: '{{ capture.bridge-routes.routes.running }}'"; -+ const char *current_state = "\ -+interfaces:\n\ -+- name: eth1\n\ -+ type: ethernet\n\ -+ state: up\n\ -+ mac-address: 1c:c1:0c:32:3b:ff\n\ -+ ipv4:\n\ -+ address:\n\ -+ - ip: 192.0.2.251\n\ -+ prefix-length: 24\n\ -+ dhcp: false\n\ -+ enabled: true\n\ -+routes:\n\ -+ config:\n\ -+ - destination: 0.0.0.0/0\n\ -+ next-hop-address: 192.0.2.1\n\ -+ next-hop-interface: eth1\n\ -+ running:\n\ -+ - destination: 0.0.0.0/0\n\ -+ next-hop-address: 192.0.2.1\n\ -+ next-hop-interface: eth1"; -+ char *state = NULL; -+ char *err_kind = NULL; -+ char *err_msg = NULL; -+ char *log = NULL; -+ -+ if (nmstate_net_state_from_policy(policy, current_state, &state, &log, -+ &err_kind, &err_msg) == NMSTATE_PASS) -+ { -+ printf("%s\n", state); -+ } else { -+ printf("%s: %s\n", err_kind, err_msg); -+ rc = EXIT_FAILURE; -+ } -+ -+ assert(state[0] != '{'); -+ -+ nmstate_cstring_free(state); -+ nmstate_cstring_free(err_kind); -+ nmstate_cstring_free(err_msg); -+ nmstate_cstring_free(log); -+ exit(rc); -+} -diff --git a/rust/src/clib/test/nmstate_test.c b/rust/src/clib/test/nmstate_json_test.c -similarity index 87% -rename from rust/src/clib/test/nmstate_test.c -rename to rust/src/clib/test/nmstate_json_test.c -index 0e79cb15..1bfbcda7 100644 ---- a/rust/src/clib/test/nmstate_test.c -+++ b/rust/src/clib/test/nmstate_json_test.c -@@ -1,3 +1,6 @@ -+// SPDX-License-Identifier: Apache-2.0 -+ -+#include - #include - #include - #include -@@ -21,6 +24,8 @@ int main(void) { - rc = EXIT_FAILURE; - } - -+ assert(state[0] == '{'); -+ - nmstate_cstring_free(state); - nmstate_cstring_free(err_kind); - nmstate_cstring_free(err_msg); -diff --git a/rust/src/clib/test/nmstate_yaml_test.c b/rust/src/clib/test/nmstate_yaml_test.c -new file mode 100644 -index 00000000..de0f2486 ---- /dev/null -+++ b/rust/src/clib/test/nmstate_yaml_test.c -@@ -0,0 +1,34 @@ -+// SPDX-License-Identifier: Apache-2.0 -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+int main(void) { -+ int rc = EXIT_SUCCESS; -+ char *state = NULL; -+ char *err_kind = NULL; -+ char *err_msg = NULL; -+ char *log = NULL; -+ uint32_t flag = NMSTATE_FLAG_KERNEL_ONLY | NMSTATE_FLAG_YAML_OUTPUT; -+ -+ if (nmstate_net_state_retrieve(flag, &state, &log, &err_kind, &err_msg) -+ == NMSTATE_PASS) { -+ printf("%s\n", state); -+ } else { -+ printf("%s: %s\n", err_kind, err_msg); -+ rc = EXIT_FAILURE; -+ } -+ -+ assert(state[0] != '{'); -+ -+ nmstate_cstring_free(state); -+ nmstate_cstring_free(err_kind); -+ nmstate_cstring_free(err_msg); -+ nmstate_cstring_free(log); -+ exit(rc); -+} -diff --git a/rust/src/lib/Cargo.toml b/rust/src/lib/Cargo.toml -index a27d0e1a..0142026d 100644 ---- a/rust/src/lib/Cargo.toml -+++ b/rust/src/lib/Cargo.toml -@@ -15,6 +15,9 @@ edition = "2018" - [lib] - path = "lib.rs" - -+[dependencies] -+serde_yaml = "0.9" -+ - [dependencies.nispor] - version = "1.2.9" - optional = true -diff --git a/rust/src/lib/net_state.rs b/rust/src/lib/net_state.rs -index 8ab79642..fe5fea78 100644 ---- a/rust/src/lib/net_state.rs -+++ b/rust/src/lib/net_state.rs -@@ -274,7 +274,19 @@ impl NetworkState { - Ok(s) => Ok(s), - Err(e) => Err(NmstateError::new( - ErrorKind::InvalidArgument, -- format!("Invalid json string: {e}"), -+ format!("Invalid JSON string: {e}"), -+ )), -+ } -+ } -+ -+ /// Wrapping function of [serde_yaml::from_str()] with error mapped to -+ /// [NmstateError]. -+ pub fn new_from_yaml(net_state_yaml: &str) -> Result { -+ match serde_yaml::from_str(net_state_yaml) { -+ Ok(s) => Ok(s), -+ Err(e) => Err(NmstateError::new( -+ ErrorKind::InvalidArgument, -+ format!("Invalid YAML string: {e}"), - )), - } - } --- -2.39.2 - diff --git a/SOURCES/nmstate-1.4.2.tar.gz.asc b/SOURCES/nmstate-1.4.2.tar.gz.asc deleted file mode 100644 index 7f3131a..0000000 --- a/SOURCES/nmstate-1.4.2.tar.gz.asc +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABCAAdFiEE8f1XsqXpyNthgIbGbM3lj+QeKP8FAmPwSo0ACgkQbM3lj+Qe -KP/P7A/8DLoHZkeuCsDjCYQ5yk0pWSuEqDMZT4Qqk6khBJOtvx5L14oImlrpmOVr -iw3pclF/fl8wxcpPYwcVn2odJWryaZxKw3vNPfth47vEtk3RVZpIqHLsgcCOEcX1 -/czFbA4EJLZV67Qu4gEfrfjbTKEmcakXLI5qUbMDw0nwqx5BI/66iF5kZD4IGJui -MDVbe61wAatcOl5RU8Y0rFI6fz4a9PXVJEijHJC8ZMg/Vq4Q/aBErUZAQ9RKJmi7 -Uu2TLYv4JTMiWX/xspH+CJX7bbaJ9N7P/Z3NzEOKVlDGMmG7TN9QtpnuSF46Jv5K -LTLdr7mBSK3dnQ9vIwcmM8m/MWU2w9dxf7Oh8YCkjwlLk1ANnANHz+xBMx+qIM5e -uNB2iPL2nHTDLFVbOMp1dcZzvndgm3a5oS9L4nglVojvNqGTmkjeJaM5bk80HvxJ -i/onHNmNRnQeHn8xUT7EcBQXUBUCORExygTyJ1dsw+BwbncwV2lOSan7OJY53Os2 -Lm7kHRBtOPeJNK7NbF55eo+N2+1+n9XP7oiCaj//FwWXN6vh97afi7fp5men2MKr -xbBPtYP5BV5LT7/DxKW+AunL2UUtlYoeCI0wm16kDzL8VW1u1Arv5NtdQsSnONk9 -PChrlhPnITjIZ0o2+GrYYOROZPbMSl4oQtO0hTiUub2Vrf3sPIc= -=zl4m ------END PGP SIGNATURE----- diff --git a/SOURCES/nmstate-1.4.4.tar.gz.asc b/SOURCES/nmstate-1.4.4.tar.gz.asc new file mode 100644 index 0000000..d885f4d --- /dev/null +++ b/SOURCES/nmstate-1.4.4.tar.gz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCAAdFiEESP1vrlFad7SENoIch4lWe4cVzrwFAmRE940ACgkQh4lWe4cV +zrzJjxAA6hjRclf2YAkIrrdCyoU3TDElpADOjrTRMGe9K0kp5FEFPrzl9mJnDSNR +S0UL7Kwn0OBe9Pw8/0OMUPAHhiFy524yd1dRrb2X5RpH6Fem51ExCYHxYXWyRuxK +ll7JsTImeUxf0M+wetojLWaDOBT2Og1H6aRW62Jm8oa90l3Yjk4KZMNOslmY410V +H8QzfHa/R75ZpH6wH9RzyX7CNvCaglMEeBkMApvjSAppllolh7AkbjCCSEMiSnK/ +3HjSftvyGGDCn4VBP8hh05amz84ielK4RTqtz2fvzARudxxhQ+f9DJ/2fVFSv3RL +YxCQL3nYMnCqEK0LZ4hw5xdZcVGeuBBj5ubzWxzahy0dC87Lifvgy6/l1Tp5GBKt +wVSEA2dest55Punng784pNnYGnks/wKTK1TVnhLmTRe0IUJtUbz0cYse4JOfhxe+ +SYyVtSmrwaS3Lo/h2PtMua3aF92z9RP6dkNKin0c5WlBpmothwiEsCD6cZR148zB +y8hitadVZ9nysWFgT0EGVHMkzGTKaCVNJ1s3UsJUYiTUEMa3StzJX704NKEitnFX +SkC2qHMlV04BMtB6Nb+86LOOPBSh5u7vzqU0M7BAD4SmVkKH27asYaSqdG3kLez6 +XRW8eeQkS6LVAACm6Wrb37XecTAGPF9pE5P9Wmg0YKZpQM6t9NM= +=3XHy +-----END PGP SIGNATURE----- diff --git a/SOURCES/nmstate.gpg b/SOURCES/nmstate.gpg new file mode 100644 index 0000000..9c0f9a4 --- /dev/null +++ b/SOURCES/nmstate.gpg @@ -0,0 +1,51 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=PdCG +-----END PGP PUBLIC KEY BLOCK----- diff --git a/SPECS/nmstate.spec b/SPECS/nmstate.spec index 3eb6f65..54eef4e 100644 --- a/SPECS/nmstate.spec +++ b/SPECS/nmstate.spec @@ -3,8 +3,8 @@ %define libname libnmstate Name: nmstate -Version: 1.4.2 -Release: 4%{?dist} +Version: 1.4.4 +Release: 3%{?dist} Summary: Declarative network manager API License: LGPLv2+ URL: https://github.com/%{srcname}/%{srcname} @@ -14,9 +14,7 @@ Source2: https://www.nmstate.io/nmstate.gpg Source3: %{url}/releases/download/v%{version}/%{srcname}-vendor-%{version}.tar.xz # Patches 0X are reserved to downstream only Patch0: BZ_2132570-nm-reverse-IPv6-order-before-adding-them-to-setting.patch -Patch11: Enable_clib_yml_api.patch -Patch12: BZ_2160416-fix-SRIOV.patch -Patch13: BZ_2160416-Ignore-error-when-creating-profile-if-not-desired.patch +Patch1: BZ_2203277-ip-Support-static-route-with-auto-ip.patch BuildRequires: python3-devel BuildRequires: python3-setuptools BuildRequires: gnupg2 @@ -151,6 +149,18 @@ popd /sbin/ldconfig %changelog +* Tue May 30 2023 Fernando Fernandez Mancera - 1.4.4-3 +- Support static route with auto-ip. RHBZ#2203277 + +* Mon Apr 24 2023 Gris Ge - 1.4.4-2 +- Enable CI gating. + +* Sun Apr 23 2023 Gris Ge - 1.4.4-1 +- Upgrade to nmstate 1.4.4 + +* Wed Mar 29 2023 Gris Ge - 1.4.3-1 +- Upgrade to nmstate 1.4.3. RHBZ#2179899 + * Mon Feb 27 2023 Gris Ge - 1.4.2-4 - Ignore undesired iface config. RHBZ#2160416