src/lib/registration/helpers.rb
# Copyright (c) [2014-2021] 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.
# encoding: utf-8
require "yast"
require "erb"
require "registration/addon"
require "registration/registration"
require "registration/storage"
require "registration/url_helpers"
require "registration/ssl_certificate"
require "suse/connect"
module Registration
class Helpers
include Yast::Logger
extend Yast::I18n
textdomain "registration"
Yast.import "Installation"
Yast.import "Linuxrc"
Yast.import "Mode"
Yast.import "Popup"
Yast.import "Stage"
Yast.import "Report"
Yast.import "SlpService"
# reg. code replacement
FILTERED = "[FILTERED]".freeze
# Get the current language (without encoding suffix)
# @return [String,nil] the current language or nil if set to "POSIX" or "C"
def self.current_language
lang = Yast::WFM.GetLanguage
log.info "Current language: #{lang}"
if lang == "POSIX" || lang == "C"
log.info "Ignoring #{lang.inspect} language"
return nil
end
# remove the encoding (e.g. ".UTF-8")
lang.sub(/\..*$/, "")
end
# Get the language for using in HTTP requests (in "Accept-Language" header)
# @return [String,nil] the language or nil if set to "POSIX" or "C"
def self.http_language
lang = current_language
return nil unless lang
# replace lang/country separator "_" -> "-"
# see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
lang.tr!("_", "-")
log.info "Language for HTTP requests set to #{lang.inspect}"
lang
end
# Create radio button label for a SLP service
# @param service [Yast::SlpServiceClass::Service] SLP service
# @return [String] label
def self.service_description(service)
url = UrlHelpers.service_url(service.slp_url)
descr = service.attributes.to_h[:description]
# display URL and the description if it is present
(descr && !descr.empty?) ? "#{descr} (#{url})" : url
end
# run the network configuration module
def self.run_network_configuration
log.info "Running network configuration..."
# ensure that no registration feedback is shown
# when running network configuration (bsc#1165705)
Yast::Popup.SuppressFeedback do
Yast::WFM.call("inst_lan", [{ "skip_detection" => true, "hide_abort_button" => true }])
end
end
# check if the network configuration module is present
# @return [Boolean] true if the network configuration client is present
def self.network_configurable
Yast::WFM.ClientExists("inst_lan")
end
# return base version
# "12-1.47" => "12"
# "12-1" => "12"
# "12.1-1.47" => "12.1"
# "12.1-1" => "12.1"
def self.base_version(version)
version.sub(/-.*\z/, "")
end
# check if insecure registration is requested
# (the "reg_ssl_verify=0" boot commandline option is used)
def self.insecure_registration
# check the boot parameter only at installation/update
if Yast::Mode.installation || Yast::Mode.update
reg_ssl_verify = Yast::Linuxrc.InstallInf("reg_ssl_verify")
log.info "Boot reg_ssl_verify option: #{reg_ssl_verify.inspect}"
return reg_ssl_verify == "0"
else
config = SUSE::Connect::Config.new
return config.insecure
end
end
# copy the imported SSL certificate to the target system (if exists)
def self.copy_certificate_to_target
cert_file = SslCertificate.default_certificate_path
return unless File.exist?(cert_file) # no certificate imported?
# copy the imported certificate
log.info "Copying SSL certificate (#{cert_file}) to the target system..."
cert_target_file = File.join(Yast::Installation.destdir,
SUSE::Connect::YaST::SERVER_CERT_FILE)
::FileUtils.mkdir_p(File.dirname(cert_target_file))
::FileUtils.cp(cert_file, cert_target_file)
# update the certificate links
cmd = SUSE::Connect::YaST::UPDATE_CERTIFICATES
log.info "Updating certificate links (#{cmd})..."
Yast::SCR.Execute(Yast::Path.new(".target.bash"), cmd)
end
# write the current configuration to the configuration file
def self.write_config
config_params = {
url: UrlHelpers.registration_url,
insecure: insecure_registration
}
log.info "writing registration config: #{config_params}"
SUSE::Connect::YaST.write_config(config_params)
end
def self.reset_registration_status
file = SUSE::Connect::YaST::GLOBAL_CREDENTIALS_FILE
return unless File.exist?(file)
log.info "Resetting registration status, removing #{file}"
File.unlink(file)
end
# TODO: move it to yast2 to share it
def self.render_erb_template(file, binding)
# use erb template for rendering the richtext summary
erb_file = if Pathname.new(file).absolute?
file
else
File.expand_path(File.join("../../../data/registration", file), __FILE__)
end
log.info "Loading ERB template #{erb_file}"
erb = ERB.new(File.read(erb_file))
# render the ERB template in the context of the requested object
erb.result(binding)
end
def self.collect_autoyast_config(known_reg_codes)
options = Storage::InstallationOptions.instance
configuration = {
"do_registration" => true,
"email" => options.email,
"reg_code" => options.reg_code,
"install_updates" => options.install_updates
}
reg_server = UrlHelpers.registration_url
configuration["reg_server"] = reg_server if reg_server
if options.imported_cert_sha256_fingerprint
configuration["reg_server_cert_fingerprint_type"] = "SHA256"
configuration["reg_server_cert_fingerprint"] = options.imported_cert_sha256_fingerprint
end
configuration["addons"] = Addon.registered.map do |addon|
addon_hash = addon.to_h(release_type_string: true)
addon_hash["reg_code"] = known_reg_codes[addon.identifier] || ""
addon_hash
end
configuration
end
# Hide registration codes in Autoyast data
# The result should be just logged, the result might not be a full duplicate
# of the input is all cases and therefore should NOT be modified.
# @param settings input value
# @return either the original value or a value with replaced "reg_code" entries
# TODO: move AutoYast settings to a separate class and override #to_s
def self.hide_reg_codes(settings)
return settings unless settings.is_a?(Hash)
# create a duplicate
filtered = settings.dup
filtered["reg_code"] &&= FILTERED
return filtered unless filtered["addons"]
# duplicate the nested values
filtered["addons"] = filtered["addons"].map(&:dup)
filtered["addons"].each do |addon|
addon["reg_code"] &&= FILTERED
end
filtered
end
def self.report_no_base_product
# error message
msg = _("The base product was not found,\ncheck your system.") + "\n\n"
if Yast::Stage.initial
# TRANSLATORS: %s = bugzilla URL
msg += _("The installation medium or the installer itself is seriously broken.\n" \
"Report a bug at %s.") % "https://bugzilla.suse.com"
else
msg += _("Make sure a product is installed and /etc/products.d/baseproduct\n" \
"is a symlink pointing to the base product .prod file.")
end
Yast::Report.Error(msg)
end
end
end