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-04-09 17:13:31.000000000 +0200
+++ /mounts/work_src_done/SLE12/yast2-registration/yast2-registration.changes 2014-04-10 11:31:56.000000000 +0200
@@ -1,0 +2,14 @@
+Thu Apr 10 08:43:48 UTC 2014 - lslezak(a)suse.cz
+
+- ask simple Yes/No for installing online updates (instead of
+ complex repository selection)
+- 3.1.31
+
+-------------------------------------------------------------------
+Tue Apr 8 16:05:20 UTC 2014 - lslezak(a)suse.cz
+
+- redesiged addon selection dialog
+- small UI improvements
+- 3.1.30
+
+-------------------------------------------------------------------
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:35777 MAIL:yast-commit@opensuse.org) (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-registration", Maintainer is "yast-commit(a)opensuse.org"
Old:
----
yast2-registration-3.1.29.tar.bz2
New:
----
yast2-registration-3.1.31.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ yast2-registration.spec ++++++
--- /var/tmp/diff_new_pack.1NzvWH/_old 2014-04-10 17:28:28.000000000 +0200
+++ /var/tmp/diff_new_pack.1NzvWH/_new 2014-04-10 17:28:28.000000000 +0200
@@ -17,7 +17,7 @@
Name: yast2-registration
-Version: 3.1.29
+Version: 3.1.31
Release: 0
BuildRoot: %{_tmppath}/%{name}-%{version}-build
++++++ yast2-registration-3.1.29.tar.bz2 -> yast2-registration-3.1.31.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-registration-3.1.29/package/yast2-registration.changes new/yast2-registration-3.1.31/package/yast2-registration.changes
--- old/yast2-registration-3.1.29/package/yast2-registration.changes 2014-04-04 13:13:14.000000000 +0200
+++ new/yast2-registration-3.1.31/package/yast2-registration.changes 2014-04-10 11:28:39.000000000 +0200
@@ -1,4 +1,18 @@
-------------------------------------------------------------------
+Thu Apr 10 08:43:48 UTC 2014 - lslezak(a)suse.cz
+
+- ask simple Yes/No for installing online updates (instead of
+ complex repository selection)
+- 3.1.31
+
+-------------------------------------------------------------------
+Tue Apr 8 16:05:20 UTC 2014 - lslezak(a)suse.cz
+
+- redesiged addon selection dialog
+- small UI improvements
+- 3.1.30
+
+-------------------------------------------------------------------
Fri Apr 4 10:56:53 UTC 2014 - lslezak(a)suse.cz
- fixed undefined method (bnc#872012)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-registration-3.1.29/package/yast2-registration.spec new/yast2-registration-3.1.31/package/yast2-registration.spec
--- old/yast2-registration-3.1.29/package/yast2-registration.spec 2014-04-04 13:13:14.000000000 +0200
+++ new/yast2-registration-3.1.31/package/yast2-registration.spec 2014-04-10 11:28:39.000000000 +0200
@@ -17,7 +17,7 @@
Name: yast2-registration
-Version: 3.1.29
+Version: 3.1.31
Release: 0
BuildRoot: %{_tmppath}/%{name}-%{version}-build
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-registration-3.1.29/src/clients/inst_scc.rb new/yast2-registration-3.1.31/src/clients/inst_scc.rb
--- old/yast2-registration-3.1.29/src/clients/inst_scc.rb 2014-04-04 13:13:14.000000000 +0200
+++ new/yast2-registration-3.1.31/src/clients/inst_scc.rb 2014-04-10 11:28:39.000000000 +0200
@@ -42,6 +42,9 @@
# this is the limit for 80x25 textmode UI
MAX_REGCODES_PER_COLUMN = 9
+ # width of reg code input field widget
+ REG_CODE_WIDTH = 33
+
def main
Yast.import "UI"
@@ -57,7 +60,7 @@
Yast.import "Installation"
Yast.import "ProductControl"
- @selected_addons = []
+ @selected_addons = ::Registration::Storage::InstallationOptions.instance.selected_addons
initialize_regkeys
@@ -103,8 +106,17 @@
when :network
::Registration::Helpers::run_network_configuration
when :next
+ # do not re-register during installation
+ return :next if !Mode.normal && ::Registration::Registration.is_registered?
+
email = UI.QueryWidget(:email, :Value)
reg_code = UI.QueryWidget(:reg_code, :Value)
+
+ # remember the entered values in case user goes back
+ options = ::Registration::Storage::InstallationOptions.instance
+ options.email = email
+ options.reg_code = reg_code
+
# reset the user input in case an exception is raised
ret = nil
@@ -119,16 +131,16 @@
end
# then register the product(s)
- products = ::Registration::SwMgmt.base_products_to_register
+ base_product = ::Registration::SwMgmt.base_product_to_register
product_services = Popup.Feedback(
- n_("Registering Product...", "Registering Products...", products.size),
+ _("Registering Product..."),
_("Contacting the SUSE Customer Center server")) do
- @registration.register_products(products)
+ @registration.register_products([base_product])
end
# remember the base products for later (to get the respective addons)
- ::Registration::Storage::BaseProducts.instance.products = products
+ ::Registration::Storage::BaseProduct.instance.product = base_product
# select repositories to use in installation (e.g. enable/disable Updates)
select_repositories(product_services) if Mode.installation
@@ -145,26 +157,55 @@
# content for the main registration dialog
def scc_credentials_dialog
+ base_product = ::Registration::SwMgmt.find_base_product
+ base_product_name = base_product["display_name"] ||
+ base_product["short_name"] ||
+ base_product["name"] ||
+ _("Unknown product")
+
+ options = ::Registration::Storage::InstallationOptions.instance
+
+ # TODO FIXME: still not the final text
+ # label text describing the registration (1/2)
+ # use \n to split to more lines if needed (use max. 76 chars/line)
+ info = _("Please enter a registration or evaluation code for this product and your\n" +
+ "User Name/EMail from the SUSE Customer Center in the fields below.\n" +
+ "Access to security and general software updates is only possible on\n" +
+ "a registered system.")
+
+ if !Mode.normal
+ # add a paragraph separator
+ info << "\n\n"
+
+ # label text describing the registration (2/2),
+ # not displayed in installed system
+ # use \n to split to more lines if needed (use max. 76 chars/line)
+ info << _("If you skip the registration now be sure to do so in the installed system.")
+ end
+
VBox(
Mode.installation ?
Right(PushButton(Id(:network), _("Network Configuration..."))) :
Empty(),
VStretch(),
- HBox(
- Frame(_("SUSE Customer Center Credentials"),
- MarginBox(1, 0.5,
- HSquash(
- VBox(
- MinWidth(33, InputField(Id(:email), _("&Email"))),
- VSpacing(0.5),
- MinWidth(33, InputField(Id(:reg_code), _("Registration &Code")))
- )
- )
- )
+ HSquash(
+ VBox(
+ VSpacing(1),
+ Left(Heading(base_product_name)),
+ VSpacing(1),
+ Label(info)
+ )
+ ),
+ VSpacing(UI.TextMode ? 1 : 2),
+ HSquash(
+ VBox(
+ MinWidth(REG_CODE_WIDTH, InputField(Id(:email), _("&Email"), options.email)),
+ VSpacing(0.5),
+ MinWidth(REG_CODE_WIDTH, InputField(Id(:reg_code), _("Registration &Code"), options.reg_code))
)
),
- VSpacing(3),
- PushButton(Id(:skip), _("&Skip Registration")),
+ VSpacing(UI.TextMode ? 1 : 3),
+ Mode.normal ? Empty() : PushButton(Id(:skip), _("&Skip Registration")),
VStretch()
)
end
@@ -177,68 +218,65 @@
# display the main registration dialog
def show_scc_credentials_dialog
+
Wizard.SetContents(
- _("SUSE Customer Center Registration"),
+ # dialog title
+ _("Registration"),
scc_credentials_dialog,
scc_help_text,
GetInstArgs.enable_back,
GetInstArgs.enable_next || Mode.normal
)
- end
-
- def repo_items(repos)
- repos.map{|repo| Item(Id(repo["SrcId"]), repo["name"], repo["enabled"])}
- end
-
- def repo_selection_dialog(repos)
- label = _("You can manually change the repository states,\n" +
- "select repositories which will be used for installation.")
-
- VBox(
- Heading(_("Repository State")),
- VSpacing(0.5),
- Label(label),
- MultiSelectionBox(Id(:repositories), "", repo_items(repos)),
- VSpacing(0.5),
- HBox(
- PushButton(Id(:ok), Opt(:default), Label.OKButton),
- PushButton(Id(:cancel), Label.CancelButton)
- )
- )
- end
- def activate_repo_settings(repos)
- selected_items = UI.QueryWidget(Id(:repositories), :SelectedItems)
- log.info "Selected items: #{selected_items.inspect}"
-
- repos.each do |repo|
- repo_id = repo["SrcId"]
- enabled = selected_items.include?(repo["SrcId"])
-
- if repo["enabled"] != enabled
- log.info "Changing repository state: #{repo["name"]} enabled: #{enabled}"
- Pkg.SourceSetEnabled(repo_id, enabled)
- end
+ registered = ::Registration::Registration.is_registered?
+ # disable the input fields when already registered
+ if registered && !Mode.normal
+ UI.ChangeWidget(Id(:email), :Enabled, false)
+ UI.ChangeWidget(Id(:reg_code), :Enabled, false)
end
end
def select_repositories(product_services)
- repos = ::Registration::SwMgmt.service_repos(product_services)
+ options = ::Registration::Storage::InstallationOptions.instance
- UI.OpenDialog(repo_selection_dialog(repos))
- UI.SetFocus(:ok)
+ # added update repositories
+ updates = ::Registration::SwMgmt.service_repos(product_services, only_updates: true)
+ log.info "Found update repositories: #{updates.size}"
- begin
- ret = UI.UserInput
- activate_repo_settings(repos) if ret == :ok
- ensure
- UI.CloseDialog
+ # not set yet?
+ if options.install_updates.nil?
+ options.install_updates = Popup.YesNo(
+ _("Registration added some update repositories.\n\n" +
+ "Do you want to install the latest available\n" +
+ "on-line updates during installation?"))
end
+
+ ::Registration::SwMgmt.set_repos_state(updates, options.install_updates)
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))}
+ box = VBox()
+
+ # whether to add extra spacing in the UI
+ if UI.TextMode
+ add_extra_spacing = addons.size < 5
+ else
+ add_extra_spacing = true
+ end
+
+ addons.each do |addon|
+ label = addon.short_name
+ label << " (#{addon.long_name})" if !addon.long_name.empty?
+
+ box.params << Left(CheckBox(Id(addon.product_ident), Opt(:notify),
+ addon.short_name, @selected_addons.include?(addon)))
+
+ # add extra spacing when there are just few addons, in GUI always
+ box.params << VSpacing(0.7) if add_extra_spacing
+ end
+
+ box
end
# create content fot the addon selection dialog
@@ -258,38 +296,42 @@
)
end
+ # less lines in textmode to fit 80x25 size
+ lines = UI.TextMode ? 9 : 14
+
+ # use two column layout if needed
+ vbox1 = addon_selection_items(addons[0..(lines - 1)])
+ vbox2 = (addons.size > lines) ? HBox(
+ HSpacing(1),
+ VBox(
+ addon_selection_items(addons[lines..(2*lines - 1)]),
+ VStretch()
+ )
+ ) :
+ Empty()
+
VBox(
- VWeight(75, MultiSelectionBox(Id(:addons), Opt(:notify), "",
- addon_selection_items(addons))),
+ VStretch(),
+ Left(Heading(_("Available Extensions"))),
+ VWeight(75, MarginBox(2, 1, HBox(
+ vbox1,
+ vbox2
+ ))),
+ Left(Label(_("Details"))),
MinHeight(8,
VWeight(25, RichText(Id(:details), Opt(:disabled), "<small>" +
- _("Select an addon to show details here") + "<small>")),
+ _("Select an addon to show details here") + "</small>")),
),
media_checkbox,
- VSpacing(0.4)
+ VSpacing(0.4),
+ VStretch()
)
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)
+ # addon description is a rich text
+ UI.ChangeWidget(Id(:details), :Value, addon.description)
UI.ChangeWidget(Id(:details), :Enabled, true)
end
@@ -312,11 +354,12 @@
end
# check for the maximum amount of reg. codes supported by Yast
- def supported_addon_count(addons, selected)
+ def supported_addon_count(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
+ # check the addons requiring a reg. code
+ if selected.count{|a| !a.free} > max_supported
Report.Error(_("YaST allows to select at most %s addons.") % max_supported)
return false
end
@@ -347,30 +390,32 @@
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)
+ selected = addons.select{|a| UI.QueryWidget(Id(a.product_ident), :Value)}
- if !supported_addon_count(addons, selected)
+ if !supported_addon_count(selected)
ret = nil
next
end
- @selected_addons = addons.select{|a| selected.include?(a.product_ident)}
+ @selected_addons = selected
+ ::Registration::Storage::InstallationOptions.instance.selected_addons = @selected_addons
log.info "Selected addons: #{@selected_addons.map(&:short_name)}"
set_media_addons
ret = :skip if @selected_addons.empty?
+ else
+ # check whether it's an add-on ID (checkbox clicked)
+ addon = addons.find{|addon| addon.product_ident == ret}
+
+ # an addon has been changed, refresh details, check dependencies
+ if addon
+ show_addon_details(addon)
+ # TODO FIXME: SCC does not support dependencies yet
+ # check_addon_dependencies(addons)
+ end
end
end
@@ -382,7 +427,7 @@
addons = get_available_addons
Wizard.SetContents(
# dialog title
- _("Available Products and Extensions"),
+ _("Extension Selection"),
addon_selection_dialog_content(addons),
# help text for add-ons installation, %s is URL
_("<p>\nTo install an add-on product from separate media together with &product;, select\n" +
@@ -404,9 +449,9 @@
addons.each do |addon|
label = addon.short_name
- label << " (#{addon.long_name})" if !addon.long_name.empty?
+ label << " (#{addon.long_name})" unless addon.long_name.empty?
- box[box.size] = MinWidth(32, InputField(Id(addon.product_ident), label,
+ box[box.size] = MinWidth(REG_CODE_WIDTH, 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
@@ -447,6 +492,7 @@
# installation workflow
def get_available_addons
# cache the available addons
+ @available_addons = ::Registration::Storage::Cache.instance.available_addons
return @available_addons if @available_addons
@available_addons = Popup.Feedback(
@@ -457,6 +503,7 @@
end
log.info "Received product extensions: #{@available_addons}"
+ ::Registration::Storage::Cache.instance.available_addons = @available_addons
@available_addons
end
@@ -603,7 +650,7 @@
def display_registered_dialog
Wizard.SetContents(
# dialog title
- _("Registration Status"),
+ _("Registration"),
registered_dialog,
# FIXME: help text
"",
@@ -624,9 +671,11 @@
end
def registration_check
- return :register unless ::Registration::Registration.is_registered?
-
- display_registered_dialog
+ if Mode.normal && ::Registration::Registration.is_registered?
+ return display_registered_dialog
+ else
+ return :register
+ end
end
# UI workflow definition
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-registration-3.1.29/src/lib/registration/registration.rb new/yast2-registration-3.1.31/src/lib/registration/registration.rb
--- old/yast2-registration-3.1.29/src/lib/registration/registration.rb 2014-04-04 13:13:14.000000000 +0200
+++ new/yast2-registration-3.1.31/src/lib/registration/registration.rb 2014-04-10 11:28:39.000000000 +0200
@@ -93,9 +93,8 @@
def get_addon_list
# extensions for base product
- ::Registration::Storage::BaseProducts.instance.products.reduce([]) do |acc, product|
- acc.concat((a)scc.extensions_for(product["name"]).extensions)
- end
+ base_product = ::Registration::Storage::BaseProduct.instance.product
+ @scc.extensions_for(base_product["name"]).extensions
end
def self.is_registered?
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-registration-3.1.29/src/lib/registration/scc_helpers.rb new/yast2-registration-3.1.31/src/lib/registration/scc_helpers.rb
--- old/yast2-registration-3.1.29/src/lib/registration/scc_helpers.rb 2014-04-04 13:13:15.000000000 +0200
+++ new/yast2-registration-3.1.31/src/lib/registration/scc_helpers.rb 2014-04-10 11:28:39.000000000 +0200
@@ -48,7 +48,7 @@
if Yast::Mode.installation && Yast::Popup.YesNo(
_("Network is not configured, the registration server cannot be reached.\n" +
"Do you want to configure the network now?") )
- Registration::Helpers::run_network_configuration
+ ::Registration::Helpers::run_network_configuration
end
false
rescue SccApi::NotAuthorized
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-registration-3.1.29/src/lib/registration/storage.rb new/yast2-registration-3.1.31/src/lib/registration/storage.rb
--- old/yast2-registration-3.1.29/src/lib/registration/storage.rb 2014-04-04 13:13:15.000000000 +0200
+++ new/yast2-registration-3.1.31/src/lib/registration/storage.rb 2014-04-10 11:28:39.000000000 +0200
@@ -35,7 +35,24 @@
end
# remember the registered base product
- class BaseProducts < Struct.new(:products)
+ class BaseProduct < Struct.new(:product)
+ include Singleton
+ end
+
+ # remember the values entered by user
+ class InstallationOptions
+ include Singleton
+
+ attr_accessor :install_updates, :email, :reg_code, :selected_addons
+
+ def initialize
+ @email = ""
+ @reg_code = ""
+ @selected_addons = []
+ end
+ end
+
+ class Cache < Struct.new(:available_addons)
include Singleton
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-registration-3.1.29/src/lib/registration/sw_mgmt.rb new/yast2-registration-3.1.31/src/lib/registration/sw_mgmt.rb
--- old/yast2-registration-3.1.29/src/lib/registration/sw_mgmt.rb 2014-04-04 13:13:15.000000000 +0200
+++ new/yast2-registration-3.1.31/src/lib/registration/sw_mgmt.rb 2014-04-10 11:28:39.000000000 +0200
@@ -69,10 +69,7 @@
`mount -o bind #{tmpdir}/zypp #{ZYPP_DIR}`
end
- def self.base_products_to_register
- # just for debugging:
- # return [{"name" => "SLES", "arch" => "x86_64", "version" => "12-1.47"}]
-
+ def self.find_base_product
# during installation the products are :selected,
# on a running system the products are :installed
# during upgrade use the newer selected product (same as in installation)
@@ -87,12 +84,27 @@
end
end
+ log.debug "Found base products: #{products}"
+ log.info "Found base products: #{products.map{|p| p["name"]}}"
+ log.warn "More than one base product found!" if products.size > 1
+
+ products.first
+ end
+
+ def self.base_product_to_register
+ # just for debugging:
+ # return {"name" => "SLES", "arch" => "x86_64", "version" => "12-1.47"}
+
+ base_product = find_base_product
+
# filter out not needed data
- product_info = products.map do |p|
- { "name" => p["name"], "arch" => p["arch"], "version" => p["version"]}
- end
+ product_info = {
+ "name" => base_product["name"],
+ "arch" => base_product["arch"],
+ "version" => base_product["version"]
+ }
- log.info("Base products to register: #{product_info}")
+ log.info("Base product to register: #{product_info}")
product_info
end
@@ -104,7 +116,7 @@
# unload them)
if !Pkg.SourceSaveAll
# error message
- raise Registration::PkgError, N_("Saving repository configuration failed.")
+ raise ::Registration::PkgError, N_("Saving repository configuration failed.")
end
# services for registered products
@@ -140,7 +152,10 @@
end
# get list of repositories belonging to registered services
- def self.service_repos(product_services)
+ # @param product_services [Array<SccApi::ProductServices>] added services
+ # @param only_updates [Boolean] return only update repositories
+ # @return [Array<Hash>] list of repositories
+ def self.service_repos(product_services, only_updates: false)
repo_data = Pkg.SourceGetCurrent(false).map do |repo|
data = Pkg.SourceGeneralData(repo)
data["SrcId"] = repo
@@ -154,9 +169,31 @@
repos = repo_data.select{|repo| service_names.include?(repo["service"])}
log.info "Service repositories: #{repos}"
+ if only_updates
+ # TODO FIXME: curently just check the name,
+ # later use a new libzypp flag for detecting update repos
+ repos.select!{|repo| repo["name"].match(/update/i)}
+ end
+
repos
end
+ # Set repository state (enabled/disabled)
+ # @param repos [Array<Hash>] list of repositories
+ # @param repos [Boolean] true = enable, false = disable, nil = no change
+ # @return [void]
+ def self.set_repos_state(repos, enabled)
+ # keep the defaults when not defined
+ return if enabled.nil?
+
+ repos.each do |repo|
+ if repo["enabled"] != enabled
+ log.info "Changing repository state: #{repo["name"]} enabled: #{enabled}"
+ Pkg.SourceSetEnabled(repo["SrcId"], enabled)
+ end
+ end
+ end
+
end
end
continue with "q"...
Checked in at Thu Apr 10 17:28:40 CEST 2014 by ro
Remember to have fun...
--
To unsubscribe, e-mail: yast-commit+unsubscribe(a)opensuse.org
For additional commands, e-mail: yast-commit+help(a)opensuse.org