Hello community, here is the log from the commit of package yast2-network for openSUSE:Factory checked in at 2017-08-04 11:57:29 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/yast2-network (Old) and /work/SRC/openSUSE:Factory/.yast2-network.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-network" Fri Aug 4 11:57:29 2017 rev:375 rq:514057 version:3.3.5 Changes: -------- --- /work/SRC/openSUSE:Factory/yast2-network/yast2-network.changes 2017-07-17 10:30:57.661344932 +0200 +++ /work/SRC/openSUSE:Factory/.yast2-network.new/yast2-network.changes 2017-08-04 11:57:31.939275787 +0200 @@ -1,0 +2,38 @@ +Wed Aug 2 13:01:48 UTC 2017 - [email protected] + +- bsc#1051624 + - Fix default values for not existent sysconfig network variables + when read. +- 3.3.5 + +------------------------------------------------------------------- +Fri Jul 28 08:46:43 UTC 2017 - [email protected] + +- bnc#1050986 + - fix udev rules export when more than one device is configured +- bnc#1037727 + - dhclient configuration warning message does not block AutoYaST +- 3.3.4 + +------------------------------------------------------------------- +Thu Jul 27 15:13:28 UTC 2017 - [email protected] + +- bsc#1039851 + - Host: Load /etc/hosts entries before import the ones defined in + a given AutoYaST profile making it backward compatible. + +------------------------------------------------------------------- +Wed Jul 12 05:37:30 UTC 2017 - [email protected] + +- bnc#1038717 + - avoid creating duplicate udev rules in AutoYaST installation + +------------------------------------------------------------------- +Fri Jul 11 09:40:11 UTC 2017 - [email protected] + +- bnc#1049814 + - Moving network setup in AY into first stage completely when + the second stage is disabled. +- 3.3.3 + +------------------------------------------------------------------- Old: ---- yast2-network-3.3.2.tar.bz2 New: ---- yast2-network-3.3.5.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yast2-network.spec ++++++ --- /var/tmp/diff_new_pack.JEykcN/_old 2017-08-04 11:57:32.707167403 +0200 +++ /var/tmp/diff_new_pack.JEykcN/_new 2017-08-04 11:57:32.715166273 +0200 @@ -17,7 +17,7 @@ Name: yast2-network -Version: 3.3.2 +Version: 3.3.5 Release: 0 BuildArch: noarch ++++++ yast2-network-3.3.2.tar.bz2 -> yast2-network-3.3.5.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/.travis.yml new/yast2-network-3.3.5/.travis.yml --- old/yast2-network-3.3.2/.travis.yml 2017-07-11 10:33:21.247935590 +0200 +++ new/yast2-network-3.3.5/.travis.yml 2017-08-02 15:32:11.173221713 +0200 @@ -5,6 +5,9 @@ before_install: - docker build -t yast-network-image . + # list the installed packages (just for easier debugging) + - docker run --rm -it yast-network-image rpm -qa | sort + script: # the "yast-travis-ruby" script is included in the base yastdevel/ruby image # see https://github.com/yast/docker-yast-ruby/blob/master/yast-travis-ruby diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/package/yast2-network.changes new/yast2-network-3.3.5/package/yast2-network.changes --- old/yast2-network-3.3.2/package/yast2-network.changes 2017-07-11 10:33:21.255935590 +0200 +++ new/yast2-network-3.3.5/package/yast2-network.changes 2017-08-02 15:32:11.181221713 +0200 @@ -1,4 +1,42 @@ ------------------------------------------------------------------- +Wed Aug 2 13:01:48 UTC 2017 - [email protected] + +- bsc#1051624 + - Fix default values for not existent sysconfig network variables + when read. +- 3.3.5 + +------------------------------------------------------------------- +Fri Jul 28 08:46:43 UTC 2017 - [email protected] + +- bnc#1050986 + - fix udev rules export when more than one device is configured +- bnc#1037727 + - dhclient configuration warning message does not block AutoYaST +- 3.3.4 + +------------------------------------------------------------------- +Thu Jul 27 15:13:28 UTC 2017 - [email protected] + +- bsc#1039851 + - Host: Load /etc/hosts entries before import the ones defined in + a given AutoYaST profile making it backward compatible. + +------------------------------------------------------------------- +Wed Jul 12 05:37:30 UTC 2017 - [email protected] + +- bnc#1038717 + - avoid creating duplicate udev rules in AutoYaST installation + +------------------------------------------------------------------- +Fri Jul 11 09:40:11 UTC 2017 - [email protected] + +- bnc#1049814 + - Moving network setup in AY into first stage completely when + the second stage is disabled. +- 3.3.3 + +------------------------------------------------------------------- Mon Jul 10 15:03:09 UTC 2017 - [email protected] - Fix crash during write if Host.Read and Host.Import is called diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/package/yast2-network.spec new/yast2-network-3.3.5/package/yast2-network.spec --- old/yast2-network-3.3.2/package/yast2-network.spec 2017-07-11 10:33:21.255935590 +0200 +++ new/yast2-network-3.3.5/package/yast2-network.spec 2017-08-02 15:32:11.181221713 +0200 @@ -17,7 +17,7 @@ Name: yast2-network -Version: 3.3.2 +Version: 3.3.5 Release: 0 BuildArch: noarch diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/src/clients/lan_auto.rb new/yast2-network-3.3.5/src/clients/lan_auto.rb --- old/yast2-network-3.3.2/src/clients/lan_auto.rb 2017-07-11 10:33:21.259935590 +0200 +++ new/yast2-network-3.3.5/src/clients/lan_auto.rb 2017-08-02 15:32:11.185221713 +0200 @@ -66,7 +66,7 @@ elsif @func == "Change" @ret = LanAutoSequence("") elsif @func == "Import" - @new = FromAY(@param) + @new = Lan.FromAY(@param) # see bnc#498993 # in case keep_install_network is set to true (in AY) # we'll keep values from installation @@ -124,131 +124,6 @@ @ret end - # If there's key in m, upcase key and assign the value to ret - # @return ret - def UpcaseCondSet(ret, m, key) - ret = deep_copy(ret) - m = deep_copy(m) - if Builtins.haskey(m, key) - Ops.set(ret, Builtins.toupper(key), Ops.get(m, key)) - end - deep_copy(ret) - end - - # Convert data from autoyast to structure used by module. - # @param [Hash] input autoyast settings - # @return native network settings - def FromAY(input) - input = deep_copy(input) - Builtins.y2debug("input %1", input) - - ifaces = [] - Builtins.foreach(Ops.get_list(input, "interfaces", [])) do |interface| - iface = {} - Builtins.foreach(interface) do |key, value| - if key == "aliases" - Builtins.foreach( - Convert.convert( - value, - from: "any", - to: "map <string, map <string, any>>" - ) - ) do |k, v| - # replace "alias0" to "0" (bnc#372687) - t = Convert.convert( - value, - from: "any", - to: "map <string, any>" - ) - Ops.set(t, Ops.get_string(v, "LABEL", ""), Ops.get_map(t, k, {})) - t = Builtins.remove(t, k) - value = deep_copy(t) - end - end - Ops.set(iface, key, value) - end - ifaces = Builtins.add(ifaces, iface) - end - Ops.set(input, "interfaces", ifaces) - - interfaces = Builtins.listmap(Ops.get_list(input, "interfaces", [])) do |interface| - # input: list of items $[ "device": "d", "foo": "f", "bar": "b"] - # output: map of items "d": $["FOO": "f", "BAR": "b"] - new_interface = {} - # uppercase map keys - newk = nil - interface = Builtins.mapmap(interface) do |k, v| - newk = if k == "aliases" - "_aliases" - else - Builtins.toupper(k) - end - { newk => v } - end - Builtins.foreach(interface) do |k, v| - Ops.set(new_interface, k, v) if v != "" && k != "DEVICE" - end - new_device = Ops.get_string(interface, "DEVICE", "") - { new_device => new_interface } - end - - # split to a two level map like NetworkInterfaces - devices = {} - - Builtins.foreach(interfaces) do |devname, if_data| - # devname can be in old-style fashion (eth-bus-<pci_id>). So, convert it - devname = LanItems.getDeviceName(devname) - type = NetworkInterfaces.GetType(devname) - d = Ops.get(devices, type, {}) - Ops.set(d, devname, if_data) - Ops.set(devices, type, d) - end - - hwcfg = {} - if Ops.greater_than(Builtins.size(Ops.get_list(input, "modules", [])), 0) - hwcfg = Builtins.listmap(Ops.get_list(input, "modules", [])) do |mod| - options = Ops.get_string(mod, "options", "") - module_name = Ops.get_string(mod, "module", "") - start_mode = Ops.get_string(mod, "startmode", "auto") - device_name = Ops.get_string(mod, "device", "") - module_data = { - "MODULE" => module_name, - "MODULE_OPTIONS" => options, - "STARTMODE" => start_mode - } - { device_name => module_data } - end - end - - Ops.set(input, "devices", devices) - Ops.set(input, "hwcfg", hwcfg) - - # DHCP:: config: some of it is in the DNS part of the profile - dhcp = {} - dhcpopts = Ops.get_map(input, "dhcp_options", {}) - dns = Ops.get_map(input, "dns", {}) - - if Builtins.haskey(dns, "dhcp_hostname") - Ops.set( - dhcp, - "DHCLIENT_SET_HOSTNAME", - Ops.get_boolean(dns, "dhcp_hostname", false) - ) - end - - dhcp = UpcaseCondSet(dhcp, dhcpopts, "dhclient_client_id") - dhcp = UpcaseCondSet(dhcp, dhcpopts, "dhclient_additional_options") - dhcp = UpcaseCondSet(dhcp, dhcpopts, "dhclient_hostname_option") - - Ops.set(input, "config", "dhcp" => dhcp) - if !Ops.get(input, "strict_IP_check_timeout").nil? - Ops.set(input, ["config", "config"], "CHECK_DUPLICATE_IP" => true) - end - - Builtins.y2milestone("input=%1", input) - deep_copy(input) - end - # Convert data from native network to autoyast for XML # @param [Hash] settings native network settings # @return [Hash] autoyast network settings diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/src/clients/save_network.rb new/yast2-network-3.3.5/src/clients/save_network.rb --- old/yast2-network-3.3.2/src/clients/save_network.rb 2017-07-11 10:33:21.259935590 +0200 +++ new/yast2-network-3.3.5/src/clients/save_network.rb 2017-08-02 15:32:11.185221713 +0200 @@ -259,16 +259,36 @@ DNS.create_hostname_link end + # Creates target's /etc/hosts configuration + # + # It uses hosts' configuration as defined in AY profile (if any) or + # proceedes according the proposal + def configure_hosts + configured = false + configured = NetworkAutoYast.instance.configure_hosts if Mode.autoinst + NetworkAutoconfiguration.instance.configure_hosts if !configured + end + + # Invokes configuration of parts which are in charge of Lan module + # + # Currently it handles just AutoYaST installation. It just exits in case + # of common installation as there currently is nothing to do. + def configure_lan + return if !Mode.autoinst + + NetworkAutoYast.instance.configure_lan + end + # It does an automatic configuration of installed system # # Basically, it runs several proposals. def configure_target NetworkAutoconfiguration.instance.configure_virtuals - configure_dns + configure_lan # this depends on DNS configuration - NetworkAutoconfiguration.instance.configure_hosts + configure_hosts set_network_service diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/src/include/network/routines.rb new/yast2-network-3.3.5/src/include/network/routines.rb --- old/yast2-network-3.3.2/src/include/network/routines.rb 2017-07-11 10:33:21.267935590 +0200 +++ new/yast2-network-3.3.5/src/include/network/routines.rb 2017-08-02 15:32:11.189221713 +0200 @@ -51,6 +51,7 @@ Yast.import "TypeRepository" Yast.import "Stage" Yast.import "PackagesProposal" + Yast.import "Report" end # Abort function @@ -978,7 +979,7 @@ # @param [Array<String>] list of incorrectly configured devices # @return [void] def fix_dhclient_warning(devs) - Popup.Warning(fix_dhclient_msg(devs)) + Report.Warning(fix_dhclient_msg(devs)) end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/src/lib/network/network_autoyast.rb new/yast2-network-3.3.5/src/lib/network/network_autoyast.rb --- old/yast2-network-3.3.2/src/lib/network/network_autoyast.rb 2017-07-11 10:33:21.279935590 +0200 +++ new/yast2-network-3.3.5/src/lib/network/network_autoyast.rb 2017-08-02 15:32:11.193221713 +0200 @@ -20,6 +20,8 @@ Yast.import "Lan" Yast.import "LanItems" Yast.import "Linuxrc" + Yast.import "Host" + Yast.import "Routing" end # Merges existing config from system into given configuration map @@ -104,26 +106,39 @@ NetworkService.EnableDisableNow end - # Initializates DNS setup according AY profile + # Initializates NICs setup according AY profile # - # FIXME: it currently doesn't write DNS configuration. It is used for initialization - # of DNS setup according AY profile in 1st stage as part of network setup was moved - # here already and some parts of network configuration needs to know it. DNS write - # is still done in 2nd stage. + # If the installer is running in 1st stage mode only, then the configuration + # is also written # + # @param [Boolean] write forces instant writing of the configuration # @return [Boolean] true when configuration was present and loaded from the profile - def configure_dns - ay_dns_config = ay_networking_section["dns"] + def configure_lan(write: false) + log.info("NetworkAutoYast: Lan configuration") - return false if !ay_dns_config + ay_configuration = Lan.FromAY(ay_networking_section) + ay_configuration = NetworkAutoYast.instance.merge_configs(ay_configuration) if keep_net_config? - DNS.Import(ay_dns_config) + configure_submodule(Lan, ay_configuration, write: write) + end + + # Initializates /etc/hosts according AY profile + # + # If the installer is running in 1st stage mode only, then the configuration + # is also written + # + # @param [Boolean] write forces instant writing of the configuration + # @return [Boolean] true when configuration was present and loaded from the profile + def configure_hosts(write: false) + log.info("NetworkAutoYast: Hosts configuration") - log.info("NetworkAutoYast: DNS / Hostname configuration") - log.info("dhcp hostname: #{DNS.dhcp_hostname}") - log.info("write hostname: #{DNS.write_hostname}") + hosts_config = (ay_host_section["hosts"] || {}).map do |host| + # we need to guarantee order of the items here + [host["host_address"] || "", host["names"] || []] + end + hosts_config = hosts_config.to_h.delete_if { |k, v| k.empty? || v.empty? } - true + configure_submodule(Host, "hosts" => hosts_config, write: write) end # Checks if the profile asks for keeping installation network configuration @@ -206,16 +221,53 @@ instsys_routing.merge(ay_routing) end - # Returns networking section of current AY profile - def ay_networking_section + # Returns current AY profile in the internal representation + # + # @return [Hash] hash representing current profile or empty hash + def ay_current_profile Yast.import "Profile" ay_profile = Profile.current return {} if ay_profile.nil? || ay_profile.empty? - return {} if ay_profile["networking"].nil? + ay_profile + end - ay_profile["networking"] + # Returns networking section of current AY profile + def ay_networking_section + return {} if ay_current_profile["networking"].nil? + + ay_current_profile["networking"] + end + + # Returns global section of current AY profile + def ay_general_section + return {} if ay_current_profile["general"].nil? + + ay_current_profile["general"] + end + + # Returns host section of the current AY profile + # + # Note that autoyast transforms the host's subsection + # into: + # { + # hosts => [ + # # first <host_entry> + # { + # "host_address" => <ip>, + # "names" => [list, of, names] + # } + # # second <host_entry> + # ... + # ] + # } + # + # return <Hash> with hosts configuration + def ay_host_section + return {} if ay_current_profile["host"].nil? + + ay_current_profile["host"] end # Checks if the udev rule is valid for renaming a NIC @@ -227,6 +279,38 @@ true end + # Renames a network device represented by given item. + # + # @param [Integer] item is an item id. See LanItems for detail + # @param [String] name_to new device name + # @param [String] attr an udev attribute usable in NIC's rule. Currently just + # "KERNELS" or "ATTR{address}" makes sense. This parameter is optional + # @param [String] value for the given udev attribute. Optional parameter. + def rename_lan_item(item, name_to, attr = nil, key = nil) + return if item.nil? || item < 0 || item >= LanItems.Items.size + return if name_to.nil? || name_to.empty? + + # selecting according device name is unreliable (selects only in between configured devices) + LanItems.current = item + + if !attr.nil? && !key.nil? + # find out what attribude is currently used for setting device name and + # change it if needed. Currently mac is used by default. So, we check is it is + # the other one (busid). If no we defaults to mac. + bus_attr = LanItems.GetItemUdev("KERNELS") + current_attr = bus_attr.empty? ? "ATTR{address}" : "KERNELS" + + # make sure that we base renaming on defined attribute with value given in AY profile + LanItems.ReplaceItemUdev(current_attr, attr, key) + elsif attr.nil? ^ key.nil? # xor + raise ArgumentError, "Not enough data for udev rule definition" + end + + LanItems.rename(name_to) + + nil + end + # Takes a list of udev rules and assignes them to corresponding devices. # # If a device has an udev rule defined already, it is overwritten by new one. @@ -242,28 +326,47 @@ next if !valid_rename_udev_rule?(rule) key.downcase! + # find item which matches to the given rule definition item, matching_item = LanItems.Items.find do |_, i| i["hwinfo"]["busid"].downcase == key || i["hwinfo"]["mac"].downcase == key end next if !matching_item - # for logging only name_from = matching_item["ifcfg"] || matching_item["dev_name"] log.info("Matching device found - renaming <#{name_from}> -> <#{name_to}>") - # selecting according device name is unreliable (selects only in between configured devices) - LanItems.current = item + # find rule in collision + colliding_item, _item_map = LanItems.Items.find do |i, _| + LanItems.GetDeviceName(i) == name_to + end - # find out what attribude is currently used for setting device name and - # change it if needed. Currently mac is used by default. So, we check is it is - # the other one (busid). If no we defaults to mac. - bus_attr = LanItems.GetItemUdev("KERNELS") - current_attr = bus_attr.empty? ? "ATTR{address}" : "KERNELS" + # rename item in collision + rename_lan_item(colliding_item, name_from) - # make sure that we base renaming on defined attribute with value given in AY profile - LanItems.ReplaceItemUdev(current_attr, attr, key) - LanItems.rename(name_to) + # rename matching item + rename_lan_item(item, name_to, attr, key) end end + + # Configures given yast submodule according AY configuration + # + # It takes data from AY profile transformed into a format expected by the YaST + # sub module's Import method. + # + # It imports the profile, configures the module and writes the configuration. + # Writing the configuration is optional when second stage is available and mandatory + # when running autoyast installation with first stage only. + def configure_submodule(yast_module, ay_config, write: false) + return false if !ay_config + + yast_module.Import(ay_config) + + write ||= !ay_general_section.fetch("mode", "second_stage" => true)["second_stage"] + log.info("Write configuration instantly: #{write}") + + yast_module.Write(gui: false) if write + + true + end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/src/modules/DNS.rb new/yast2-network-3.3.5/src/modules/DNS.rb --- old/yast2-network-3.3.2/src/modules/DNS.rb 2017-07-11 10:33:21.279935590 +0200 +++ new/yast2-network-3.3.5/src/modules/DNS.rb 2017-08-02 15:32:11.193221713 +0200 @@ -280,16 +280,12 @@ # Includes Host,NetworkConfig::Read # @return true if success def Read - return true if @initialized == true + return true if @initialized - tmp1 = Convert.to_string( - SCR.Read(path(".sysconfig.network.dhcp.DHCLIENT_SET_HOSTNAME")) - ) - @dhcp_hostname = tmp1 == "yes" - tmp2 = Convert.to_string( - SCR.Read(path(".sysconfig.network.dhcp.WRITE_HOSTNAME_TO_HOSTS")) - ) - @write_hostname = tmp2 == "yes" + # Used false as "no" is the default value in sysconfig for both + # attributes (bsc#bug_1051624) + @dhcp_hostname = dhclient_set_hostname || false + @write_hostname = get_write_hostname_to_hosts || false @resolv_conf_policy = Convert.to_string( SCR.Read(path(".sysconfig.network.config.NETCONFIG_DNS_POLICY")) @@ -325,59 +321,13 @@ Builtins.y2milestone("domain=%1", @domain) @initialized = true - true end # Write new DNS and hostname settings # Includes Host,NetworkConfig::Write # @return true if success - def Write - # build FQ hostname - fqhostname = Hostname.MergeFQ(@hostname, @domain) - - # We do not collect static IP addresses here, as hostnames - # are defined for each static IP separately in address dialog - # FaTE #2202 - - @oldhostname = fqhostname # #49634 - - # ensure that nothing is saved in case old values are the same, as it makes - # rcnetwork reload restart all interfaces (even 'touch /etc/sysconfig/network/dhcp' - # is sufficient) - tmp = SCR.Read(path(".sysconfig.network.dhcp.DHCLIENT_SET_HOSTNAME")) - old_dhcp_hostname = tmp == "yes" - - tmp = SCR.Read(path(".sysconfig.network.dhcp.WRITE_HOSTNAME_TO_HOSTS")) - old_write_hostname = tmp == "yes" - - if old_dhcp_hostname != dhcp_hostname || old_write_hostname != write_hostname - SCR.Write( - path(".sysconfig.network.dhcp.DHCLIENT_SET_HOSTNAME"), - @dhcp_hostname ? "yes" : "no" - ) - SCR.Write( - path(".sysconfig.network.dhcp.WRITE_HOSTNAME_TO_HOSTS"), - @write_hostname ? "yes" : "no" - ) - SCR.Write(path(".sysconfig.network.dhcp"), nil) - end - - Builtins.y2milestone("Writing configuration") - if !@modified - Builtins.y2milestone("No changes to DNS -> nothing to write") - return true - end - - Builtins.y2milestone("nameservers=%1", @nameservers) - Builtins.y2milestone("searchlist=%1", @searchlist) - Builtins.y2milestone("hostname=%1", @hostname) - Builtins.y2milestone("domain=%1", @domain) - Builtins.y2milestone( - "dhcp_hostname=%1, write_hostname=%2", - @dhcp_hostname, - @write_hostname - ) - + def Write(gui: true) + # Write process description labels steps = [ # Progress stage 1 _("Write hostname"), @@ -387,65 +337,37 @@ _("Update /etc/resolv.conf") ] + # ensure that nothing is saved in case old values are the same, as it makes + # rcnetwork reload restart all interfaces (even 'touch /etc/sysconfig/network/dhcp' + # is sufficient) + update_sysconfig_dhcp + + log.info("DNS: Writing configuration") + if !@modified + log.info("No changes to DNS -> nothing to write") + return true + end + # Write dialog caption caption = _("Saving Hostname and DNS Configuration") - sl = 0 # 100; for testing - - Progress.New(caption, " ", Builtins.size(steps), steps, [], "") - # Allow to set hostname even if it's modified by DHCP (#13427) - # if(NetworkConfig::DHCP["DHCLIENT_SET_HOSTNAME"]:false != true) { + Progress.New(caption, " ", Builtins.size(steps), steps, [], "") if gui # Progress step 1/3 - ProgressNextStage(_("Writing hostname...")) - - # change the hostname - SCR.Execute(path(".target.bash"), Ops.add("/bin/hostname ", @hostname)) - - # write hostname - SCR.Write( - path(".target.string"), - HOSTNAME_PATH, - Ops.add(fqhostname, "\n") - ) - - create_hostname_link - - Builtins.sleep(sl) + ProgressNextStage(_("Writing hostname...")) if gui + update_hostname # Progress step 2/3 - ProgressNextStage(_("Updating configuration...")) - - # Finish him + ProgressNextStage(_("Updating configuration...")) if gui update_mta_config - Builtins.sleep(sl) - - # if(SCR::Read(.target.size, resolv_conf) < 0) - # SCR::Write(.target.string, resolv_conf, ""); # Progress step 3/3 - ProgressNextStage(_("Updating /etc/resolv.conf ...")) - - SCR.Write( - path(".sysconfig.network.config.NETCONFIG_DNS_POLICY"), - @resolv_conf_policy - ) - SCR.Write( - path(".sysconfig.network.config.NETCONFIG_DNS_STATIC_SEARCHLIST"), - Builtins.mergestring(@searchlist, " ") - ) - SCR.Write( - path(".sysconfig.network.config.NETCONFIG_DNS_STATIC_SERVERS"), - Builtins.mergestring(@nameservers, " ") - ) - SCR.Write(path(".sysconfig.network.config"), nil) - - SCR.Execute(path(".target.bash"), "/sbin/netconfig update") - - Builtins.sleep(sl) + ProgressNextStage(_("Updating /etc/resolv.conf ...")) if gui + update_sysconfig_config - Progress.NextStage + Progress.NextStage if gui @modified = false + true end @@ -720,6 +642,90 @@ @nameservers.empty? && @searchlist.empty? && @hostname.empty? && @domain.empty? end + # Updates /etc/sysconfig/network/dhcp + def update_sysconfig_dhcp + if dhclient_set_hostname != @dhcp_hostname || get_write_hostname_to_hosts != @write_hostname + log.info("dhcp_hostname=#{@dhcp_hostname}") + log.info("write_hostname=#{@write_hostname}") + + # @dhcp_hostname and @wrote_hostname can currently be nil only when + # not present in original file. So, do not add it in such case. + SCR.Write( + path(".sysconfig.network.dhcp.DHCLIENT_SET_HOSTNAME"), + @dhcp_hostname ? "yes" : "no" + ) if !@dhcp_hostname.nil? + SCR.Write( + path(".sysconfig.network.dhcp.WRITE_HOSTNAME_TO_HOSTS"), + @write_hostname ? "yes" : "no" + ) if !@write_hostname.nil? + SCR.Write(path(".sysconfig.network.dhcp"), nil) + else + log.info("No update for /etc/sysconfig/network/dhcp") + end + end + + # Updates system with new hostname + def update_hostname + log.info("hostname=#{@hostname}") + log.info("domain=#{@domain}") + + # change the hostname + SCR.Execute(path(".target.bash"), Ops.add("/bin/hostname ", @hostname)) + + # build and write FQDN hostname + fqhostname = Hostname.MergeFQ(@hostname, @domain) + @oldhostname = fqhostname # #49634 + + SCR.Write( + path(".target.string"), + HOSTNAME_PATH, + Ops.add(fqhostname, "\n") + ) + + create_hostname_link + end + + # Updates /etc/sysconfig/network/config + def update_sysconfig_config + log.info("nameservers=#{@nameservers}") + log.info("searchlist=#{@searchlist}") + + SCR.Write( + path(".sysconfig.network.config.NETCONFIG_DNS_POLICY"), + @resolv_conf_policy + ) + SCR.Write( + path(".sysconfig.network.config.NETCONFIG_DNS_STATIC_SEARCHLIST"), + Builtins.mergestring(@searchlist, " ") + ) + SCR.Write( + path(".sysconfig.network.config.NETCONFIG_DNS_STATIC_SERVERS"), + Builtins.mergestring(@nameservers, " ") + ) + SCR.Write(path(".sysconfig.network.config"), nil) + + SCR.Execute(path(".target.bash"), "/sbin/netconfig update") + end + + # A constant for translating sysconfig's yes/no values into boolean + SYSCFG_TO_BOOL = { "yes" => true, "no" => false }.freeze + + # Reads value of DHCLIENT_SET_HOSTNAME and translates it to boolean + # + # return {true, false, nil} "yes" => true, "no" => false, otherwise or not + # present => nil + def dhclient_set_hostname + SYSCFG_TO_BOOL[SCR.Read(path(".sysconfig.network.dhcp.DHCLIENT_SET_HOSTNAME"))] + end + + # Reads value of WRITE_HOSTNAME_TO_HOSTS and translates it to boolean + # + # return {true, false, nil} "yes" => true, "no" => false, otherwise or not + # present => nil + def get_write_hostname_to_hosts + SYSCFG_TO_BOOL[SCR.Read(path(".sysconfig.network.dhcp.WRITE_HOSTNAME_TO_HOSTS"))] + end + publish variable: :proposal_valid, type: "boolean" publish variable: :hostname, type: "string" publish variable: :domain, type: "string" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/src/modules/Host.rb new/yast2-network-3.3.5/src/modules/Host.rb --- old/yast2-network-3.3.2/src/modules/Host.rb 2017-07-11 10:33:21.279935590 +0200 +++ new/yast2-network-3.3.5/src/modules/Host.rb 2017-08-02 15:32:11.193221713 +0200 @@ -127,7 +127,7 @@ # Write hosts settings and apply changes # @return true if success - def Write + def Write(gui: false) Builtins.y2milestone("Writing hosts configuration") if !@modified @@ -141,13 +141,15 @@ return true end - steps = [_("Update /etc/hosts")] + if gui + steps = [_("Update /etc/hosts")] - caption = _("Saving Hostname Configuration") + caption = _("Saving Hostname Configuration") - Progress.New(caption, " ", steps.size, steps, [], "") + Progress.New(caption, " ", steps.size, steps, [], "") - ProgressNextStage(_("Updating /etc/hosts ...")) + ProgressNextStage(_("Updating /etc/hosts ...")) + end # backup if exists if SCR.Read(path(".target.size"), CFA::Hosts::PATH) >= 0 @@ -156,7 +158,7 @@ @hosts.save - Progress.NextStage + Progress.NextStage if gui true end @@ -164,13 +166,18 @@ # Get all the Hosts configuration from a map. # When called by hosts_auto (preparing autoinstallation data) # the map may be empty. + # # @param [Hash] settings autoinstallation settings + # expected format of settings["hosts"] is { "ip" => [list, of, names] } # @return true if success def Import(settings) @modified = true # trigger Write @initialized = true # don't let Read discard our data @hosts = CFA::Hosts.new + # Load default entries (bsc#1039851) + @hosts.load + imported_hosts = Builtins.eval(Ops.get_map(settings, "hosts", {})) # convert from old format to the new one diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/src/modules/Lan.rb new/yast2-network-3.3.5/src/modules/Lan.rb --- old/yast2-network-3.3.2/src/modules/Lan.rb 2017-07-11 10:33:21.283935590 +0200 +++ new/yast2-network-3.3.5/src/modules/Lan.rb 2017-08-02 15:32:11.193221713 +0200 @@ -473,7 +473,7 @@ # Update the SCR according to network settings # @return true on success - def Write + def Write(gui: true) Builtins.y2milestone("Writing configuration") # Query modified flag in all components, not just LanItems - DNS, @@ -547,7 +547,7 @@ # Progress step 5 ProgressNextStage(_("Writing routing configuration...")) orig = Progress.set(false) - Routing.Write + Routing.Write(gui: gui) Progress.set(orig) Builtins.sleep(sl) @@ -557,9 +557,9 @@ # write resolv.conf after change from dhcp to static (#327074) # reload/restart network before this to put correct resolv.conf from dhcp-backup orig = Progress.set(false) - DNS.Write + DNS.Write(gui: gui) Host.EnsureHostnameResolvable - Host.Write + Host.Write(gui: gui) Progress.set(orig) Builtins.sleep(sl) @@ -644,6 +644,132 @@ Write() end + # If there's key in m, upcase key and assign the value to ret + # @return ret + def UpcaseCondSet(ret, m, key) + ret = deep_copy(ret) + m = deep_copy(m) + if Builtins.haskey(m, key) + Ops.set(ret, Builtins.toupper(key), Ops.get(m, key)) + end + deep_copy(ret) + end + + # Convert data from autoyast to structure used by module. + # @param [Hash] input autoyast settings + # @return native network settings + # FIXME: massive refactoring required + def FromAY(input) + input = deep_copy(input) + Builtins.y2debug("input %1", input) + + ifaces = [] + Builtins.foreach(Ops.get_list(input, "interfaces", [])) do |interface| + iface = {} + Builtins.foreach(interface) do |key, value| + if key == "aliases" + Builtins.foreach( + Convert.convert( + value, + from: "any", + to: "map <string, map <string, any>>" + ) + ) do |k, v| + # replace "alias0" to "0" (bnc#372687) + t = Convert.convert( + value, + from: "any", + to: "map <string, any>" + ) + Ops.set(t, Ops.get_string(v, "LABEL", ""), Ops.get_map(t, k, {})) + t = Builtins.remove(t, k) + value = deep_copy(t) + end + end + Ops.set(iface, key, value) + end + ifaces = Builtins.add(ifaces, iface) + end + Ops.set(input, "interfaces", ifaces) + + interfaces = Builtins.listmap(Ops.get_list(input, "interfaces", [])) do |interface| + # input: list of items $[ "device": "d", "foo": "f", "bar": "b"] + # output: map of items "d": $["FOO": "f", "BAR": "b"] + new_interface = {} + # uppercase map keys + newk = nil + interface = Builtins.mapmap(interface) do |k, v| + newk = if k == "aliases" + "_aliases" + else + Builtins.toupper(k) + end + { newk => v } + end + Builtins.foreach(interface) do |k, v| + Ops.set(new_interface, k, v) if v != "" && k != "DEVICE" + end + new_device = Ops.get_string(interface, "DEVICE", "") + { new_device => new_interface } + end + + # split to a two level map like NetworkInterfaces + devices = {} + + Builtins.foreach(interfaces) do |devname, if_data| + # devname can be in old-style fashion (eth-bus-<pci_id>). So, convert it + devname = LanItems.getDeviceName(devname) + type = NetworkInterfaces.GetType(devname) + d = Ops.get(devices, type, {}) + Ops.set(d, devname, if_data) + Ops.set(devices, type, d) + end + + hwcfg = {} + if Ops.greater_than(Builtins.size(Ops.get_list(input, "modules", [])), 0) + hwcfg = Builtins.listmap(Ops.get_list(input, "modules", [])) do |mod| + options = Ops.get_string(mod, "options", "") + module_name = Ops.get_string(mod, "module", "") + start_mode = Ops.get_string(mod, "startmode", "auto") + device_name = Ops.get_string(mod, "device", "") + module_data = { + "MODULE" => module_name, + "MODULE_OPTIONS" => options, + "STARTMODE" => start_mode + } + { device_name => module_data } + end + end + + Ops.set(input, "devices", devices) + Ops.set(input, "hwcfg", hwcfg) + + # DHCP:: config: some of it is in the DNS part of the profile + dhcp = {} + dhcpopts = Ops.get_map(input, "dhcp_options", {}) + dns = Ops.get_map(input, "dns", {}) + + if Builtins.haskey(dns, "dhcp_hostname") + Ops.set( + dhcp, + "DHCLIENT_SET_HOSTNAME", + Ops.get_boolean(dns, "dhcp_hostname", false) + ) + end + + dhcp = UpcaseCondSet(dhcp, dhcpopts, "dhclient_client_id") + dhcp = UpcaseCondSet(dhcp, dhcpopts, "dhclient_additional_options") + dhcp = UpcaseCondSet(dhcp, dhcpopts, "dhclient_hostname_option") + + Ops.set(input, "config", "dhcp" => dhcp) + if !Ops.get(input, "strict_IP_check_timeout").nil? + Ops.set(input, ["config", "config"], "CHECK_DUPLICATE_IP" => true) + end + + Builtins.y2milestone("input=%1", input) + deep_copy(input) + end + # Import data. # It expects data described networking.rnc # and then passed through {LanAutoClient#FromAY}. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/src/modules/LanItems.rb new/yast2-network-3.3.5/src/modules/LanItems.rb --- old/yast2-network-3.3.2/src/modules/LanItems.rb 2017-07-11 10:33:21.283935590 +0200 +++ new/yast2-network-3.3.5/src/modules/LanItems.rb 2017-08-02 15:32:11.193221713 +0200 @@ -2726,7 +2726,7 @@ end else configured = Items().select { |i, _| IsItemConfigured(i) } - configured.each do |id, _| + ay["net-udev"] = configured.keys.each_with_object({}) do |id, udev| @current = id # for GetItemUdev name = GetItemUdev("NAME").to_s @@ -2734,12 +2734,10 @@ next if !rule || name.empty? - ay["net-udev"] = { - name => { - "rule" => rule, - "name" => name, - "value" => GetItemUdev(rule) - } + udev[name] = { + "rule" => rule, + "name" => name, + "value" => GetItemUdev(rule) } end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/src/modules/Routing.rb new/yast2-network-3.3.5/src/modules/Routing.rb --- old/yast2-network-3.3.2/src/modules/Routing.rb 2017-07-11 10:33:21.283935590 +0200 +++ new/yast2-network-3.3.5/src/modules/Routing.rb 2017-08-02 15:32:11.197221713 +0200 @@ -300,7 +300,7 @@ # Write routing settings and apply changes # @return true if success - def Write + def Write(gui: false) Builtins.y2milestone("Writing configuration") if !Modified() Builtins.y2milestone("No changes to routing -> nothing to write") @@ -316,10 +316,12 @@ caption = _("Saving Routing Configuration") - Progress.New(caption, " ", Builtins.size(steps), steps, [], "") + if gui + Progress.New(caption, " ", Builtins.size(steps), steps, [], "") - # Progress stage 1/2 - ProgressNextStage(_("Writing IP forwarding settings...")) + # Progress stage 1/2 + ProgressNextStage(_("Writing IP forwarding settings...")) + end WriteIPForwarding() @@ -329,11 +331,11 @@ # so we let our caller do it together with other things # Progress stage 2/2 - ProgressNextStage(_("Writing routing settings...")) + ProgressNextStage(_("Writing routing settings...")) if gui ret = write_routes(@Routes) - Progress.NextStage + Progress.NextStage if gui ret end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/test/data/default_hosts new/yast2-network-3.3.5/test/data/default_hosts --- old/yast2-network-3.3.2/test/data/default_hosts 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-network-3.3.5/test/data/default_hosts 2017-08-02 15:32:11.197221713 +0200 @@ -0,0 +1,22 @@ +# +# hosts This file describes a number of hostname-to-address +# mappings for the TCP/IP subsystem. It is mostly +# used at boot time, when no name servers are running. +# On small systems, this file can be used instead of a +# "named" name server. +# Syntax: +# +# IP-Address Full-Qualified-Hostname Short-Hostname +# + +127.0.0.1 localhost + +# special IPv6 addresses +::1 localhost ipv6-localhost ipv6-loopback + +fe00::0 ipv6-localnet + +ff00::0 ipv6-mcastprefix +ff02::1 ipv6-allnodes +ff02::2 ipv6-allrouters +ff02::3 ipv6-allhosts diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/test/host_test.rb new/yast2-network-3.3.5/test/host_test.rb --- old/yast2-network-3.3.2/test/host_test.rb 2017-07-11 10:33:21.291935590 +0200 +++ new/yast2-network-3.3.5/test/host_test.rb 2017-08-02 15:32:11.201221713 +0200 @@ -114,10 +114,52 @@ end end + describe ".Import" do + let(:file) do + file_path = File.expand_path("../data/default_hosts", __FILE__) + CFA::MemoryFile.new(File.read(file_path)) + end + + let(:etc_hosts) do + { + "127.0.0.1" => ["localhost"], + "::1" => ["localhost ipv6-localhost ipv6-loopback"], + "fe00::0" => ["ipv6-localnet"], + "ff00::0" => ["ipv6-mcastprefix"], + "ff02::1" => ["ipv6-allnodes"], + "ff02::2" => ["ipv6-allrouters"], + "ff02::3" => ["ipv6-allhosts"] + } + end + + it "loads the current '/etc/hosts' entries" do + Yast::Host.Import("hosts" => {}) + + expect(Yast::Host.name_map).to eql(etc_hosts) + end + + it "merges current entries with the given ones" do + Yast::Host.Import("hosts" => { "10.20.1.29" => ["beholder"] }) + + expect(Yast::Host.name_map).to eql(etc_hosts.merge("10.20.1.29" => ["beholder"])) + end + end + describe ".Export" do + let(:file) do + file_path = File.expand_path("../data/default_hosts", __FILE__) + CFA::MemoryFile.new(File.read(file_path)) + end + let(:etc_hosts) do { "127.0.0.1" => ["localhost localhost.localdomain"], + "::1" => ["localhost ipv6-localhost ipv6-loopback"], + "fe00::0" => ["ipv6-localnet"], + "ff00::0" => ["ipv6-mcastprefix"], + "ff02::1" => ["ipv6-allnodes"], + "ff02::2" => ["ipv6-allrouters"], + "ff02::3" => ["ipv6-allhosts"], "10.20.1.29" => ["beholder"] } end @@ -128,12 +170,24 @@ end it "removes empty name lists" do - Yast::Host.Import("hosts" => { "127.0.0.1" => ["localhost"], "10.0.0.1" => [] }) - expect(Yast::Host.Export).to eql("hosts" => { "127.0.0.1" => ["localhost"] }) + Yast::Host.Import("hosts" => { "127.0.0.1" => ["localhost localhost.localdomain"], "10.20.1.29" => [] }) + etc_hosts.delete("10.20.1.29") + + expect(Yast::Host.Export).to eql("hosts" => etc_hosts) end it "exports empty hash when no mapping is defined" do - Yast::Host.Import("hosts" => {}) + Yast::Host.Import( + "hosts" => { + "127.0.0.1" => [], + "::1" => [], + "fe00::0" => [], + "ff00::0" => [], + "ff02::1" => [], + "ff02::2" => [], + "ff02::3" => [] + } + ) expect(Yast::Host.Export).to be_empty end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/test/lan_items_export_test.rb new/yast2-network-3.3.5/test/lan_items_export_test.rb --- old/yast2-network-3.3.2/test/lan_items_export_test.rb 2017-07-11 10:33:21.291935590 +0200 +++ new/yast2-network-3.3.5/test/lan_items_export_test.rb 2017-08-02 15:32:11.201221713 +0200 @@ -20,26 +20,73 @@ let(:scr) { Yast::SCR } + let(:is_s390) { false } + + let(:eth0) do + { + "hwinfo" => { "dev_name" => "eth0" }, + "udev" => { + "net" => [ + "SUBSYSTEM==\"net\"", "ACTION==\"add\"", "DRIVERS==\"?*\"", "ATTR{type}==\"1\"", + "ATTR{address}==\"00:50:56:12:34:56\"", "NAME=\"eth0\"" + ] + } + } + end + + let(:eth1) do + { + "hwinfo" => { "dev_name" => "eth1" }, + "udev" => { + "net" => [ + "SUBSYSTEM==\"net\"", "ACTION==\"add\"", "DRIVERS==\"?*\"", + "KERNELS==\"0000:00:1f.6\"", "NAME=\"eth1\"" + ] + } + } + end + + let(:items) { { 0 => eth0, 1 => eth1 } } + before(:each) do # mock SCR to not touch system allow(scr).to receive(:Read).and_return("") allow(scr).to receive(:Execute).and_return("exit" => -1, "stdout" => "", "stderr" => "") + allow(subject).to receive(:IsItemConfigured).and_return(true) + allow(subject).to receive(:Items).and_return(items) end - def path(p) - Yast::Path.new(p) + before(:each) do + allow(Yast::Arch).to receive(:s390).and_return(is_s390) end - context "When running on s390" do - before(:each) do - allow(Yast::Arch).to receive(:s390).and_return(true) + it "exports udev rules" do + ay = subject.send(:export_udevs, devices) + expect(ay["net-udev"]).to eq( + "eth0" => { "rule" => "ATTR{address}", "name" => "eth0", "value" => "00:50:56:12:34:56" }, + "eth1" => { "rule" => "KERNELS", "name" => "eth1", "value" => "0000:00:1f.6" } + ) + end + + context "when an interface is not configured" do + before do + allow(subject).to receive(:IsItemConfigured).with(1).and_return(false) + end + + it "does not include an udev rule for that interface" do + ay = subject.send(:export_udevs, devices) + expect(ay["net-udev"].keys).to eq(["eth0"]) end + end + + context "When running on s390" do + let(:is_s390) { true } # kind of smoke test it "produces s390 specific content in exported AY profile" do allow(scr) .to receive(:Execute) - .with(path(".target.bash_output"), /^driver=.*/) + .with(Yast::Path.new(".target.bash_output"), /^driver=.*/) .and_return("exit" => 0, "stdout" => "qeth", "stderr" => "") ay = subject.send(:export_udevs, devices) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/test/lan_test.rb new/yast2-network-3.3.5/test/lan_test.rb --- old/yast2-network-3.3.2/test/lan_test.rb 2017-07-11 10:33:21.291935590 +0200 +++ new/yast2-network-3.3.5/test/lan_test.rb 2017-08-02 15:32:11.201221713 +0200 @@ -389,3 +389,71 @@ end end end + +describe "LanClass#FromAY" do + it "makes a minimal structure from an empty input" do + expected = { + "config" => { "dhcp"=>{} }, + "devices" => {}, + "hwcfg" => {}, + "interfaces" => [] + } + expect(Yast::Lan.FromAY({})).to eq(expected) + end + + it "converts 'interfaces' into nested 'devices'" do + input = { + "interfaces" => [ + { + "bootproto" => "static", + "device" => "eth1", + "ipaddr" => "10.1.1.1", + "name" => "Ethernet Card 0", + "prefixlen" => "24", + "startmode" => "auto", + "usercontrol" => "no" + } + ] + } + expected = { + "eth" => { + "eth1" => { + "BOOTPROTO" => "static", + "IPADDR" => "10.1.1.1", + "NAME" => "Ethernet Card 0", + "PREFIXLEN" => "24", + "STARTMODE" => "auto", + "USERCONTROL" => "no" + } + } + } + + expect(Yast::Lan.FromAY(input)["devices"]).to eq(expected) + end + + it "converts DHCP options" do + input = { + "dhcp_options" => { + "dhclient_hostname_option" => "AUTO" + }, + "dns" => { + "dhcp_hostname" => false, + "domain" => "example.com", + "hostname" => "eg", + "nameservers" => ["10.10.0.100"], + "resolv_conf_policy" => "auto", + "searchlist" => ["example.com"], + "write_hostname" => false + } + } + expected_config = { + "dhcp" => { + "DHCLIENT_HOSTNAME_OPTION" => "AUTO", + "DHCLIENT_SET_HOSTNAME" => false + } + } + + actual = Yast::Lan.FromAY(input) + expect(actual["config"]).to eq(expected_config) + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.3.2/test/network_autoyast_test.rb new/yast2-network-3.3.5/test/network_autoyast_test.rb --- old/yast2-network-3.3.2/test/network_autoyast_test.rb 2017-07-11 10:33:21.295935590 +0200 +++ new/yast2-network-3.3.5/test/network_autoyast_test.rb 2017-08-02 15:32:11.205221713 +0200 @@ -210,22 +210,6 @@ end end - describe "#configure_dns" do - let(:network_autoyast) { Yast::NetworkAutoYast.instance } - - it "imports DNS configuration when available in profile" do - Yast.import "DNS" - - allow(network_autoyast) - .to receive(:ay_networking_section) - .and_return("dns" => { "dhcp_hostname" => false }) - - expect(Yast::DNS).to receive(:Import) - - network_autoyast.configure_dns - end - end - describe "#keep_net_config?" do let(:network_autoyast) { Yast::NetworkAutoYast.instance } @@ -347,4 +331,62 @@ expect(network_autoyast.send(:valid_rename_udev_rule?, complete_rule)).to be true end end + + describe "#rename_lan_item" do + before(:each) do + allow(Yast::LanItems) + .to receive(:Items) + .and_return(0 => { "ifcfg" => "eth0" }) + end + + context "valid arguments given" do + it "renames the item with no udev attribute change" do + expect(Yast::LanItems) + .to receive(:rename) + .with("new_name") + expect(Yast::LanItems) + .not_to receive(:ReplaceItemUdev) + + network_autoyast.send(:rename_lan_item, 0, "new_name") + end + + it "renames the item with udev attribute change" do + expect(Yast::LanItems) + .to receive(:rename) + .with("new_name") + expect(Yast::LanItems) + .to receive(:ReplaceItemUdev) + + network_autoyast.send(:rename_lan_item, 0, "new_name", "KERNELS", "0000:00:03.0") + end + end + + context "invalid arguments given" do + it "do not try to rename an item when missing new name" do + expect(Yast::LanItems) + .not_to receive(:rename) + + network_autoyast.send(:rename_lan_item, 0, nil) + network_autoyast.send(:rename_lan_item, 0, "") + end + + it "do not try to rename an item when given item id is invalid" do + expect(Yast::LanItems) + .not_to receive(:rename) + + network_autoyast.send(:rename_lan_item, nil, "new_name") + network_autoyast.send(:rename_lan_item, -1, "new_name") + network_autoyast.send(:rename_lan_item, 100, "new_name") + end + + it "raise an exception when udev definition is incomplete" do + expect do + network_autoyast.send(:rename_lan_item, 0, "new_name", "KERNELS", nil) + end.to raise_error(ArgumentError) + expect do + network_autoyast.send(:rename_lan_item, 0, "new_name", nil, "0000:00:03.0") + end.to raise_error(ArgumentError) + end + end + end end
