From 5f36c635720aab3006b7c34824d024831cc27d40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Alejandro=20Anderssen=20Gonz=C3=A1lez?= Date: Wed, 25 Mar 2020 12:11:32 +0000 Subject: [PATCH 1/9] Clean the cache and read after writing --- library/network/src/modules/NetworkInterfaces.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/library/network/src/modules/NetworkInterfaces.rb b/library/network/src/modules/NetworkInterfaces.rb index 47793d06c..afdd2de96 100644 --- a/library/network/src/modules/NetworkInterfaces.rb +++ b/library/network/src/modules/NetworkInterfaces.rb @@ -954,6 +954,7 @@ def Write(devregex) # Finish him SCR.Write(path(".network"), nil) + CleanCacheRead() true end From 90642b65d62cbb29ad633ae475607f190e8b3ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Alejandro=20Anderssen=20Gonz=C3=A1lez?= Date: Wed, 25 Mar 2020 12:45:07 +0000 Subject: [PATCH 2/9] Bump version & changelog --- package/yast2.changes | 7 +++++++ package/yast2.spec | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/package/yast2.changes b/package/yast2.changes index bc1a969cd..fe5fbe40b 100644 --- a/package/yast2.changes +++ b/package/yast2.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Wed Mar 25 12:12:00 UTC 2020 - Knut Anderssen + +- Force a cache clean and read of the current network interfaces + configuration after writing it (bsc#1166778) +- 4.1.76 + ------------------------------------------------------------------- Thu Dec 19 14:51:23 UTC 2019 - Knut Anderssen diff --git a/package/yast2.spec b/package/yast2.spec index 6f1d544e8..abe77cb42 100644 --- a/package/yast2.spec +++ b/package/yast2.spec @@ -17,7 +17,7 @@ Name: yast2 -Version: 4.1.75 +Version: 4.1.76 Release: 0 Summary: YaST2 - Main Package From 11375fb4940dadd683836743fa34d18fd03c2879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Alejandro=20Anderssen=20Gonz=C3=A1lez?= Date: Thu, 26 Mar 2020 09:21:41 +0000 Subject: [PATCH 3/9] Removed failing old testsuite and added write test --- .../data/etc/sysconfig/network/ifcfg-eth1 | 4 +- .../etc/sysconfig/network/single_quote.test | 5 ++ .../network/test/network_interfaces_test.rb | 45 ++++++++++++ .../testsuite/tests/NetworkInterfaces4.err | 0 .../testsuite/tests/NetworkInterfaces4.out | 15 ---- .../testsuite/tests/NetworkInterfaces4.rb | 68 ------------------- 6 files changed, 52 insertions(+), 85 deletions(-) create mode 100644 library/network/test/data/etc/sysconfig/network/single_quote.test delete mode 100644 library/network/testsuite/tests/NetworkInterfaces4.err delete mode 100644 library/network/testsuite/tests/NetworkInterfaces4.out delete mode 100644 library/network/testsuite/tests/NetworkInterfaces4.rb diff --git a/library/network/test/data/etc/sysconfig/network/ifcfg-eth1 b/library/network/test/data/etc/sysconfig/network/ifcfg-eth1 index faa69c162..90f431e23 100644 --- a/library/network/test/data/etc/sysconfig/network/ifcfg-eth1 +++ b/library/network/test/data/etc/sysconfig/network/ifcfg-eth1 @@ -1,4 +1,4 @@ -DEVICE=eth1 +DEVICE='eth1' BOOTPROTO='static' STARTMODE='auto' -SLAVE=YES +SLAVE='YES' diff --git a/library/network/test/data/etc/sysconfig/network/single_quote.test b/library/network/test/data/etc/sysconfig/network/single_quote.test new file mode 100644 index 000000000..168f0f9d8 --- /dev/null +++ b/library/network/test/data/etc/sysconfig/network/single_quote.test @@ -0,0 +1,5 @@ +DEVICE='single' +BOOTPROTO='dhcp' +STARTMODE='auto' +DHCLIENT_SET_HOSTNAME='yes' +NAME='single 'quoted' name' diff --git a/library/network/test/network_interfaces_test.rb b/library/network/test/network_interfaces_test.rb index 86f858577..3e7c449aa 100755 --- a/library/network/test/network_interfaces_test.rb +++ b/library/network/test/network_interfaces_test.rb @@ -52,6 +52,9 @@ def mock_ppp describe "#Read" do let(:data_dir) { File.join(File.dirname(__FILE__), "data") } + let(:network_path) { File.join(data_dir, "etc/sysconfig/network") } + let(:single_template) { File.join(network_path, "single_quote.test") } + let(:single_file) { File.join(network_path, "ifcfg-single") } # Defined in test/data/etc/sysconfig/ifcfg-* let(:devices) { ["arc5", "bond0", "br1", "cold", "em1", "eth0", "eth1", "eth2", "ppp0", "vlan3"] } @@ -89,6 +92,12 @@ def mock_ppp expect(subject.GetValue("eth0", "NETMASK")).to eql("255.255.255.0") end + it "reads the ifcfg files with single quote removed" do + ::FileUtils.cp(single_template, single_file) + subject.Read + expect(subject.GetValue("single", "NAME")).to eql("single quoted name") + ::FileUtils.rm(single_file) + end end describe "adapt_old_config!" do @@ -306,4 +315,40 @@ def mock_ppp expect(subject.Devices[device_type]).to include(device => device_map, "eth1" => {}) end end + + describe "#Write" do + let(:data_dir) { File.join(File.dirname(__FILE__), "data") } + let(:network_path) { File.join(data_dir, "etc/sysconfig/network") } + let(:ifcfg_copy) { File.join(network_path, "ifcfg-copy") } + let(:ifcfg_file) { File.join(network_path, "ifcfg-eth1") } + + before do + Yast::NetworkInterfaces.CleanCacheRead() + end + + around do |example| + ::FileUtils.cp(ifcfg_file, ifcfg_copy) + change_scr_root(data_dir, &example) + ::FileUtils.rm(ifcfg_copy) + end + + it "writes interfaces configuration changes to ifcfg files" do + devmap = Yast::NetworkInterfaces.devmap("eth1") + devmap["DHCLIENT_SET_HOSTNAME"] = "yes" + Yast::NetworkInterfaces.Write("") + devmap = Yast::NetworkInterfaces.devmap("eth1") + expect(devmap["DHCLIENT_SET_HOSTNAME"]).to eq("yes") + devmap["DHCLIENT_SET_HOSTNAME"] = nil + Yast::NetworkInterfaces.Write("") + expect(::FileUtils.compare_file(ifcfg_copy, ifcfg_file)).to eq(true) + end + + it "deletes removed interfaces" do + size = Yast::NetworkInterfaces.List("").size + Yast::NetworkInterfaces.Delete("copy") + Yast::NetworkInterfaces.Commit() + Yast::NetworkInterfaces.Write("") + expect(Yast::NetworkInterfaces.List("").size).to eq(size - 1) + end + end end diff --git a/library/network/testsuite/tests/NetworkInterfaces4.err b/library/network/testsuite/tests/NetworkInterfaces4.err deleted file mode 100644 index e69de29bb..000000000 diff --git a/library/network/testsuite/tests/NetworkInterfaces4.out b/library/network/testsuite/tests/NetworkInterfaces4.out deleted file mode 100644 index eba881637..000000000 --- a/library/network/testsuite/tests/NetworkInterfaces4.out +++ /dev/null @@ -1,15 +0,0 @@ -Read .target.tmpdir "/tmp" -Dump NetworkInterfaces::Read -Dir .network.section: ["eth4"] -Dir .network.value."eth4": ["BOOTPROTO", "NAME"] -Read .network.value."eth4".BOOTPROTO "dhcp" -Read .network.value."eth4".NAME "we like 'singles'" -Read .target.stat "/sys/class/net/eth4/type" nil -Read .target.string "/sys/class/net/eth4/type" nil -Return true -Dump NetworkInterfaces::Write -Write .network.value."eth4".BOOTPROTO "dhcp" true -Write .network.value."eth4".NAME "we like 'singles'" true -Write .network.value."eth4".STARTMODE "" true -Write .network nil true -Return true diff --git a/library/network/testsuite/tests/NetworkInterfaces4.rb b/library/network/testsuite/tests/NetworkInterfaces4.rb deleted file mode 100644 index 2dbdfd564..000000000 --- a/library/network/testsuite/tests/NetworkInterfaces4.rb +++ /dev/null @@ -1,68 +0,0 @@ -# encoding: utf-8 - -# *************************************************************************** -# -# Copyright (c) 2002 - 2012 Novell, Inc. -# All Rights Reserved. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, contact Novell, Inc. -# -# To contact Novell about this file by physical or electronic mail, -# you may find current contact information at www.novell.com -# -# *************************************************************************** -module Yast - # inject NetworkInterfaces accessor so we can modify Devices - class NetworkInterfacesClass < Module - attr_accessor :OriginalDevices - end - - class NetworkInterfaces4Client < Client - def main - # bug 72164 - - Yast.include self, "testsuite.rb" - - @READ = { - "network" => { - "section" => { "eth4" => nil }, - "value" => { - "eth4" => { "BOOTPROTO" => "dhcp", "NAME" => "we like 'singles'" } - } - }, - "probe" => { "system" => [] }, - "target" => { "tmpdir" => "/tmp" } - } - - @EXEC = { - "target" => { - "bash_output" => { "exit" => 0, "stdout" => "", "stderr" => "" } - } - } - - TESTSUITE_INIT([@READ, {}, @EXEC], nil) - Yast.import "NetworkInterfaces" - - DUMP("NetworkInterfaces::Read") - TEST(->() { NetworkInterfaces.Read }, [@READ, {}, @EXEC], nil) - NetworkInterfaces.OriginalDevices = nil - - DUMP("NetworkInterfaces::Write") - TEST(->() { NetworkInterfaces.Write("") }, [@READ], nil) - - nil - end - end -end - -Yast::NetworkInterfaces4Client.new.main From 75606f771e6d1f3870722e9ac07a7c99a6a87194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Alejandro=20Anderssen=20Gonz=C3=A1lez?= Date: Thu, 26 Mar 2020 09:21:51 +0000 Subject: [PATCH 4/9] Changes based on CR --- library/network/src/modules/NetworkInterfaces.rb | 2 ++ library/network/test/network_interfaces_test.rb | 1 + package/yast2.changes | 5 +++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/library/network/src/modules/NetworkInterfaces.rb b/library/network/src/modules/NetworkInterfaces.rb index afdd2de96..3b8faf1f9 100644 --- a/library/network/src/modules/NetworkInterfaces.rb +++ b/library/network/src/modules/NetworkInterfaces.rb @@ -954,6 +954,8 @@ def Write(devregex) # Finish him SCR.Write(path(".network"), nil) + # Reread all settings to avoid wrong values when reopen the network + # dialog during installation (bsc#1166778) CleanCacheRead() true diff --git a/library/network/test/network_interfaces_test.rb b/library/network/test/network_interfaces_test.rb index 3e7c449aa..5e69861ed 100755 --- a/library/network/test/network_interfaces_test.rb +++ b/library/network/test/network_interfaces_test.rb @@ -92,6 +92,7 @@ def mock_ppp expect(subject.GetValue("eth0", "NETMASK")).to eql("255.255.255.0") end + # bsc#72164 it "reads the ifcfg files with single quote removed" do ::FileUtils.cp(single_template, single_file) subject.Read diff --git a/package/yast2.changes b/package/yast2.changes index fe5fbe40b..852b6a33a 100644 --- a/package/yast2.changes +++ b/package/yast2.changes @@ -1,8 +1,9 @@ ------------------------------------------------------------------- Wed Mar 25 12:12:00 UTC 2020 - Knut Anderssen -- Force a cache clean and read of the current network interfaces - configuration after writing it (bsc#1166778) +- Reread network interfaces configuration after writing it avoiding + wrong values when reopen network configuration dialog during an + installation (bsc#1166778) - 4.1.76 ------------------------------------------------------------------- From 2fe4cd747aeb53e09bd833321a99fa21b3c1e3cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Alejandro=20Anderssen=20Gonz=C3=A1lez?= Date: Thu, 26 Mar 2020 09:55:41 +0000 Subject: [PATCH 5/9] Add explicit read after writing test --- .../network/test/network_interfaces_test.rb | 48 ++++++++++++------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/library/network/test/network_interfaces_test.rb b/library/network/test/network_interfaces_test.rb index 5e69861ed..8e5c38856 100755 --- a/library/network/test/network_interfaces_test.rb +++ b/library/network/test/network_interfaces_test.rb @@ -324,7 +324,7 @@ def mock_ppp let(:ifcfg_file) { File.join(network_path, "ifcfg-eth1") } before do - Yast::NetworkInterfaces.CleanCacheRead() + subject.CleanCacheRead() end around do |example| @@ -333,23 +333,37 @@ def mock_ppp ::FileUtils.rm(ifcfg_copy) end - it "writes interfaces configuration changes to ifcfg files" do - devmap = Yast::NetworkInterfaces.devmap("eth1") - devmap["DHCLIENT_SET_HOSTNAME"] = "yes" - Yast::NetworkInterfaces.Write("") - devmap = Yast::NetworkInterfaces.devmap("eth1") - expect(devmap["DHCLIENT_SET_HOSTNAME"]).to eq("yes") - devmap["DHCLIENT_SET_HOSTNAME"] = nil - Yast::NetworkInterfaces.Write("") - expect(::FileUtils.compare_file(ifcfg_copy, ifcfg_file)).to eq(true) - end + context "when the configuration has changed" do + it "writes interfaces configuration changes to ifcfg files" do + devmap = subject.devmap("eth1") + devmap["SOME_VALUE"] = "yes" + subject.Write("") + expect(::FileUtils.compare_file(ifcfg_copy, ifcfg_file)).to eq(false) + devmap = subject.devmap("eth1") + devmap["SOME_VALUE"] = nil + subject.Write("") + expect(::FileUtils.compare_file(ifcfg_copy, ifcfg_file)).to eq(true) + end - it "deletes removed interfaces" do - size = Yast::NetworkInterfaces.List("").size - Yast::NetworkInterfaces.Delete("copy") - Yast::NetworkInterfaces.Commit() - Yast::NetworkInterfaces.Write("") - expect(Yast::NetworkInterfaces.List("").size).to eq(size - 1) + it "cleans the cache and read again the configuration after writing" do + expect(subject).to receive(:CleanCacheRead).twice.and_call_original + devmap = subject.devmap("eth1") + devmap["DHCLIENT_SET_HOSTNAME"] = "yes" + subject.Write("") + devmap = subject.devmap("eth1") + expect(devmap["DHCLIENT_SET_HOSTNAME"]).to eq("yes") + devmap["DHCLIENT_SET_HOSTNAME"] = nil + subject.Write("") + expect(::FileUtils.compare_file(ifcfg_copy, ifcfg_file)).to eq(true) + end + + it "deletes removed interfaces" do + size = subject.List("").size + subject.Delete("copy") + subject.Commit() + subject.Write("") + expect(subject.List("").size).to eq(size - 1) + end end end end From 198f44a28a6cf9888cec673e86aeafd2fc9c6cfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Alejandro=20Anderssen=20Gonz=C3=A1lez?= Date: Mon, 13 Apr 2020 13:36:32 +0100 Subject: [PATCH 6/9] Bring back the deletion of removed ip aliases --- .../network/src/modules/NetworkInterfaces.rb | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/library/network/src/modules/NetworkInterfaces.rb b/library/network/src/modules/NetworkInterfaces.rb index 3b8faf1f9..52b40844f 100644 --- a/library/network/src/modules/NetworkInterfaces.rb +++ b/library/network/src/modules/NetworkInterfaces.rb @@ -800,12 +800,11 @@ def Write(devregex) # remove deleted devices log.info("Deleted=#{@Deleted}") - Builtins.foreach(@Deleted) do |d| - # delete config file - p = Builtins.add(path(".network.section"), d) - log.debug("deleting: #{p}") - SCR.Write(p, nil) + @Deleted.each do |d| + iface, alias_num = d.split("#") + alias_num ? delete_alias(original_devs, iface, alias_num) : delete_device(iface) end + @Deleted = [] # write all devices @@ -1591,6 +1590,39 @@ def get_devices(devregex) devices end + # Convenience method to delete an interface config file from the system + # + # @param iface [String] interface name of the config file to be deleted + def delete_device(iface) + # delete config file + p = path(".network.section") + iface + log.debug("deleting: #{p}") + SCR.Write(p, nil) + end + + # Convenience method to delete an specific ip alias from an interface + # config file + # + # @param devices [Hash>] hash with the devices + # to remove the aliases from + # @param iface [String] interface name of the alias which alias need to be + # removed + # @param alias_num [String] index num of the alias that needs to be removed + def delete_alias(devices, iface, alias_num) + dev_map = devices.values.find { |d| d.keys.include? (iface) } || {} + dev_aliases = dev_map.fetch(iface, {}).fetch("_aliases", {}) + + base = path(".network.value") + iface + # look in OriginalDevs because we need to catch all variables + # of the alias + + dev_aliases.fetch(alias_num, {}).keys.each do |key| + p = base + "#{key}_#{alias_num}" + log.debug("deleting: #{p}") + SCR.Write(p, nil) + end + end + publish variable: :Name, type: "string" publish variable: :Current, type: "map " publish variable: :CardRegex, type: "map " From ecac4a241db1033d3ec72ed96d1abf5fd76720b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Alejandro=20Anderssen=20Gonz=C3=A1lez?= Date: Mon, 13 Apr 2020 14:59:44 +0100 Subject: [PATCH 7/9] Added test for removed aliases --- .../network/src/modules/NetworkInterfaces.rb | 2 +- library/network/test/network_interfaces_test.rb | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/library/network/src/modules/NetworkInterfaces.rb b/library/network/src/modules/NetworkInterfaces.rb index 52b40844f..07aef718f 100644 --- a/library/network/src/modules/NetworkInterfaces.rb +++ b/library/network/src/modules/NetworkInterfaces.rb @@ -1609,7 +1609,7 @@ def delete_device(iface) # removed # @param alias_num [String] index num of the alias that needs to be removed def delete_alias(devices, iface, alias_num) - dev_map = devices.values.find { |d| d.keys.include? (iface) } || {} + dev_map = devices.values.find { |d| d.keys.include?(iface) } || {} dev_aliases = dev_map.fetch(iface, {}).fetch("_aliases", {}) base = path(".network.value") + iface diff --git a/library/network/test/network_interfaces_test.rb b/library/network/test/network_interfaces_test.rb index 8e5c38856..e6a6470ee 100755 --- a/library/network/test/network_interfaces_test.rb +++ b/library/network/test/network_interfaces_test.rb @@ -322,6 +322,8 @@ def mock_ppp let(:network_path) { File.join(data_dir, "etc/sysconfig/network") } let(:ifcfg_copy) { File.join(network_path, "ifcfg-copy") } let(:ifcfg_file) { File.join(network_path, "ifcfg-eth1") } + let(:eth0_back) { File.join(network_path, "ifcfg-eth0.backup") } + let(:eth0) { File.join(network_path, "ifcfg-eth0") } before do subject.CleanCacheRead() @@ -329,8 +331,11 @@ def mock_ppp around do |example| ::FileUtils.cp(ifcfg_file, ifcfg_copy) + ::FileUtils.cp(eth0, eth0_back) change_scr_root(data_dir, &example) + ::FileUtils.cp(eth0_back, eth0) ::FileUtils.rm(ifcfg_copy) + ::FileUtils.rm(eth0_back) end context "when the configuration has changed" do @@ -364,6 +369,18 @@ def mock_ppp subject.Write("") expect(subject.List("").size).to eq(size - 1) end + + it "deletes removed aliases" do + devmap = subject.devmap("eth0") + expect(devmap["_aliases"].size).to eq(1) + subject.Edit("eth0") + subject.Current["_aliases"] = {} + subject.Commit() + subject.DeleteAlias("eth0", "0") + subject.Write("") + devmap = subject.devmap("eth0") + expect(devmap["_aliases"]).to be(nil) + end end end end From 54f6762d7b732e89b2f89e288e065d4808f75601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Alejandro=20Anderssen=20Gonz=C3=A1lez?= Date: Mon, 13 Apr 2020 13:39:12 +0100 Subject: [PATCH 8/9] Bump version & changelog --- package/yast2.changes | 7 +++++++ package/yast2.spec | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/package/yast2.changes b/package/yast2.changes index 852b6a33a..a59261c01 100644 --- a/package/yast2.changes +++ b/package/yast2.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Mon Apr 13 12:36:58 UTC 2020 - Knut Anderssen + +- Remove ip aliases that were marked to be deleted from the + interface configuration files (bsc#1146020) +- 4.1.77 + ------------------------------------------------------------------- Wed Mar 25 12:12:00 UTC 2020 - Knut Anderssen diff --git a/package/yast2.spec b/package/yast2.spec index abe77cb42..98bc7e4f1 100644 --- a/package/yast2.spec +++ b/package/yast2.spec @@ -17,7 +17,7 @@ Name: yast2 -Version: 4.1.76 +Version: 4.1.77 Release: 0 Summary: YaST2 - Main Package From af783b14dc38402d16bb9864d04d62d68041a609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Alejandro=20Anderssen=20Gonz=C3=A1lez?= Date: Mon, 13 Apr 2020 15:25:40 +0100 Subject: [PATCH 9/9] Changes based on CR --- library/network/src/modules/NetworkInterfaces.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/library/network/src/modules/NetworkInterfaces.rb b/library/network/src/modules/NetworkInterfaces.rb index 07aef718f..ea39c352e 100644 --- a/library/network/src/modules/NetworkInterfaces.rb +++ b/library/network/src/modules/NetworkInterfaces.rb @@ -1594,7 +1594,6 @@ def get_devices(devregex) # # @param iface [String] interface name of the config file to be deleted def delete_device(iface) - # delete config file p = path(".network.section") + iface log.debug("deleting: #{p}") SCR.Write(p, nil)