Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AutoYaST: Support to configure the network during the first stage by default #1059

Merged
merged 16 commits into from
May 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,4 @@ testsuite/run/
.yardoc
/coverage
*.pot
config.*
/test/data/scr_read/var/log
7 changes: 7 additions & 0 deletions package/yast2-network.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
-------------------------------------------------------------------
Wed May 20 13:07:13 UTC 2020 - Knut Anderssen <kanderssen@suse.com>

- AutoYaST: Adapted the module to handle a complete network
configuration during the first stage (bsc#1171922)
- 4.3.1

-------------------------------------------------------------------
Tue May 12 13:08:03 UTC 2020 - Josef Reidinger <jreidinger@suse.com>

Expand Down
2 changes: 1 addition & 1 deletion package/yast2-network.spec
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@


Name: yast2-network
Version: 4.3.0
Version: 4.3.1
Release: 0
Summary: YaST2 - Network Configuration
License: GPL-2.0-only
Expand Down
206 changes: 2 additions & 204 deletions src/clients/lan_auto.rb
Original file line number Diff line number Diff line change
@@ -1,205 +1,3 @@
# ***************************************************************************
#
# Copyright (c) 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
#
# **************************************************************************
require "y2network/clients/auto"

require "network/network_autoyast"

module Yast
# Client providing autoyast functionality
class LanAutoClient < Client
def main
Yast.import "UI"

textdomain "network"

Builtins.y2milestone("----------------------------------------")
Builtins.y2milestone("Lan autoinst client started")

Yast.import "Lan"
Yast.import "Progress"
Yast.import "Map"
Yast.import "NetworkInterfaces"
Yast.import "LanItems"
Yast.include self, "network/lan/wizards.rb"
Yast.include self, "network/routines.rb"

@func = ""
@param = {}

# Check arguments
if Ops.greater_than(Builtins.size(WFM.Args), 0) &&
Ops.is_string?(WFM.Args(0))
@func = Convert.to_string(WFM.Args(0))
if Ops.greater_than(Builtins.size(WFM.Args), 1) &&
Ops.is_map?(WFM.Args(1))
@param = Convert.to_map(WFM.Args(1))
end
end

Builtins.y2milestone("Lan autoinst callback: #{@func}")

if @func == "Summary"
@ret = Lan.Summary("summary")
elsif @func == "Reset"
Lan.Import({})
Yast::Lan.clear_configs
@ret = {}
elsif @func == "Change"
Yast::Lan.add_config(:yast, Y2Network::Config.from(:defaults)) unless Yast::Lan.yast_config
@ret = LanAutoSequence("")
elsif @func == "Import"
@new = Lan.FromAY(@param)
# see bnc#498993
# in case keep_install_network is set to true (in AY)
# we'll keep values from installation
# and merge with XML data (bnc#712864)
@new = NetworkAutoYast.instance.merge_configs(@new) if @new["keep_install_network"]

Lan.Import(@new)
@ret = true
elsif @func == "Read"
@progress_orig = Progress.set(false)
@ret = Lan.Read(:nocache)
Progress.set(@progress_orig)
elsif @func == "Packages"
@ret = Lan.AutoPackages
elsif @func == "SetModified"
@ret = Lan.SetModified
elsif @func == "GetModified"
@ret = Lan.Modified
elsif @func == "Export"
@settings2 = Lan.Export
Builtins.y2debug("settings: %1", @settings2)
@autoyast = ToAY(@settings2)
@ret = deep_copy(@autoyast)
elsif @func == "Write"
@progress_orig = Progress.set(false)

result = Lan.WriteOnly
Builtins.y2error("Writing lan config failed") if !result
@ret &&= result

if Ops.get(LanItems.autoinstall_settings, "strict_IP_check_timeout")
if Lan.isAnyInterfaceDown
@timeout = Ops.get_integer(
LanItems.autoinstall_settings,
"strict_IP_check_timeout",
0
)
Builtins.y2debug("timeout %1", @timeout)
@error_text = _("Configuration Error: uninitialized interface.")
if @timeout == 0
Popup.Error(@error_text)
else
Popup.TimedError(@error_text, @timeout)
end
end
end
Progress.set(@progress_orig)
else
Builtins.y2error("unknown function: %1", @func)
@ret = false
end

Builtins.y2milestone("Lan auto finished (#{@ret})")
Builtins.y2milestone("----------------------------------------")
@ret
end

# Convert data from native network to autoyast for XML
# @param [Hash] settings native network settings
# @return [Hash] autoyast network settings
def ToAY(settings)
settings = deep_copy(settings)
interfaces = settings["interfaces"] || []
Builtins.y2milestone("interfaces: #{interfaces.inspect})")
net_udev = settings["net-udev"] || []
Builtins.y2milestone("net-udev: #{net_udev.inspect})")

# Modules
s390_devices = settings["s390-devices"] || []
Builtins.y2milestone("s390-devices: #{s390_devices.inspect})")

modules = []
Builtins.foreach(Ops.get_map(settings, "hwcfg", {})) do |device, mod|
newmap = {}
Ops.set(newmap, "device", device)
Ops.set(newmap, "module", Ops.get_string(mod, "MODULE", ""))
Ops.set(newmap, "options", Ops.get_string(mod, "MODULE_OPTIONS", ""))
modules = Builtins.add(modules, newmap)
end

config = Ops.get_map(settings, "config", {})
dhcp = Ops.get_map(config, "dhcp", {})
dhcp_hostname = Ops.get_boolean(dhcp, "DHCLIENT_SET_HOSTNAME", false)
dns = Ops.get_map(settings, "dns", {})
Ops.set(dns, "dhcp_hostname", dhcp_hostname)
dhcpopts = {}
if Builtins.haskey(dhcp, "DHCLIENT_HOSTNAME_OPTION")
Ops.set(
dhcpopts,
"dhclient_hostname_option",
Ops.get_string(dhcp, "DHCLIENT_HOSTNAME_OPTION", "AUTO")
)
end
if Builtins.haskey(dhcp, "DHCLIENT_ADDITIONAL_OPTIONS")
Ops.set(
dhcpopts,
"dhclient_additional_options",
Ops.get_string(dhcp, "DHCLIENT_ADDITIONAL_OPTIONS", "")
)
end
if Builtins.haskey(dhcp, "DHCLIENT_CLIENT_ID")
Ops.set(
dhcpopts,
"dhclient_client_id",
Ops.get_string(dhcp, "DHCLIENT_CLIENT_ID", "")
)
end

ret = {}
Ops.set(ret, "managed", Ops.get_boolean(settings, "managed", false))
if Builtins.haskey(settings, "ipv6")
Ops.set(ret, "ipv6", Ops.get_boolean(settings, "ipv6", true))
end
Ops.set(
ret,
"keep_install_network",
Ops.get_boolean(settings, "keep_install_network", true)
)
Ops.set(ret, "modules", modules) if Ops.greater_than(Builtins.size(modules), 0)
Ops.set(ret, "dns", dns) if Ops.greater_than(Builtins.size(dns), 0)
Ops.set(ret, "dhcp_options", dhcpopts) if Ops.greater_than(Builtins.size(dhcpopts), 0)
if Ops.greater_than(
Builtins.size(Ops.get_map(settings, "routing", {})),
0
)
Ops.set(ret, "routing", Ops.get_map(settings, "routing", {}))
end
Ops.set(ret, "interfaces", interfaces) if Ops.greater_than(Builtins.size(interfaces), 0)
Ops.set(ret, "s390-devices", s390_devices) if Ops.greater_than(Builtins.size(s390_devices), 0)
Ops.set(ret, "net-udev", net_udev) if Ops.greater_than(Builtins.size(net_udev), 0)
deep_copy(ret)
end
end
end

Yast::LanAutoClient.new.main
Y2Network::Clients::Auto.new.run
7 changes: 4 additions & 3 deletions src/lib/network/clients/save_network.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def adjust_for_network_disks(file)
NETWORK_MANAGER = "/etc/NetworkManager".freeze

def CopyConfiguredNetworkFiles
return if Mode.autoinst && !NetworkAutoYast.instance.keep_net_config?
return if Mode.autoinst && !Lan.autoinst.copy_network?

log.info(
"Copy network configuration files from 1st stage into installed system"
Expand All @@ -98,6 +98,7 @@ def CopyConfiguredNetworkFiles
{ dir: SYSCONFIG, file: "routes" },
{ dir: ::File.join(ETC, "wicked"), file: "common.xml" },
{ dir: ETC, file: DNSClass::HOSTNAME_FILE },
{ dir: ETC, file: "hosts" },
# Copy sysctl file as network writes there ip forwarding (bsc#1159295)
{ dir: ::File.join(ETC, "sysctl.d"), file: "70-yast.conf" }
]
Expand Down Expand Up @@ -283,11 +284,11 @@ def configure_hosts
# It creates a proposal in case of common installation. In case of AY
# installation it does full import of <networking> section
def configure_lan
NetworkAutoYast.instance.configure_lan if Mode.autoinst
copy_udev_rules if Mode.autoinst && NetworkAutoYast.instance.configure_lan

# FIXME: Really make sense to configure it in autoinst mode? At least the
# proposal should be done and checked after lan configuration and in case
# that a bridge configuratio is present in the profile it should be
# that a bridge configuration is present in the profile it should be
# skipped or even only done in case of missing `networking -> interfaces`
# section
NetworkAutoconfiguration.instance.configure_virtuals
Expand Down
36 changes: 19 additions & 17 deletions src/lib/network/network_autoyast.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ def initialize
# import has to be done here, there are some collisions otherwise
Yast.import "Arch"
Yast.import "Lan"
Yast.import "LanItems"
Yast.import "Linuxrc"
Yast.import "Host"
Yast.import "AutoInstall"
Yast.import "Stage"
end

# Merges existing config from system into given configuration map
Expand Down Expand Up @@ -101,22 +101,21 @@ def set_network_service
NetworkService.EnableDisableNow
end

# Initializates NICs setup according AY profile
# Writes the autoyast network configuration according to the already
# imported configuration
#
# If the installer is running in 1st stage mode only, then the configuration
# is also written
# If the network was already written before the proposal it returns without
# touching it
#
# @param [Boolean] write forces instant writing of the configuration
# @return [Boolean] true when configuration was present and loaded from the profile
def configure_lan(write: false)
# @return [Boolean] true when written
def configure_lan
log.info("NetworkAutoYast: Lan configuration")
return false if Lan.autoinst.before_proposal

ay_configuration = Lan.FromAY(ay_networking_section)
if keep_net_config?
ay_configuration = NetworkAutoYast.instance.merge_configs(ay_configuration)
end

configure_submodule(Lan, ay_configuration, write: write)
# force a write only as it is run at the end of the installation and it
# is already chrooted in the target system where restarting services or
# refreshing udev rules does not make sense at all
Lan.Write(apply_config: false)
end

# Takes care of activate s390 devices from the profile declaration
Expand Down Expand Up @@ -154,6 +153,12 @@ def activate_s390_devices(section = nil)
def configure_hosts(write: false)
log.info("NetworkAutoYast: Hosts configuration")

unless ay_current_profile.key? "host"
Host.Write(gui: false)

return true
end

hosts_config = (ay_host_section["hosts"] || {}).map do |host|
# we need to guarantee order of the items here
[host["host_address"] || "", host["names"] || []]
Expand All @@ -165,7 +170,7 @@ def configure_hosts(write: false)

# Checks if the profile asks for keeping installation network configuration
def keep_net_config?
ret = ay_networking_section.fetch("keep_install_network", true)
ret = Lan.autoinst.keep_install_network

log.info("NetworkAutoYast: keep installation network: #{ret}")

Expand Down Expand Up @@ -310,10 +315,7 @@ def configure_submodule(yast_module, ay_config, write: false)
# Return true in order to not call the NetworkAutoconfiguration.configure_hosts
return true unless AutoInstall.valid_imported_values

mode_section = ay_general_section.fetch("mode", {})
write ||= !mode_section.fetch("second_stage", true)
log.info("Write configuration instantly: #{write}")

yast_module.Write(gui: false) if write

true
Expand Down
Loading