src/lib/y2network/wicked/hostname_reader.rb
# Copyright (c) [2019] SUSE LLC
#
# 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 SUSE LLC.
#
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com.
require "yast"
require "cfa/interface_file"
require "y2network/hostname"
require "network/wicked"
Yast.import "Hostname"
Yast.import "IP"
Yast.import "Stage"
Yast.import "NetHwDetection"
module Y2Network
module Wicked
# This class is responsible for reading the hostname
#
# Depending on different circunstamces, the hostname can be read from different places (from a
# simple call to `/usr/bin/hostname` to the `/etc/install.inf` during installation).
#
# @example Read hostname
# Y2Network::HostnameReader.new.hostname #=> "foo"
class HostnameReader
include Yast::Logger
include Yast::Wicked
# Return configuration from sysconfig files
#
# @return [Y2Network::Hostname] Hostname configuration
def config
Y2Network::Hostname.new(
installer: hostname_from_install_inf,
static: static_hostname,
transient: hostname_from_system,
dhcp_hostname: dhcp_hostname
)
end
# Returns whether the hostname should be taken from DHCP
#
# @return [String,:any,:none] Interface to set the hostname based on DHCP settings;
# :any for any interface; :none for ignoring the hostname assigned via DHCP
def dhcp_hostname
value = Yast::SCR.Read(Yast::Path.new(".sysconfig.network.dhcp.DHCLIENT_SET_HOSTNAME"))
return :any if value == "yes"
files = CFA::InterfaceFile.all
file = files.find do |f|
f.load
f.dhclient_set_hostname == "yes"
end
file ? file.interface : :none
end
# Reads the hostname from the /etc/install.inf file
#
# @return [String,nil] Hostname
def hostname_from_install_inf
install_inf_hostname = Yast::SCR.Read(Yast::Path.new(".etc.install_inf.Hostname")) || ""
log.info("Got #{install_inf_hostname} from install.inf")
return nil if install_inf_hostname.empty?
# if the name is actually IP, try to resolve it (bnc#556613, bnc#435649)
if Yast::IP.Check(install_inf_hostname)
fqdn = Yast::NetHwDetection.ResolveIP(install_inf_hostname)
log.info("Got #{fqdn} after resolving IP from install.inf")
else
fqdn = install_inf_hostname
end
host, _domain = *Yast::Hostname.SplitFQ(fqdn)
return nil if host.nil? || host.empty?
host
end
# Reads the (transient) hostname known to the resolver
#
# @return [String, nil] Hostname or nil if transient hostname is not known
def hostname_from_resolver
Yast::Execute.on_target!("/usr/bin/hostname", "--fqdn", stdout: :capture).strip
rescue Cheetah::ExecutionFailed
nil
end
# Reads the transient hostname or system (local) hostname
#
# @return [String, nil] Hostname
def hostname_from_system
Yast::Execute.on_target!("/usr/bin/hostname", stdout: :capture).strip
rescue Cheetah::ExecutionFailed
static_hostname
end
# Reads the static hostname from /etc/hostname
#
# @return [String, nil]
def static_hostname
name = Yast::SCR.Read(Yast::Path.new(".target.string"), "/etc/hostname").to_s.strip
name.empty? ? nil : name
end
# Queries for hostname obtained as part of dhcp configuration
#
# @return [String, nil] Hostname
def hostname_from_dhcp
# We currently cannot use connections for getting only dhcp aware configurations here
# bcs this can be called during Y2Network::Config initialization and this is
# acceptable replacement for this case.
ifaces = CFA::InterfaceFile.all.map(&:interface)
dhcp_hostname = ifaces.map { |i| parse_hostname(i) }.compact.first
log.info("Hostname obtained from DHCP: #{dhcp_hostname}")
dhcp_hostname
end
end
end
end