Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package yast2-firstboot for openSUSE:Factory 
checked in at 2022-10-22 14:12:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-firstboot (Old)
 and      /work/SRC/openSUSE:Factory/.yast2-firstboot.new.2275 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yast2-firstboot"

Sat Oct 22 14:12:26 2022 rev:115 rq:1030340 version:4.5.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-firstboot/yast2-firstboot.changes  
2022-08-23 14:26:37.411223058 +0200
+++ 
/work/SRC/openSUSE:Factory/.yast2-firstboot.new.2275/yast2-firstboot.changes    
    2022-10-22 14:12:46.184692881 +0200
@@ -1,0 +2,7 @@
+Wed Oct 19 08:09:57 UTC 2022 - Jos?? Iv??n L??pez Gonz??lez <jlo...@suse.com>
+
+- Add client to select product in WSL (jsc#PED-1380).
+- Allow installing WSL GUI pattern (jsc#PM-3439).
+- 4.5.4
+
+-------------------------------------------------------------------

Old:
----
  yast2-firstboot-4.5.3.tar.bz2

New:
----
  yast2-firstboot-4.5.4.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ yast2-firstboot.spec ++++++
--- /var/tmp/diff_new_pack.03x0Ca/_old  2022-10-22 14:12:46.752694227 +0200
+++ /var/tmp/diff_new_pack.03x0Ca/_new  2022-10-22 14:12:46.756694237 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-firstboot
-Version:        4.5.3
+Version:        4.5.4
 Release:        0
 Summary:        YaST2 - Initial System Configuration
 License:        GPL-2.0-only
@@ -78,6 +78,7 @@
 # registration and +1 for next line and then here change false to true
 sed -i '/<name>registration/,+1s/false/true/' control/firstboot.xml
 sed -i '/<name>registration/,+1s/false/true/' wsl/firstboot.ycontrol.xml
+sed -i '/<name>firstboot_wsl_product_selection/,+1s/false/true/' 
wsl/firstboot.ycontrol.xml
 %endif
 
 %install

++++++ yast2-firstboot-4.5.3.tar.bz2 -> yast2-firstboot-4.5.4.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-firstboot-4.5.3/package/yast2-firstboot.changes 
new/yast2-firstboot-4.5.4/package/yast2-firstboot.changes
--- old/yast2-firstboot-4.5.3/package/yast2-firstboot.changes   2022-08-11 
13:23:45.000000000 +0200
+++ new/yast2-firstboot-4.5.4/package/yast2-firstboot.changes   2022-10-21 
11:27:11.000000000 +0200
@@ -1,4 +1,11 @@
 -------------------------------------------------------------------
+Wed Oct 19 08:09:57 UTC 2022 - Jos?? Iv??n L??pez Gonz??lez <jlo...@suse.com>
+
+- Add client to select product in WSL (jsc#PED-1380).
+- Allow installing WSL GUI pattern (jsc#PM-3439).
+- 4.5.4
+
+-------------------------------------------------------------------
 Wed Aug 10 13:59:28 UTC 2022 - David Diaz <dgonza...@suse.com>
 
 - Do not skip client for root password automatically if
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-firstboot-4.5.3/package/yast2-firstboot.spec 
new/yast2-firstboot-4.5.4/package/yast2-firstboot.spec
--- old/yast2-firstboot-4.5.3/package/yast2-firstboot.spec      2022-08-11 
13:23:45.000000000 +0200
+++ new/yast2-firstboot-4.5.4/package/yast2-firstboot.spec      2022-10-21 
11:27:11.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-firstboot
-Version:        4.5.3
+Version:        4.5.4
 Release:        0
 Summary:        YaST2 - Initial System Configuration
 License:        GPL-2.0-only
@@ -77,6 +77,7 @@
 # registration and +1 for next line and then here change false to true
 sed -i '/<name>registration/,+1s/false/true/' control/firstboot.xml
 sed -i '/<name>registration/,+1s/false/true/' wsl/firstboot.ycontrol.xml
+sed -i '/<name>firstboot_wsl_product_selection/,+1s/false/true/' 
wsl/firstboot.ycontrol.xml
 %endif
 
 %install
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-firstboot-4.5.3/src/Makefile.am 
new/yast2-firstboot-4.5.4/src/Makefile.am
--- old/yast2-firstboot-4.5.3/src/Makefile.am   2022-08-11 13:23:45.000000000 
+0200
+++ new/yast2-firstboot-4.5.4/src/Makefile.am   2022-10-21 11:27:11.000000000 
+0200
@@ -26,7 +26,8 @@
   clients/firstboot_root.rb \
   clients/firstboot_user.rb \
   clients/firstboot_configuration_management.rb \
-  clients/firstboot_wsl.rb
+  clients/firstboot_wsl.rb \
+  clients/firstboot_wsl_product_selection.rb
 
 yncludedir = @yncludedir@/firstboot
 ynclude_DATA = \
@@ -50,7 +51,16 @@
   lib/y2firstboot/clients/root.rb \
   lib/y2firstboot/clients/user.rb \
   lib/y2firstboot/clients/licenses.rb \
-  lib/y2firstboot/clients/wsl.rb
+  lib/y2firstboot/clients/wsl.rb \
+  lib/y2firstboot/clients/wsl_product_selection.rb
+
+ylibdir = "${yast2dir}/lib/y2firstboot"
+ylib_DATA = \
+  lib/y2firstboot/wsl_config.rb
+
+ylibdialogsdir = "${yast2dir}/lib/y2firstboot/dialogs"
+ylibdialogs_DATA = \
+  lib/y2firstboot/dialogs/wsl_product_selection.rb
 
 symbolicdir = @icondir@/hicolor/symbolic/apps
 symbolic_DATA = \
@@ -59,6 +69,6 @@
 scalable_DATA = \
   icons/hicolor/scalable/apps/yast-firstboot.svg
 
-EXTRA_DIST = $(module_DATA) $(client_DATA) $(ynclude_DATA) $(scrconf_DATA) 
$(schemafiles_DATA) $(fillup_DATA) $(ylibclient_DATA) $(symbolic_DATA) 
$(scalable_DATA)
+EXTRA_DIST = $(module_DATA) $(client_DATA) $(ynclude_DATA) $(scrconf_DATA) 
$(schemafiles_DATA) $(fillup_DATA) $(ylibclient_DATA) ${ylib_DATA} 
${ylibdialogs_DATA} $(symbolic_DATA) $(scalable_DATA)
 
 include $(top_srcdir)/Makefile.am.common
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-firstboot-4.5.3/src/clients/firstboot_wsl_product_selection.rb 
new/yast2-firstboot-4.5.4/src/clients/firstboot_wsl_product_selection.rb
--- old/yast2-firstboot-4.5.3/src/clients/firstboot_wsl_product_selection.rb    
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-firstboot-4.5.4/src/clients/firstboot_wsl_product_selection.rb    
2022-10-21 11:27:11.000000000 +0200
@@ -0,0 +1,22 @@
+# Copyright (c) [2022] 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 "y2firstboot/clients/wsl_product_selection"
+
+Y2Firstboot::Clients::WSLProductSelection.new.run
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-firstboot-4.5.3/src/lib/y2firstboot/clients/wsl.rb 
new/yast2-firstboot-4.5.4/src/lib/y2firstboot/clients/wsl.rb
--- old/yast2-firstboot-4.5.3/src/lib/y2firstboot/clients/wsl.rb        
2022-08-11 13:23:45.000000000 +0200
+++ new/yast2-firstboot-4.5.4/src/lib/y2firstboot/clients/wsl.rb        
2022-10-21 11:27:11.000000000 +0200
@@ -21,18 +21,27 @@
 require "yast2/execute"
 require "y2firstboot/clients/user"
 require "etc"
+require "y2firstboot/wsl_config"
 
 Yast.import "GetInstArgs"
+Yast.import "Report"
 
 module Y2Firstboot
   module Clients
     # Client to set up required configuration for WSL
     class WSL < Yast::Client
+      def initialize
+        textdomain "firstboot"
+        super
+      end
+
       def run
         return :back if Yast::GetInstArgs.going_back
 
         write_wsl_user
         setup_machine_id
+        switch_product
+        install_patterns
 
         :next
       end
@@ -60,6 +69,30 @@
         # missing
         Yast::Execute.locally("/usr/bin/systemd-machine-id-setup")
       end
+
+      # Performs changes in order to remove the current product and install 
the selected product
+      # (see client wsl_product_selection)
+      def switch_product
+        return unless Y2Firstboot::WSLConfig.instance.product_switched?
+
+        product = Y2Firstboot::WSLConfig.instance.product
+        installed_product = Y2Firstboot::WSLConfig.instance.installed_product
+
+        Yast::Pkg.ResolvableRemove(installed_product.name, :product) if 
installed_product
+        Yast::Pkg.ResolvableInstall(product["name"], :product)
+      end
+
+      # Installs the selected patterns
+      # (see client wsl_product_selection)
+      def install_patterns
+        Y2Firstboot::WSLConfig.instance.patterns.each do |pattern|
+          next if Yast::Pkg.ResolvableInstall(pattern, :pattern)
+
+          # TRANSLATORS: Error message, %s is a pattern name
+          Yast::Report.Error(_("Cannot select pattern\n\"%s\" to install.\n" \
+            "Some software might be missing.") % pattern)
+        end
+      end
     end
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-firstboot-4.5.3/src/lib/y2firstboot/clients/wsl_product_selection.rb 
new/yast2-firstboot-4.5.4/src/lib/y2firstboot/clients/wsl_product_selection.rb
--- 
old/yast2-firstboot-4.5.3/src/lib/y2firstboot/clients/wsl_product_selection.rb  
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/yast2-firstboot-4.5.4/src/lib/y2firstboot/clients/wsl_product_selection.rb  
    2022-10-21 11:27:11.000000000 +0200
@@ -0,0 +1,147 @@
+# Copyright (c) [2022] 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 "y2firstboot/wsl_config"
+require "y2firstboot/dialogs/wsl_product_selection"
+
+module Y2Firstboot
+  module Clients
+    # Client for selecting the product to use with WSL (jsc#PED-1380)
+    #
+    # It also allows to indicate whether to install WSL GUI pattern 
(jsc#PM-3439).
+    class WSLProductSelection < Yast::Client
+      # Runs the client
+      #
+      # @raise [RuntimeError] see {#require_registration}.
+      #
+      # @return [Symbol]
+      def run
+        require_registration
+
+        return :auto if products.none?
+
+        dialog = Dialogs::WSLProductSelection.new(products,
+          default_product: product,
+          wsl_gui_pattern: wsl_gui_pattern?)
+
+        result = dialog.run
+
+        save(product: dialog.product, wsl_gui_pattern: dialog.wsl_gui_pattern) 
if result == :next
+
+        result
+      end
+
+    private
+
+      WSL_GUI_PATTERN = "wsl_gui".freeze
+      private_constant :WSL_GUI_PATTERN
+
+      # Saves changes
+      #
+      # @param product [Hash] Selected product
+      # @param wsl_gui_pattern [Boolean] Whether to install WSL GUI pattern
+      def save(product:, wsl_gui_pattern:)
+        self.product = product
+        self.wsl_gui_pattern = wsl_gui_pattern
+        update_registration
+      end
+
+      # Product to use
+      #
+      # @see ???SLConfig
+      #
+      # @return [Hash]
+      def product
+        WSLConfig.instance.product || default_product
+      end
+
+      # Sets the product to use
+      #
+      # @see ???SLConfig
+      #
+      # @param value [Hash] A product
+      def product=(value)
+        WSLConfig.instance.product = value
+      end
+
+      # Whether the WSL GUI pattern should be installed
+      #
+      # @see ???SLConfig
+      #
+      # @return [Boolean]
+      def wsl_gui_pattern?
+        WSLConfig.instance.patterns.include?(WSL_GUI_PATTERN)
+      end
+
+      # Sets whether to install the WSL GUI pattern
+      #
+      # @param value [Boolean]
+      def wsl_gui_pattern=(value)
+        if value
+          WSLConfig.instance.patterns.push(WSL_GUI_PATTERN).uniq!
+        else
+          WSLConfig.instance.patterns.delete(WSL_GUI_PATTERN)
+        end
+      end
+
+      # Updates values stored in registration
+      #
+      # Those values indicates to registration what product was selected and 
whether the product
+      # has to be registered.
+      #
+      # @see Registration::Storage::InstallationOptions
+      def update_registration
+        yaml_product = WSLConfig.instance.product
+        force_registration = WSLConfig.instance.product_switched? || 
wsl_gui_pattern?
+
+        Registration::Storage::InstallationOptions.instance.yaml_product = 
yaml_product
+        Registration::Storage::InstallationOptions.instance.force_registration 
= force_registration
+      end
+
+      # Name of the default product to use from YAML file
+      #
+      # @return [String]
+      def default_product
+        return nil if products.none?
+
+        products.find { |p| p["default"] } || products.first
+      end
+
+      # All products from YAML file
+      #
+      # @return [Array<Hash>]
+      def products
+        @products ||= Registration::YamlProductsReader.new.read
+      end
+
+      # Tries to require yast2-registration files
+      #
+      # @note yast2-registration might not be available for some products 
(e.g., openSUSE).
+      #
+      # @raise [RuntimeError] if yast2-registration files cannot be loaded
+      def require_registration
+        require "registration/yaml_products_reader"
+        require "registration/storage"
+      rescue LoadError
+        raise "yast2-registration >= 4.5.6 required"
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-firstboot-4.5.3/src/lib/y2firstboot/dialogs/wsl_product_selection.rb 
new/yast2-firstboot-4.5.4/src/lib/y2firstboot/dialogs/wsl_product_selection.rb
--- 
old/yast2-firstboot-4.5.3/src/lib/y2firstboot/dialogs/wsl_product_selection.rb  
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/yast2-firstboot-4.5.4/src/lib/y2firstboot/dialogs/wsl_product_selection.rb  
    2022-10-21 11:27:11.000000000 +0200
@@ -0,0 +1,155 @@
+# Copyright (c) [2022] 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 "ui/installation_dialog"
+require "y2firstboot/wsl_config"
+
+Yast.import "UI"
+
+module Y2Firstboot
+  module Dialogs
+    # Dialog for selecting the product to use with WSL
+    class WSLProductSelection < ::UI::InstallationDialog
+      include Yast::I18n
+
+      # Selected product
+      #
+      # @return [Hash]
+      attr_reader :product
+
+      # Whether the WSL GUI pattern was selected
+      #
+      # @return [Boolean]
+      attr_reader :wsl_gui_pattern
+
+      # Constructor
+      #
+      # @param products [Array<Hash>] All possible products
+      # @param default_product [Hash] Product selected by default
+      # @param wsl_gui_pattern [Boolean] Whether WSL GUI pattern is selected 
by default
+      def initialize(products, default_product: nil, wsl_gui_pattern: false)
+        textdomain "firstboot"
+
+        super()
+        @products = products
+        @product = default_product || products.first
+        @wsl_gui_pattern = wsl_gui_pattern
+      end
+
+      def next_handler
+        save
+        super
+      end
+
+    protected
+
+      def dialog_title
+        # TRANSLATORS: dialog title
+        _("Product Selection")
+      end
+
+      def dialog_content
+        items = products.map { |p| item_for(p) }
+
+        HSquash(
+          VBox(
+            RadioButtonGroup(
+              Id(:product_selector),
+              VBox(
+                # TRANSLATORS: dialog heading
+                Left(Heading(_("Select the product to use"))),
+                VSpacing(1),
+                *items
+              )
+            ),
+            VSpacing(2),
+            # TRANSLATORS:
+            Label(_("The WSL GUI pattern provides some needed packages for\n" \
+              "a better experience with graphical applications in WSL.")),
+            VSpacing(1),
+            # TRANSLATORS: check box label
+            Left(CheckBox(Id(:wsl_gui_pattern),
+              _("Install WSL GUI pattern (requires registration)"),
+              wsl_gui_pattern))
+          )
+        )
+      end
+
+      def help_text
+        # TRANSLATORS: help text (1/2)
+        _("<p>Select the product to use with Windows Subsystem for Linux 
(WSL). " \
+          "Some products might require registration.</p>") +
+          # TRANSLATORS: help text (2/2)
+          _("<p>To use graphical programs in WSL you need to install the WSL 
GUI pattern. " \
+              "In that case the system needs to be registered as well.</p>")
+      end
+
+    private
+
+      # All possible products to select
+      #
+      # @return [Array<Hash>]
+      attr_reader :products
+
+      # Radio button for selecting a product
+      #
+      # @param product [Hash]
+      def item_for(product)
+        Left(
+          RadioButton(
+            Id(item_id(product)),
+            product_label(product),
+            item_id(product) == item_id(self.product)
+          )
+        )
+      end
+
+      # Id for the radio button
+      #
+      # @param product [Hash]
+      # @return [String]
+      def item_id(product)
+        "#{product["name"]}:#{product["version"]}"
+      end
+
+      def product_label(product)
+        label = product["display_name"]
+
+        installed_product = WSLConfig.instance.installed_product
+        if installed_product.name != product["name"] ||
+            installed_product.version_version != product["version"]
+
+          # TRANSLATORS: suffix displayed for the products which require 
registration,
+          # %s is a product name like "SUSE Linux Enterprise Server 15 SP4"
+          label = _("%s (requires registration)") % label
+        end
+
+        label
+      end
+
+      def save
+        @wsl_gui_pattern = Yast::UI.QueryWidget(Id(:wsl_gui_pattern), :Value)
+
+        selected_id = Yast::UI.QueryWidget(Id(:product_selector), :Value)
+        @product = products.find { |p| item_id(p) == selected_id }
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-firstboot-4.5.3/src/lib/y2firstboot/wsl_config.rb 
new/yast2-firstboot-4.5.4/src/lib/y2firstboot/wsl_config.rb
--- old/yast2-firstboot-4.5.3/src/lib/y2firstboot/wsl_config.rb 1970-01-01 
01:00:00.000000000 +0100
+++ new/yast2-firstboot-4.5.4/src/lib/y2firstboot/wsl_config.rb 2022-10-21 
11:27:11.000000000 +0200
@@ -0,0 +1,79 @@
+# Copyright (c) [2022] 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 "singleton"
+require "y2packager/resolvable"
+
+module Y2Firstboot
+  # Configuration for WSL firstboot
+  class WSLConfig
+    include Singleton
+
+    # Product to use with WSL
+    #
+    # @return [Hash, nil]
+    attr_accessor :product
+
+    # Patterns to install as part of the WSL configuration
+    #
+    # @return [Array<String>]
+    attr_accessor :patterns
+
+    def initialize
+      @patterns = []
+    end
+
+    # Whether the selected product is not the installed product
+    #
+    # @return [Boolean]
+    def product_switched?
+      return false unless installed_product && product
+
+      # "version_version" contains the version without the release number 
("15.4"),
+      # unlike the "version" attribute ("15.4-0")
+      installed_product.name != product["name"] ||
+        installed_product.version_version != product["version"]
+    end
+
+    # Current installed product
+    #
+    # @return [Y2Packager::Resolvable, nil]
+    def installed_product
+      @installed_product ||= find_installed_product
+    end
+
+  private
+
+    # Finds the currently installed product
+    #
+    # @return [Y2Packager::Resolvable, nil]
+    def find_installed_product
+      init_package_system
+      Y2Packager::Resolvable.find(kind: :product, status: :installed, 
category: "base").first
+    end
+
+    # Initializes the package system
+    def init_package_system
+      Yast.import "PackageSystem"
+
+      Yast::PackageSystem.EnsureTargetInit
+      Yast::PackageSystem.EnsureSourceInit
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-firstboot-4.5.3/test/y2firstboot/clients/wsl_product_selection_test.rb
 
new/yast2-firstboot-4.5.4/test/y2firstboot/clients/wsl_product_selection_test.rb
--- 
old/yast2-firstboot-4.5.3/test/y2firstboot/clients/wsl_product_selection_test.rb
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/yast2-firstboot-4.5.4/test/y2firstboot/clients/wsl_product_selection_test.rb
    2022-10-21 11:27:11.000000000 +0200
@@ -0,0 +1,252 @@
+#!/usr/bin/env rspec
+
+# Copyright (c) [2022] 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_relative "../../test_helper"
+require "y2firstboot/clients/wsl_product_selection"
+require "y2firstboot/dialogs/wsl_product_selection"
+require "y2firstboot/wsl_config"
+require "singleton"
+
+describe Y2Firstboot::Clients::WSLProductSelection do
+  subject { described_class.new }
+
+  describe "#run" do
+    context "when yast2-registration is not available" do
+      before do
+        allow(subject).to 
receive(:require).with(/registration\/*/).and_raise(LoadError)
+      end
+
+      it "raises an exception" do
+        expect { subject.run }.to raise_error(RuntimeError, 
/yast2-registration/)
+      end
+    end
+
+    context "when yast2-registration is available" do
+      before do
+        allow(subject).to receive(:require_registration)
+      end
+
+      # Mimic yast-registration classes
+      module Registration
+        class YamlProductsReader
+          attr_reader :read
+        end
+
+        module Storage
+          class InstallationOptions
+            include Singleton
+
+            attr_accessor :yaml_product, :force_registration
+          end
+        end
+      end
+
+      context "and there are no products from YAML file" do
+        before do
+          allow_any_instance_of(Registration::YamlProductsReader).to 
receive(:read).and_return([])
+          allow(Y2Firstboot::Dialogs::WSLProductSelection).to 
receive(:new).and_return(dialog)
+        end
+
+        let(:dialog) { 
instance_double(Y2Firstboot::Dialogs::WSLProductSelection) }
+
+        it "does not run the dialog for selecting product" do
+          expect(dialog).to_not receive(:run)
+
+          subject.run
+        end
+
+        it "does not change the current WSL config" do
+          Y2Firstboot::WSLConfig.instance.product = { "name" => "test" }
+          Y2Firstboot::WSLConfig.instance.patterns = ["test"]
+
+          subject.run
+
+          expect(Y2Firstboot::WSLConfig.instance.product).to eq("name" => 
"test")
+          expect(Y2Firstboot::WSLConfig.instance.patterns).to 
contain_exactly("test")
+        end
+
+        it "returns :auto" do
+          expect(subject.run).to eq(:auto)
+        end
+      end
+
+      context "and there are products from YAML file" do
+        before do
+          allow_any_instance_of(Registration::YamlProductsReader)
+            .to receive(:read).and_return([sles, sled])
+
+          allow(Y2Firstboot::Dialogs::WSLProductSelection).to 
receive(:new).and_return(dialog)
+
+          allow(Y2Firstboot::WSLConfig.instance)
+            .to receive(:product_switched?).and_return(product_switched)
+        end
+
+        let(:sles) { { "name" => "SLES", "version" => "15.4" } }
+        let(:sled) { { "name" => "SLED", "version" => "15.4" } }
+
+        let(:dialog) do
+          instance_double(Y2Firstboot::Dialogs::WSLProductSelection,
+            run:             dialog_result,
+            product:         selected_product,
+            wsl_gui_pattern: wsl_gui_pattern)
+        end
+
+        let(:dialog_result) { :abort }
+        let(:selected_product) { nil }
+        let(:wsl_gui_pattern) { nil }
+
+        let(:product_switched) { false }
+
+        it "runs the dialog for selecting product" do
+          expect(dialog).to receive(:run)
+
+          subject.run
+        end
+
+        context "if the dialog is accepted" do
+          let(:dialog_result) { :next }
+          let(:selected_product) { sled }
+
+          it "stores the selected product in the WSL config" do
+            subject.run
+
+            expect(Y2Firstboot::WSLConfig.instance.product).to eq(sled)
+          end
+
+          context "if the WSL GUI pattern was selected" do
+            let(:wsl_gui_pattern) { true }
+
+            before do
+              Y2Firstboot::WSLConfig.instance.patterns = []
+            end
+
+            it "stores the WSL GUI pattern in the WSL config" do
+              subject.run
+
+              expect(Y2Firstboot::WSLConfig.instance.patterns).to 
include("wsl_gui")
+            end
+          end
+
+          context "if the WSL GUI pattern was not selected" do
+            let(:wsl_gui_pattern) { false }
+
+            before do
+              Y2Firstboot::WSLConfig.instance.patterns = ["wsl_gui"]
+            end
+
+            it "does not store the WSL GUI pattern in the WSL config" do
+              subject.run
+
+              expect(Y2Firstboot::WSLConfig.instance.patterns).to_not 
include("wsl_gui")
+            end
+          end
+
+          it "updates the product in registration storage" do
+            Registration::Storage::InstallationOptions.instance.yaml_product = 
nil
+
+            subject.run
+
+            
expect(Registration::Storage::InstallationOptions.instance.yaml_product).to 
eq(sled)
+          end
+
+          context "if the product was switched" do
+            let(:product_switched) { true }
+            let(:wsl_gui_pattern) { false }
+
+            it "updates registration storage to force registration" do
+              
Registration::Storage::InstallationOptions.instance.force_registration = false
+
+              subject.run
+
+              
expect(Registration::Storage::InstallationOptions.instance.force_registration)
+                .to eq(true)
+            end
+          end
+
+          context "if the product was not switched" do
+            let(:product_switched) { false }
+
+            context "and the WSL GUI pattern was selected" do
+              let(:wsl_gui_pattern) { true }
+
+              it "updates registration storage to force registration" do
+                
Registration::Storage::InstallationOptions.instance.force_registration = false
+
+                subject.run
+
+                
expect(Registration::Storage::InstallationOptions.instance.force_registration)
+                  .to eq(true)
+              end
+            end
+
+            context "and the WSL GUI pattern was not selected" do
+              let(:wsl_gui_pattern) { false }
+
+              it "updates registration storage to not force registration" do
+                
Registration::Storage::InstallationOptions.instance.force_registration = true
+
+                subject.run
+
+                
expect(Registration::Storage::InstallationOptions.instance.force_registration)
+                  .to eq(false)
+              end
+            end
+          end
+
+          it "returns :next" do
+            expect(subject.run).to eq(:next)
+          end
+        end
+
+        context "if the dialog is not accepted" do
+          let(:dialog_result) { :cancel }
+          let(:selected_product) { sled }
+          let(:wsl_gui_pattern) { true }
+
+          it "does not change the WSL config" do
+            Y2Firstboot::WSLConfig.instance.product = sles
+            Y2Firstboot::WSLConfig.instance.patterns = []
+
+            subject.run
+
+            expect(Y2Firstboot::WSLConfig.instance.product).to eq(sles)
+            expect(Y2Firstboot::WSLConfig.instance.patterns).to eq([])
+          end
+
+          it "does not change the registration storage" do
+            Registration::Storage::InstallationOptions.instance.yaml_product = 
sles
+            
Registration::Storage::InstallationOptions.instance.force_registration = false
+
+            subject.run
+
+            
expect(Registration::Storage::InstallationOptions.instance.yaml_product).to 
eq(sles)
+            
expect(Registration::Storage::InstallationOptions.instance.force_registration)
+              .to eq(false)
+          end
+
+          it "returns the dialog result" do
+            expect(subject.run).to eq(:cancel)
+          end
+        end
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-firstboot-4.5.3/test/y2firstboot/clients/wsl_test.rb 
new/yast2-firstboot-4.5.4/test/y2firstboot/clients/wsl_test.rb
--- old/yast2-firstboot-4.5.3/test/y2firstboot/clients/wsl_test.rb      
2022-08-11 13:23:45.000000000 +0200
+++ new/yast2-firstboot-4.5.4/test/y2firstboot/clients/wsl_test.rb      
2022-10-21 11:27:11.000000000 +0200
@@ -21,6 +21,7 @@
 
 require_relative "../../test_helper"
 require "y2firstboot/clients/wsl"
+require "y2firstboot/wsl_config"
 
 describe Y2Firstboot::Clients::WSL do
   subject(:client) { described_class.new }
@@ -36,6 +37,15 @@
       allow(File).to receive(:write)
 
       allow(Yast::Execute).to receive(:locally)
+
+      allow(Y2Firstboot::WSLConfig.instance)
+        .to receive(:installed_product).and_return(installed_product)
+
+      allow(Y2Firstboot::WSLConfig.instance)
+        .to receive(:product).and_return(product)
+
+      allow(Yast::Pkg).to receive(:ResolvableRemove)
+      allow(Yast::Pkg).to receive(:ResolvableInstall)
     end
 
     let(:going_back) { nil }
@@ -44,6 +54,10 @@
 
     let(:user) { nil }
 
+    let(:installed_product) { nil }
+
+    let(:product) { nil }
+
     context "when going back from another client" do
       let(:going_back) { true }
 
@@ -88,6 +102,78 @@
 
           subject.run
         end
+      end
+
+      context "when the product was switched" do
+        let(:installed_product) do
+          double(
+            Y2Packager::Resolvable,
+            name:            "SLES",
+            version_version: "15.4"
+          )
+        end
+        let(:product) { { "name" => "SLED", "version" => "15.4" } }
+
+        it "removes the installed product" do
+          expect(Yast::Pkg).to receive(:ResolvableRemove).with("SLES", 
:product)
+
+          subject.run
+        end
+
+        it "installs the selected product" do
+          expect(Yast::Pkg).to receive(:ResolvableInstall).with("SLED", 
:product)
+
+          subject.run
+        end
+      end
+
+      context "when the product was not switched" do
+        let(:installed_product) do
+          double(
+            Y2Packager::Resolvable,
+            name:            "SLES",
+            version_version: "15.4"
+          )
+        end
+        let(:product) { { "name" => "SLES", "version" => "15.4" } }
+
+        it "does remove the installed product" do
+          expect(Yast::Pkg).to_not receive(:ResolvableRemove).with("SLES", 
:product)
+
+          subject.run
+        end
+
+        it "does not install another product" do
+          expect(Yast::Pkg).to_not receive(:ResolvableInstall).with(anything, 
:product)
+
+          subject.run
+        end
+      end
+
+      context "when there are selected patterns" do
+        before do
+          Y2Firstboot::WSLConfig.instance.patterns = ["wsl_gui", "test"]
+        end
+
+        it "installs the selected patterns" do
+          expect(Yast::Pkg).to receive(:ResolvableInstall).with("wsl_gui", 
:pattern)
+            .and_return(true)
+          expect(Yast::Pkg).to receive(:ResolvableInstall).with("test", 
:pattern)
+            .and_return(true)
+
+          subject.run
+        end
+
+        it "reports an error when a pattern cannot be installed" do
+          expect(Yast::Pkg).to receive(:ResolvableInstall).with("wsl_gui", 
:pattern)
+            .and_return(false)
+          expect(Yast::Pkg).to receive(:ResolvableInstall).with("test", 
:pattern)
+            .and_return(true)
+
+          expect(Yast::Report).to receive(:Error).with(/wsl_gui/)
+
+          subject.run
+        end
       end
     end
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-firstboot-4.5.3/test/y2firstboot/dialogs/wsl_product_selection_test.rb
 
new/yast2-firstboot-4.5.4/test/y2firstboot/dialogs/wsl_product_selection_test.rb
--- 
old/yast2-firstboot-4.5.3/test/y2firstboot/dialogs/wsl_product_selection_test.rb
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/yast2-firstboot-4.5.4/test/y2firstboot/dialogs/wsl_product_selection_test.rb
    2022-10-21 11:27:11.000000000 +0200
@@ -0,0 +1,134 @@
+#!/usr/bin/env rspec
+
+# Copyright (c) [2022] 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_relative "../../test_helper"
+require "y2firstboot/dialogs/wsl_product_selection"
+
+Yast.import "UI"
+
+describe Y2Firstboot::Dialogs::WSLProductSelection do
+  include Yast::UIShortcuts
+
+  def find_widget(regexp, content)
+    regexp = regexp.to_s unless regexp.is_a?(Regexp)
+
+    content.nested_find do |element|
+      next unless element.is_a?(Yast::Term)
+
+      element.params.any? do |param|
+        param.is_a?(Yast::Term) &&
+          param.value == :id &&
+          regexp.match?(param.params.first.to_s)
+      end
+    end
+  end
+
+  subject do
+    described_class.new(products,
+      default_product: default_product, wsl_gui_pattern: wsl_gui_pattern)
+  end
+
+  let(:products) { [sles, sled] }
+  let(:sles) { { "name" => "SLES", "version" => "15.4" } }
+  let(:sled) { { "name" => "SLED", "version" => "15.4" } }
+
+  let(:default_product) { sled }
+  let(:wsl_gui_pattern) { false }
+
+  let(:installed_product) { double(Y2Packager::Resolvable, name: "SLES", 
version_version: "15.4") }
+  before do
+    allow(Y2Firstboot::WSLConfig.instance).to receive(:installed_product)
+      .and_return(installed_product)
+  end
+
+  describe "#dialog_content" do
+    it "shows radio button box for selecting the product" do
+      widget = find_widget(:product_selector, subject.send(:dialog_content))
+
+      expect(widget).to_not be_nil
+    end
+
+    it "shows a radio button for each product" do
+      products.each do |product|
+        name = product["name"]
+        widget = find_widget(/#{name}/, subject.send(:dialog_content))
+        expect(widget).to_not be_nil
+      end
+    end
+
+    it "shows a check box for selecting the WSL GUI pattern" do
+      widget = find_widget(:wsl_gui_pattern, subject.send(:dialog_content))
+
+      expect(widget).to_not be_nil
+    end
+
+    it "automatically selects the default product" do
+      widget = find_widget(/SLED/, subject.send(:dialog_content))
+
+      expect(widget.params.last).to eq(true)
+    end
+
+    context "when WSL GUI pattern is indicated as selected" do
+      let(:wsl_gui_pattern) { true }
+
+      it "selects WSL GUI pattern checkbox by default" do
+        widget = find_widget(:wsl_gui_pattern, subject.send(:dialog_content))
+
+        expect(widget.params.last).to eq(true)
+      end
+    end
+
+    context "when WSL GUI pattern is not indicated as selected" do
+      let(:wsl_gui_pattern) { false }
+
+      it "does not select WSL GUI pattern checkbox by default" do
+        widget = find_widget(:wsl_gui_pattern, subject.send(:dialog_content))
+
+        expect(widget.params.last).to eq(false)
+      end
+    end
+  end
+
+  describe "#next_handler" do
+    before do
+      allow(Yast::UI).to receive(:QueryWidget).and_call_original
+      allow(Yast::UI).to receive(:QueryWidget).with(Id(:wsl_gui_pattern), 
:Value).and_return(true)
+      allow(Yast::UI).to receive(:QueryWidget).with(Id(:product_selector), 
:Value)
+        .and_return("SLES:15.4")
+    end
+
+    it "saves whether the WSL GUI pattern checkbox was selected" do
+      expect(subject.wsl_gui_pattern).to eq(false)
+
+      subject.next_handler
+
+      expect(subject.wsl_gui_pattern).to eq(true)
+    end
+
+    it "saves the selected product" do
+      expect(subject.product).to eq(sled)
+
+      subject.next_handler
+
+      expect(subject.product).to eq(sles)
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-firstboot-4.5.3/test/y2firstboot/wsl_config_test.rb 
new/yast2-firstboot-4.5.4/test/y2firstboot/wsl_config_test.rb
--- old/yast2-firstboot-4.5.3/test/y2firstboot/wsl_config_test.rb       
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-firstboot-4.5.4/test/y2firstboot/wsl_config_test.rb       
2022-10-21 11:27:11.000000000 +0200
@@ -0,0 +1,119 @@
+#!/usr/bin/env rspec
+
+# Copyright (c) [2022] 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_relative "../test_helper"
+require "y2firstboot/wsl_config"
+
+Yast.import "PackageSystem"
+
+describe Y2Firstboot::WSLConfig do
+  subject { described_class.instance }
+
+  before do
+    allow(Yast::PackageSystem).to receive(:EnsureTargetInit)
+    allow(Yast::PackageSystem).to receive(:EnsureSourceInit)
+
+    allow(Y2Packager::Resolvable)
+      .to receive(:find).with(a_hash_including(kind: 
:product)).and_return([installed_product])
+  end
+
+  after do
+    subject.instance_variable_set(:@installed_product, nil)
+  end
+
+  let(:installed_product) { nil }
+
+  describe "#product_switched?" do
+    before do
+      subject.product = product
+    end
+
+    context "when there is an installed product" do
+      let(:installed_product) do
+        double(
+          Y2Packager::Resolvable,
+          name:            "SLES",
+          version_version: "15.4"
+        )
+      end
+
+      context "and there is no selected product" do
+        let(:product) { nil }
+
+        it "returns false" do
+          expect(subject.product_switched?).to eq(false)
+        end
+      end
+
+      context "and the selected product is the installed product" do
+        let(:product) { { "name" => "SLES", "version" => "15.4" } }
+
+        it "returns false" do
+          expect(subject.product_switched?).to eq(false)
+        end
+      end
+
+      context "and the selected product is the installed product with 
different version" do
+        let(:product) { { "name" => "SLES", "version" => "15.3" } }
+
+        it "returns true" do
+          expect(subject.product_switched?).to eq(true)
+        end
+      end
+
+      context "and the selected product is not the installed product" do
+        let(:product) { { "name" => "SLED", "version" => "15.4" } }
+
+        it "returns true" do
+          expect(subject.product_switched?).to eq(true)
+        end
+      end
+    end
+
+    context "when there is no installed product" do
+      let(:installed_product) { nil }
+
+      let(:product) { "SLES" }
+
+      it "returns false" do
+        expect(subject.product_switched?).to eq(false)
+      end
+    end
+  end
+
+  describe "#installed_product" do
+    context "when there is an installed product" do
+      let(:installed_product) { double(Y2Packager::Resolvable, name: "SLES") }
+
+      it "returns the installed product" do
+        expect(subject.installed_product.name).to eq("SLES")
+      end
+    end
+
+    context "when there is no installed product" do
+      let(:installed_product) { nil }
+
+      it "returns nil" do
+        expect(subject.installed_product).to be_nil
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-firstboot-4.5.3/wsl/firstboot.ycontrol.xml 
new/yast2-firstboot-4.5.4/wsl/firstboot.ycontrol.xml
--- old/yast2-firstboot-4.5.3/wsl/firstboot.ycontrol.xml        2022-08-11 
13:23:45.000000000 +0200
+++ new/yast2-firstboot-4.5.4/wsl/firstboot.ycontrol.xml        2022-10-21 
11:27:11.000000000 +0200
@@ -155,6 +155,11 @@
                     <name>firstboot_root</name>
                 </module>
                 <module>
+                    <label>Product Selection</label>
+                    <name>firstboot_wsl_product_selection</name>
+                    <enabled config:type="boolean">false</enabled>
+                </module>
+                <module>
                     <label>Customer Center</label>
                     <name>registration</name>
                     <enabled config:type="boolean">false</enabled>
@@ -171,6 +176,12 @@
                     <enable_back>no</enable_back>
                     <enable_next>no</enable_next>
                 </module>
+                <module>
+                    <label>Package Installation</label>
+                    <name>inst_rpmcopy</name>
+                    <enable_back>no</enable_back>
+                    <enable_next>no</enable_next>
+                </module>
                 <module>
                     <label>Finish Setup</label>
                     <name>firstboot_write</name>

Reply via email to