Script 'mail_helper' called by ro
Hello packager,
This is just FYI. Your package was checked in in distribution "sle12"
by autobuild-member: ro.
Here comes the log...
---------------------------%<------------------------------
Hi,
here is the log from ci_new_pac /mounts/work_src_done/SLE12/yast2-registration -> sle12
Changes:
--------
--- /work/SRC/SUSE:SLE-12:GA/yast2-registration/yast2-registration.changes 2014-03-10 16:14:03.000000000 +0100
+++ /mounts/work_src_done/SLE12/yast2-registration/yast2-registration.changes 2014-03-18 10:47:09.000000000 +0100
@@ -1,0 +2,7 @@
+Tue Mar 18 09:31:39 UTC 2014 - lslezak@suse.cz
+
+- Display and allow registering online add-ons from SCC during
+ installation (FATE#312925, FATE#315685)
+- 3.1.19
+
+-------------------------------------------------------------------
calling whatdependson for sle12-i586
Packages directly triggered for rebuild:
- yast2-registration
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/SUSE:SLE-12:GA/yast2-registration (Old)
and /mounts/work_src_done/SLE12/yast2-registration (BS:build ID:34529 MAIL:yast-commit@opensuse.org) (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-registration", Maintainer is "yast-commit@opensuse.org"
Old:
----
yast2-registration-3.1.18.tar.bz2
New:
----
yast2-registration-3.1.19.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ yast2-registration.spec ++++++
--- /var/tmp/diff_new_pack.hxjloI/_old 2014-03-18 13:07:43.000000000 +0100
+++ /var/tmp/diff_new_pack.hxjloI/_new 2014-03-18 13:07:43.000000000 +0100
@@ -17,7 +17,7 @@
Name: yast2-registration
-Version: 3.1.18
+Version: 3.1.19
Release: 0
BuildRoot: %{_tmppath}/%{name}-%{version}-build
@@ -31,7 +31,7 @@
# N_() method
Requires: yast2-ruby-bindings >= 3.1.12
# SCC API library
-Requires: rubygem-scc_api >= 0.2.4
+Requires: rubygem-scc_api >= 0.2.7
Requires: yast2-slp >= 3.1.2
BuildRequires: yast2 >= 2.23.13
++++++ yast2-registration-3.1.18.tar.bz2 -> yast2-registration-3.1.19.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-registration-3.1.18/package/yast2-registration.changes new/yast2-registration-3.1.19/package/yast2-registration.changes
--- old/yast2-registration-3.1.18/package/yast2-registration.changes 2014-03-10 14:49:36.000000000 +0100
+++ new/yast2-registration-3.1.19/package/yast2-registration.changes 2014-03-18 10:44:23.000000000 +0100
@@ -1,4 +1,11 @@
-------------------------------------------------------------------
+Tue Mar 18 09:31:39 UTC 2014 - lslezak@suse.cz
+
+- Display and allow registering online add-ons from SCC during
+ installation (FATE#312925, FATE#315685)
+- 3.1.19
+
+-------------------------------------------------------------------
Thu Mar 6 20:31:05 UTC 2014 - lslezak@suse.cz
- display a popup for selecting/deselecting registered repositories
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-registration-3.1.18/package/yast2-registration.spec new/yast2-registration-3.1.19/package/yast2-registration.spec
--- old/yast2-registration-3.1.18/package/yast2-registration.spec 2014-03-10 14:49:36.000000000 +0100
+++ new/yast2-registration-3.1.19/package/yast2-registration.spec 2014-03-18 10:44:23.000000000 +0100
@@ -17,7 +17,7 @@
Name: yast2-registration
-Version: 3.1.18
+Version: 3.1.19
Release: 0
BuildRoot: %{_tmppath}/%{name}-%{version}-build
@@ -31,7 +31,7 @@
# N_() method
Requires: yast2-ruby-bindings >= 3.1.12
# SCC API library
-Requires: rubygem-scc_api >= 0.2.4
+Requires: rubygem-scc_api >= 0.2.7
Requires: yast2-slp >= 3.1.2
BuildRequires: yast2 >= 2.23.13
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-registration-3.1.18/src/Makefile.am new/yast2-registration-3.1.19/src/Makefile.am
--- old/yast2-registration-3.1.18/src/Makefile.am 2014-03-10 14:49:36.000000000 +0100
+++ new/yast2-registration-3.1.19/src/Makefile.am 2014-03-18 10:44:23.000000000 +0100
@@ -11,8 +11,10 @@
ylibdir = @ylibdir@/registration
ylib_DATA = \
+ lib/registration/addon.rb \
lib/registration/exceptions.rb \
lib/registration/sw_mgmt.rb \
+ lib/registration/storage.rb \
lib/registration/repo_state.rb \
lib/registration/helpers.rb
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-registration-3.1.18/src/clients/inst_scc.rb new/yast2-registration-3.1.19/src/clients/inst_scc.rb
--- old/yast2-registration-3.1.18/src/clients/inst_scc.rb 2014-03-10 14:49:36.000000000 +0100
+++ new/yast2-registration-3.1.19/src/clients/inst_scc.rb 2014-03-18 10:44:23.000000000 +0100
@@ -25,15 +25,22 @@
# use external rubygem for SCC communication
require "scc_api"
+require "cgi"
+
require "registration/exceptions"
require "registration/helpers"
require "registration/sw_mgmt"
require "registration/repo_state"
+require "registration/storage"
module Yast
class InstSccClient < Client
include Yast::Logger
+ # the maximum number of reg. codes displayed vertically,
+ # this is the limit for 80x25 textmode UI
+ MAX_REGCODES_PER_COLUMN = 9
+
def main
Yast.import "UI"
@@ -45,10 +52,46 @@
Yast.import "Report"
Yast.import "Mode"
Yast.import "Label"
+ Yast.import "Sequencer"
+ Yast.import "Installation"
# redirect the scc_api log to y2log
SccApi::GlobalLogger.instance.log = Y2Logger.instance
+ @selected_addons = []
+
+ initialize_regkeys
+
+ start_workflow
+ end
+
+ private
+
+ # initialize known reg. keys
+ def initialize_regkeys
+ @known_reg_keys = ::Registration::Storage::RegKeys.instance.reg_keys
+ if @known_reg_keys
+ log.info "Known reg keys: #{@known_reg_keys.size} keys"
+ return
+ end
+
+ if !Mode.normal
+ # read registration keys from USB media
+ log.info "Reading keys from USB media..."
+ # TODO FIXME: placeholder for FATE#316796 (https://fate.suse.com/316796)
+ # read the keys here, return Hash with mapping product_name => reg_key
+ @known_reg_keys = {}
+ log.info "Found #{@known_reg_keys.size} keys"
+ else
+ log.info "Initializing empty known reg keys"
+ @known_reg_keys = {}
+ end
+
+ # cache the values
+ ::Registration::Storage::RegKeys.instance.reg_keys = @known_reg_keys
+ end
+
+ def register_base_system
show_scc_credentials_dialog
ret = nil
@@ -58,116 +101,128 @@
ret = UI.UserInput
if ret == :next
+
email = UI.QueryWidget(:email, :Value)
reg_code = UI.QueryWidget(:reg_code, :Value)
# reset the user input in case an exception is raised
ret = nil
- begin
+ catch_registration_errors do
register(email, reg_code)
return :next
- rescue SccApi::NoNetworkError
- # Error popup
- Report.Error(_("Network is not configured, the registration server cannot be reached."))
- rescue SccApi::NotAuthorized
- # Error popup
- Report.Error(_("The email address or the registration\ncode is not valid."))
- rescue Timeout::Error
- # Error popup
- Report.Error(_("Connection time out."))
- rescue SccApi::ErrorResponse => e
- # TODO FIXME: display error details from the response
- Report.Error(_("Registration server error.\n\nRetry registration later."))
- rescue SccApi::HttpError => e
- case e.response
- when Net::HTTPClientError
- Report.Error(_("Registration client error."))
- when Net::HTTPServerError
- Report.Error(_("Registration server error.\n\nRetry registration later."))
- else
- Report.Error(_("Registration failed."))
- end
- rescue ::Registration::ServiceError => e
- log.error("Service error: #{e.message % e.service}")
- Report.Error(_(e.message) % e.service)
- rescue ::Registration::PkgError => e
- log.error("Pkg error: #{e.message}")
- Report.Error(_(e.message))
- rescue Exception => e
- log.error("SCC registration failed: #{e}, #{e.backtrace}")
- Report.Error(_("Registration failed."))
end
+
end
- return :next if ret == :skip && confirm_skipping
+ return ret if ret == :skip && confirm_skipping
end
return ret
end
-
- private
+ def catch_registration_errors(&block)
+ begin
+ yield
+ rescue SccApi::NoNetworkError
+ # Error popup
+ Report.Error(_("Network is not configured, the registration server cannot be reached."))
+ rescue SccApi::NotAuthorized
+ # Error popup
+ Report.Error(_("The email address or the registration\ncode is not valid."))
+ rescue Timeout::Error
+ # Error popup
+ Report.Error(_("Connection time out."))
+ rescue SccApi::ErrorResponse => e
+ # TODO FIXME: display error details from the response
+ Report.Error(_("Registration server error.\n\nRetry registration later."))
+ rescue SccApi::HttpError => e
+ case e.response
+ when Net::HTTPClientError
+ Report.Error(_("Registration client error."))
+ when Net::HTTPServerError
+ Report.Error(_("Registration server error.\n\nRetry registration later."))
+ else
+ Report.Error(_("Registration failed."))
+ end
+ rescue ::Registration::ServiceError => e
+ log.error("Service error: #{e.message % e.service}")
+ Report.Error(_(e.message) % e.service)
+ rescue ::Registration::PkgError => e
+ log.error("Pkg error: #{e.message}")
+ Report.Error(_(e.message))
+ rescue Exception => e
+ log.error("SCC registration failed: #{e}, #{e.backtrace}")
+ Report.Error(_("Registration failed."))
+ end
+ end
def register(email, reg_code)
- scc = SccApi::Connection.new(email, reg_code)
+ @scc = SccApi::Connection.new(email, reg_code)
# set the current language to receive translated error messages
- scc.language = ::Registration::Helpers.language
+ @scc.language = ::Registration::Helpers.language
reg_url = ::Registration::Helpers.registration_url
if reg_url
log.info "Using custom registration URL: #{reg_url.inspect}"
- scc.url = reg_url
+ @scc.url = reg_url
end
# announce (register the system) first
- credentials = run_with_feedback(_("Registering the System..."), _("Contacting the SUSE Customer Center server")) do
- scc.announce
+ @credentials = run_with_feedback(_("Registering the System..."), _("Contacting the SUSE Customer Center server")) do
+ @scc.announce
end
# ensure the zypp config directories are writable in inst-sys
::Registration::SwMgmt.zypp_config_writable!
# write the global credentials
- credentials.write
+ @credentials.write
# then register the product(s)
- product_services = run_with_feedback(_("Registering the Product..."), _("Contacting the SUSE Customer Center server")) do
- # there will be just one base product, but theoretically there can be more...
- ::Registration::SwMgmt.products_to_register.map do |base_product|
- log.info("Registering base product: #{base_product.inspect}")
- scc.register(base_product)
- end
- end
+ products = ::Registration::SwMgmt.products_to_register
+ register_products(products)
- log.info "product_services: #{product_services.inspect}"
+ # remember the base products for later (to get the respective addons)
+ ::Registration::Storage::BaseProducts.instance.products = products
+ end
- if !product_services.empty?
- Progress.New(
- # TRANSLATORS: dialog caption
- _("Adding Registered Software Repositories"),
- " ",
- product_services.size,
- [ _("Add Services") ],
- [ _("Adding Services") ],
- # TRANSLATORS: dialog help
- _("<p>The repository manager is downloading registered repositories...</p>")
- )
+ def register_products(products)
+ product_services = run_with_feedback(n_("Registering Product...", "Registering Products...", products.size), _("Contacting the SUSE Customer Center server")) do
+ products.map do |product|
+ log.info("Registering product: #{product["name"]}")
- Progress.NextStage
+ begin
+ orig_reg_code = @scc.reg_code
+ # use product specific reg. key (e.g. for addons)
+ @scc.reg_code = product["reg_key"] if product["reg_key"]
+
+ ret = @scc.register(product)
+ ensure
+ # restore the original base product key
+ @scc.reg_code = orig_reg_code
+ end
- begin
- ::Registration::SwMgmt.add_services(product_services, credentials)
- ensure
- Progress.Finish
+ ret
end
+ end
+
+ log.info "registered product_services: #{product_services.inspect}"
+
+ if !product_services.empty?
+ add_product_services(product_services)
# select repositories to use in installation (e.g. enable/disable Updates)
select_repositories(product_services) if Mode.installation
end
end
+ def add_product_services(product_services)
+ ::Registration::SwMgmt.add_services(product_services, @credentials)
+ end
+
+ # content for the main registration dialog
def scc_credentials_dialog
VBox(
HBox(
@@ -188,11 +243,13 @@
)
end
+ # help text for the main registration dialog
def scc_help_text
# TODO: improve the help text
_("Enter SUSE Customer Center credentials here to register the system to get updates and add-on products.")
end
+ # display the main registration dialog
def show_scc_credentials_dialog
Wizard.SetContents(
_("SUSE Customer Center Registration"),
@@ -264,6 +321,329 @@
Popup.ClearFeedback
end
+ # create item list (available addons items)
+ def addon_selection_items(addons)
+ addons.map{|a| Item(Id(a.product_ident), a.short_name, @selected_addons.include?(a))}
+ end
+
+ # create content fot the addon selection dialog
+ def addon_selection_dialog_content(addons)
+ media_checkbox = Empty()
+
+ # the media check box is displayed only at installation
+ # to modify the installation workflow (display extra add-on dialog)
+ if Mode.installation || true
+ media_checkbox = VBox(
+ VSpacing(0.4),
+ HBox(
+ HSpacing(1),
+ Left(CheckBox(Id(:media), _("In&clude Add-on Products from Separate Media"),
+ Installation.add_on_selected)),
+ )
+ )
+ end
+
+ VBox(
+ VWeight(75, MultiSelectionBox(Id(:addons), Opt(:notify), "",
+ addon_selection_items(addons))),
+ MinHeight(8,
+ VWeight(25, RichText(Id(:details), Opt(:disabled), "<small>" +
+ _("Select an addon to show details here") + "<small>")),
+ ),
+ media_checkbox,
+ VSpacing(0.4)
+ )
+ end
+
+ # update addon details after changing the current addon in the UI
+ def show_addon_details(addon)
+ details = "<p><big><b>#{CGI.escape_html(addon.long_name)}</b></big></p>" +
+ "<p>#{CGI.escape_html(addon.description)}</p>"
+
+ # TODO FIXME: SCC does not support dependencies yet
+ #
+ # if !addon.depends_on.empty?
+ # # rich text content: list of required (dependent) addons,
+ # # %s is a list of product names
+ # details << (_("<p><b>Required Add-ons:</b> %s</p>") %
+ # CGI.escape_html(addon.depends_on.map(&:label).join(", ")))
+ # end
+
+ if !addon.free
+ # rich text content: the selected addon requires a registration key
+ details << _("<p><b>A Registration Key is Required</b></p>")
+ end
+
+ UI.ChangeWidget(Id(:details), :Value, details)
+ UI.ChangeWidget(Id(:details), :Enabled, true)
+ end
+
+ # check addon dependencies and automatically select required addons
+ def check_addon_dependencies(addons)
+ selected = UI.QueryWidget(Id(:addons), :SelectedItems)
+ selected_addons = addons.select{|a| selected.include?(a.name)}
+
+ selected_addons.each do |a|
+ missing = a.required_addons - selected_addons
+
+ if !missing.empty?
+ # popup message, %s are product names
+ Popup.Message((_("Automatically selecting '%s'\ndependencies:\n\n%s") %
+ [a.label, missing.map(&:label).join("\n")]))
+ # select the missing entries
+ UI.ChangeWidget(Id(:addons), :SelectedItems, selected + missing.map(&:name))
+ end
+ end
+ end
+
+ # check for the maximum amount of reg. codes supported by Yast
+ def supported_addon_count(addons, selected)
+ # maximum number or reg codes which can be displayed in two column layout
+ max_supported = 2*MAX_REGCODES_PER_COLUMN
+
+ if addons.select{|a| selected.include?(a.product_ident) && !a.free}.size > max_supported
+ Report.Error(_("YaST allows to select at most %s addons.") % max_supported)
+ return false
+ end
+
+ return true
+ end
+
+ # read the addon media checkbox and adapt the installation workflow accordingly
+ def set_media_addons
+ if Mode.installation
+ # the widget exists only at installation
+ Installation.add_on_selected = UI.QueryWidget(Id(:media), :Value)
+ log.info "Add-on media selected: #{Installation.add_on_selected}"
+
+ # lazy include, the file is part of yast2-installation
+ # avoid yast2-installation runtime dependency by including it only here,
+ # not at the global level
+ Yast.include self, "installation/misc.rb"
+ AdjustStepsAccordingToInstallationSettings()
+ end
+ end
+
+ # handle user input in the addon selection dialog
+ def handle_addon_selection_dialog(addons)
+ ret = nil
+ continue_buttons = [:next, :back, :close, :abort, :skip]
+
+ while !continue_buttons.include?(ret) do
+ ret = UI.UserInput
+
+ # current item has been changed, refresh details, check dependencies
+ case ret
+ when :addons
+ current_addon = UI.QueryWidget(Id(:addons), :CurrentItem)
+
+ if current_addon
+ show_addon_details(addons.find{|addon| addon.product_ident == current_addon})
+ # TODO FIXME: SCC does not support dependencies yet
+ # check_addon_dependencies(addons)
+ end
+ when :next
+ selected = UI.QueryWidget(Id(:addons), :SelectedItems)
+
+ if !supported_addon_count(addons, selected)
+ ret = nil
+ next
+ end
+
+ @selected_addons = addons.select{|a| selected.include?(a.product_ident)}
+ log.info "Selected addons: #{@selected_addons.map(&:short_name)}"
+
+ set_media_addons
+
+ ret = :skip if @selected_addons.empty?
+ end
+ end
+
+ ret
+ end
+
+ # run the addon selection dialog
+ def select_addons
+ addons = get_available_addons
+ Wizard.SetContents(
+ # dialog title
+ _("Available Products and Extensions"),
+ addon_selection_dialog_content(addons),
+ # FIXME: help text
+ "",
+ GetInstArgs.enable_back || Mode.normal,
+ GetInstArgs.enable_next || Mode.normal
+ )
+
+ handle_addon_selection_dialog(addons)
+ end
+
+
+ # create widgets for entering the addon reg keys
+ def addon_regkey_items(addons)
+ textmode = UI.TextMode
+ box = VBox()
+
+ addons.each do |addon|
+ label = addon.short_name
+ label << " (#{addon.long_name})" if !addon.long_name.empty?
+
+ box[box.size] = MinWidth(32, InputField(Id(addon.product_ident), label,
+ @known_reg_keys.fetch(addon.product_ident, "")))
+ # add extra spacing when there are just few addons, in GUI always
+ box[box.size] = VSpacing(1) if (addons.size < 5) || !textmode
+ end
+
+ box
+ end
+
+ # create content for the addon reg keys dialog
+ def addon_regkeys_dialog_content(addons)
+ # display the second column if needed
+ if addons.size > MAX_REGCODES_PER_COLUMN
+ # display only the addons which fit two column layout
+ display_addons = addons[0..2*MAX_REGCODES_PER_COLUMN - 1]
+
+ # round the half up (more items in the first column for odd number of items)
+ half = (display_addons.size + 1) / 2
+
+ box1 = addon_regkey_items(display_addons[0..half - 1])
+ box2 = HBox(
+ HSpacing(2),
+ addon_regkey_items(display_addons[half..-1])
+ )
+ else
+ box1 = addon_regkey_items(addons)
+ end
+
+ HBox(
+ HSpacing(Opt(:hstretch), 3),
+ box1,
+ box2 ? box2 : Empty(),
+ HSpacing(Opt(:hstretch), 3)
+ )
+ end
+
+ # load available addons from SCC server
+ # the result is cached to avoid reloading when going back and forth in the
+ # installation workflow
+ def get_available_addons
+ # cache the available addons
+ return @available_addons if @available_addons
+
+ @available_addons = run_with_feedback(_("Loading Available Add-on Products and Extensions..."),
+ _("Contacting the SUSE Customer Center server")) do
+
+ # extensions for base product
+ ::Registration::Storage::BaseProducts.instance.products.reduce([]) do |acc, product|
+ acc.concat(@scc.extensions_for(product["name"]).extensions)
+ end
+ end
+
+ log.info "Received product extensions: #{@available_addons}"
+ @available_addons
+ end
+
+ # handle user input in the addon reg keys dialog
+ def handle_register_addons_dialog(addons_with_keys)
+ continue_buttons = [:next, :back, :close, :abort]
+
+ ret = nil
+ while !continue_buttons.include?(ret) do
+ ret = UI.UserInput
+
+ if ret == :next
+ collect_addon_regkeys(addons_with_keys)
+
+ # register the add-ons
+ ret = nil unless register_selected_addons
+ end
+ end
+
+ return ret
+ end
+
+ # collect the entered reg keys from UI
+ # @return [Hash