Skip to content

Commit

Permalink
Merge pull request #930 from yast/network-ng-keep_custom_udev_rules
Browse files Browse the repository at this point in the history
network-ng: keep custom udev rules
  • Loading branch information
imobachgs committed Sep 2, 2019
2 parents 8226572 + f46423e commit 13567d3
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 21 deletions.
10 changes: 10 additions & 0 deletions src/lib/y2network/interfaces_collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ def delete_if(&block)
self
end

# Returns all interfaces names
#
# For those interfaces that are renamed, the new and old names are included
# in the list.
#
# @return [Array<String>] List of known interfaces
def known_names
@interfaces.map { |i| [i.old_name, i.name] }.flatten.compact
end

# Compares InterfacesCollections
#
# @return [Boolean] true when both collections contain only equal interfaces,
Expand Down
13 changes: 11 additions & 2 deletions src/lib/y2network/sysconfig/interfaces_writer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,22 @@ def udev_rule_for(iface)
end
end

# Renames interfaces and refresh the udev service
# Renames interfaces and refreshes the udev service
#
# @param interfaces [InterfaceCollection] Interfaces
def update_udevd(interfaces)
update_udev_rules(interfaces)
reload_udev_rules
end

def update_udev_rules(interfaces)
udev_rules = interfaces.map { |i| udev_rule_for(i) }.compact
Y2Network::UdevRule.write(udev_rules)
known_names = interfaces.known_names
custom_rules = Y2Network::UdevRule.all.reject { |u| known_names.include?(u.device) }
Y2Network::UdevRule.write(custom_rules + udev_rules)
end

def reload_udev_rules
Yast::Execute.on_target("/usr/bin/udevadm", "control", "--reload")
Yast::Execute.on_target("/usr/bin/udevadm", "trigger", "--subsystem-match=net", "--action=add")
# wait so that ifcfgs written in NetworkInterfaces are newer
Expand Down
44 changes: 26 additions & 18 deletions src/lib/y2network/udev_rule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,24 @@ module Y2Network
# rule.to_s #=> "ACTION==\"add\", SUBSYSTEM==\"net\", ATTR{address}==\"?*31:78:f2\", NAME=\"eth0\""
class UdevRule
class << self
# Returns all persistent network rules
#
# @return [Array<UdevRule>] Persistent network rules
def all
return @all if @all
rules_map = Yast::SCR.Read(Yast::Path.new(".udev_persistent.net")) || {}
@all = rules_map.values.map do |parts|
udev_parts = parts.map { |p| UdevRulePart.from_string(p) }
new(udev_parts)
end
end

# Returns the udev rule for a given device
#
# @param device [String] Network device name
# @return [UdevRule] udev rule
def find_for(device)
return nil unless rules_map.key?(device)
parts = rules_map[device].map { |p| UdevRulePart.from_string(p) }
new(parts)
all.find { |r| r.device == device }
end

# Helper method to create a rename rule based on a MAC address
Expand Down Expand Up @@ -107,16 +117,7 @@ def write(udev_rules)

# Clears rules cache map
def reset_cache
@rules_map = nil
end

private

# Returns the rules map
#
# @return [Hash<String,Array<String>>] Rules parts (as strings) indexed by interface name
def rules_map
@rules_map ||= Yast::SCR.Read(Yast::Path.new(".udev_persistent.net")) || {}
@all = nil
end
end

Expand Down Expand Up @@ -148,17 +149,19 @@ def to_s

# Returns the part with the given key
#
# @param key [String] Key name
def part_by_key(key)
parts.find { |p| p.key == key }
# @param key [String] Key name to match
# @param operator [String,nil] Operator to match; nil omits matching the operator
def part_by_key(key, operator = nil)
parts.find { |p| p.key == key && (operator.nil? || p.operator == operator) }
end

# Returns the value for a given part
#
# @param key [String] Key name
# @param operator [String,nil] Operator to match; nil omits matching the operator
# @return [String,nil] Value or nil if not found a part which such a key
def part_value_for(key)
part = part_by_key(key)
def part_value_for(key, operator = nil)
part = part_by_key(key, operator)
return nil unless part
part.value
end
Expand Down Expand Up @@ -186,5 +189,10 @@ def bus_id
def dev_port
part_value_for("ATTR{dev_port}")
end

# Returns the device mentioned in the rule (if any)
def device
part_value_for("NAME", "=")
end
end
end
15 changes: 15 additions & 0 deletions test/y2network/interfaces_collection_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,19 @@
end
end
end

describe "#known_names" do
it "returns the list of known interfaces" do
expect(collection.known_names).to eq(["eth0", "br0", "wlan0"])
end

context "when an interface was renamed" do
before do
eth0.rename("eth1", :mac)
end
it "returns the old and the new names" do
expect(collection.known_names).to eq(["eth0", "eth1", "br0", "wlan0"])
end
end
end
end
16 changes: 16 additions & 0 deletions test/y2network/sysconfig/interfaces_writer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
before do
allow(Yast::Execute).to receive(:on_target)
allow(eth0).to receive(:hardware).and_return(hardware)
allow(writer).to receive(:sleep)
end

around do |example|
Expand Down Expand Up @@ -111,6 +112,21 @@
subject.write(interfaces)
end
end

context "when there is some rule for an unknown interface" do
let(:unknown_rule) { Y2Network::UdevRule.new_mac_based_rename("unknown", "00:11:22:33:44:55:66") }

before do
allow(Y2Network::UdevRule).to receive(:all).and_return([unknown_rule])
end

it "keeps the rule" do
expect(Y2Network::UdevRule).to receive(:write) do |rules|
expect(rules.first.to_s).to eq(unknown_rule.to_s)
end
subject.write(interfaces)
end
end
end

context "when the interface is not renamed" do
Expand Down
10 changes: 9 additions & 1 deletion test/y2network/udev_rule_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
end
end

describe "#bus_id" do
describe "#dev_port" do
subject(:udev_rule) { described_class.new_bus_id_based_rename("eth0", "0000:08:00.0", "1") }

it "returns the device port from the udev rule" do
Expand All @@ -155,4 +155,12 @@
end
end
end

describe "#device" do
subject(:udev_rule) { described_class.new_mac_based_rename("eth0", "01:23:45:67:89:ab") }

it "returns device" do
expect(udev_rule.device).to eq("eth0")
end
end
end

0 comments on commit 13567d3

Please sign in to comment.