Skip to content

Commit

Permalink
Fixed registration order in AutoYaST
Browse files Browse the repository at this point in the history
  • Loading branch information
lslezak committed Nov 22, 2017
1 parent 929d0a3 commit 581bbfe
Show file tree
Hide file tree
Showing 4 changed files with 225 additions and 18 deletions.
26 changes: 8 additions & 18 deletions src/clients/scc_auto.rb
Expand Up @@ -30,6 +30,7 @@

require "registration/storage"
require "registration/sw_mgmt"
require "registration/autoyast_addons"
require "registration/registration"
require "registration/registration_ui"
require "registration/helpers"
Expand Down Expand Up @@ -308,29 +309,18 @@ def register_base_product

# register the addons specified in the profile
def register_addons
# register addons
@config.addons.each do |addon|
product_service = register_addon(addon)
# set the option for installing the updates for addons
options = Registration::Storage::InstallationOptions.instance
options.install_updates = @config.install_updates

::Registration::Storage::Cache.instance.addon_services << product_service
ay_addons_handler = Registration::AutoyastAddons.new(@config.addons, registration)
ay_addons_handler.select
ay_addons_handler.register

registration_ui.disable_update_repos(product_service) if !@config.install_updates
end

# install the new products
# select the new products to install
::Registration::SwMgmt.select_addon_products
end

def register_addon(addon)
Popup.Feedback(
_(CONTACTING_MESSAGE),
# %s is name of given product
_("Registering %s ...") % addon["name"]
) do
registration.register_product(addon)
end
end

# was the system already registered?
# @return [Boolean] true if the system was alreay registered
def old_system_registered?
Expand Down
2 changes: 2 additions & 0 deletions src/lib/registration/addon.rb
Expand Up @@ -44,6 +44,8 @@ def find_all(registration)
def reset!
@cached_addons = nil
@registered = nil
@selected = nil
@auto_selected = nil
end

# list of registered add-ons
Expand Down
116 changes: 116 additions & 0 deletions src/lib/registration/autoyast_addons.rb
@@ -0,0 +1,116 @@
# ------------------------------------------------------------------------------
# Copyright (c) 2017 SUSE LLC
#
# 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.
# ------------------------------------------------------------------------------
#

require "yast"

module Registration
# This class handles the AutoYaST addons
class AutoyastAddons
include Yast::I18n

attr_accessor :requested_addons, :selected_addons

# Constructor
# @param requested_addons [Array<Hash<String,String>>] the addons configuration
# from the AutoYaST profile
# @param registration [Registration::Registration] the Registration object to use
# for registering the addons
def initialize(requested_addons, registration)
self.requested_addons = requested_addons
self.registration = registration
end

# read the available addons from the server, sort the addons from the profile
# according to the dependencies
def select
# ask the server for all available addons (with UI feedback)
all_addons = registration_ui.get_available_addons

# remove the addons marked as not available
rejected = all_addons.reject! { |a| a.available? == false }
log.info("Not available addons: #{rejected.map(&:label).inspect}") if rejected

# select the requested addons from the available addons
self.selected_addons = select_addons(all_addons)
end

# register the selected addons, the #select method must be called before
def register
regcodes = collect_reg_codes
registration_ui.register_addons(selected_addons, regcodes)
end

private

attr_writer :selected_addons
attr_accessor :registration

# select the requested addons
# @param all_addons [Array<Registration::Addon>] all addons available on the server
def select_addons(all_addons)
# select the requested addons from the AY profile
requested_addons.each do |addon|
server_addon = all_addons.find do |a|
a.identifier == addon["name"] && a.version == addon["version"] &&
a.arch == addon["arch"]
end

if server_addon
# mark it as selected
server_addon.selected
else
log.error("Unavailable addon: #{addon.inspect}")
Yast::Report.Error(
# TRANSLATORS: %s is an addon name (including version and arch)
# from the AutoYast XML installation profile
_("Addon '%s'\nis not available for registration.") % \
"#{addon["name"]}-#{addon["version"]}-#{addon["arch"]}"
)
end
end

ordered_addons
end

# Order the addons according to thier dependencies, the result is sorted
# in the registration order. The result also includes the dependant addons
# (even not specified in the profile).
# @return [Array<Registration::Addon>]
def ordered_addons
# include also the automatically selected dependent modules/extensions
ret = Addon.registration_order(Addon.selected + Addon.auto_selected)

log.info("Addons to register: #{ret.map(&:label).inspect}")

ret
end

# collect the registration codes specified in the profile
# @return [Hash<String,String>] mapping "product identifier" => "reg code"
def collect_reg_codes
ret = {}

requested_addons.each do |a|
ret[a["name"]] = a["reg_code"] if a["reg_code"]
end

log.info("Found reg codes for addons: #{ret.keys.inspect}")

ret
end

def registration_ui
@registration_ui ||= RegistrationUI.new(registration)
end
end
end
99 changes: 99 additions & 0 deletions test/autoyast_addons_spec.rb
@@ -0,0 +1,99 @@
#! /usr/bin/env rspec

require_relative "spec_helper"
require "yaml"

describe Registration::AutoyastAddons do
let(:registration) { double("registration") }
let(:unsorted_addons) do
[
# deliberately in a wrong registration order, the "sle-module-basesystem"
# module needs to be registered first
{ "name" => "sle-module-desktop-applications", "version" => "15", "arch" => "x86_64" },
{ "name" => "sle-module-basesystem", "version" => "15", "arch" => "x86_64" }
]
end

# it depends on the "sle-module-basesystem" which is not listed here
let(:incomplete_addons) do
["name" => "sle-module-desktop-applications", "version" => "15",
"arch" => "x86_64"]
end

# the basesystem module does not need a reg. key in reality
# but let's use it in this test for the simplicity
let(:addons_with_reg_key) do
["name" => "sle-module-basesystem", "version" => "15", "arch" => "x86_64",
"reg_code" => "abcd42"]
end

# some dummy non-existing addon to test error handling
let(:missing_addons) do
["name" => "non-existing-module", "version" => "42", "arch" => "x86_64"]
end

# the addons to register in the expcted correct order
let(:expected_registration_order) { ["sle-module-basesystem", "sle-module-desktop-applications"] }

before do
addons = load_yaml_fixture("sle15_addons.yaml")
allow(Registration::Addon).to receive(:find_all).and_return(addons)
allow(registration).to receive(:get_addon_list).and_return(addons)
end

after do
Registration::Addon.reset!
end

describe "#select" do
it "sorts the addons according to their dependencies" do
ayaddons = Registration::AutoyastAddons.new(unsorted_addons, registration)
ayaddons.select

expect(ayaddons.selected_addons.map(&:identifier)).to eq(expected_registration_order)
end

it "automatically selects the dependent addons" do
ayaddons = Registration::AutoyastAddons.new(incomplete_addons, registration)
ayaddons.select

expect(ayaddons.selected_addons.map(&:identifier)).to eq(expected_registration_order)
end

it "reports error for not available addons" do
expect(Yast::Report).to receive(:Error).with(/is not available for registration/)

ayaddons = Registration::AutoyastAddons.new(missing_addons, registration)
ayaddons.select
end
end

describe "#register" do
it "registers the selected addons" do
expect(registration).to receive(:register_product).with(
"name" => "sle-module-basesystem", "reg_code" => nil, "arch" => "x86_64",
"version" => "15"
).ordered
expect(registration).to receive(:register_product).with(
"name" => "sle-module-desktop-applications", "reg_code" => nil,
"arch" => "x86_64", "version" => "15"
).ordered

ayaddons = Registration::AutoyastAddons.new(unsorted_addons, registration)
ayaddons.select
ayaddons.register
end

it "registers the selected addon using the provided reg. key" do
expect(registration).to receive(:register_product).with(
"name" => "sle-module-basesystem", "reg_code" => "abcd42", "arch" => "x86_64",
"version" => "15"
)

ayaddons = Registration::AutoyastAddons.new(addons_with_reg_key, registration)
ayaddons.select
ayaddons.register
end
end

end

0 comments on commit 581bbfe

Please sign in to comment.