Hello community,

here is the log from the commit of package yast2-installation for 
openSUSE:Factory checked in at 2018-06-19 11:52:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-installation (Old)
 and      /work/SRC/openSUSE:Factory/.yast2-installation.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yast2-installation"

Tue Jun 19 11:52:28 2018 rev:406 rq:616344 version:4.1.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-installation/yast2-installation.changes    
2018-05-22 16:58:49.659068885 +0200
+++ 
/work/SRC/openSUSE:Factory/.yast2-installation.new/yast2-installation.changes   
    2018-06-19 11:52:39.258557179 +0200
@@ -1,0 +2,30 @@
+Mon Jun 11 11:30:44 UTC 2018 - [email protected]
+
+- Firstboot.service: Shutdown on failure preventing the service to
+  hang because of a systemd dependency when trying to call halt
+  directly from the firsboot clients (bsc#1095253)
+- 4.1.2
+
+-------------------------------------------------------------------
+Wed Jun  6 14:21:02 UTC 2018 - [email protected]
+
+- Fixed possibly broken system after aborting upgrade running
+  over SSH (caused by a partially finished rollback) (bsc#1089643)
+
+-------------------------------------------------------------------
+Thu May 31 15:31:34 UTC 2018 - [email protected]
+
+- fix calling copy_files_finish to not crash
+  (related to bsc#1095323)
+- 4.1.1
+
+-------------------------------------------------------------------
+Thu May 31 10:17:19 UTC 2018 - [email protected]
+
+- Fix crash caused by previous fix when multipath is not available
+  (bsc#1095323)
+- Copy active_devices.txt for s390 to prevent blocking of
+  important devices when cio_ignore is active (bsc#1095033)
+- 4.1.0
+
+-------------------------------------------------------------------

Old:
----
  yast2-installation-4.0.61.tar.bz2

New:
----
  yast2-installation-4.1.2.tar.bz2

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

Other differences:
------------------
++++++ yast2-installation.spec ++++++
--- /var/tmp/diff_new_pack.MMpoKr/_old  2018-06-19 11:52:40.170523320 +0200
+++ /var/tmp/diff_new_pack.MMpoKr/_new  2018-06-19 11:52:40.174523171 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-installation
-Version:        4.0.61
+Version:        4.1.2
 Release:        0
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build

++++++ YaST2-Firstboot.service ++++++
--- /var/tmp/diff_new_pack.MMpoKr/_old  2018-06-19 11:52:40.218521538 +0200
+++ /var/tmp/diff_new_pack.MMpoKr/_new  2018-06-19 11:52:40.222521390 +0200
@@ -5,6 +5,7 @@
 [email protected] [email protected] 
[email protected] [email protected]
 Before=display-manager.service
 ConditionPathExists=/var/lib/YaST2/reconfig_system
+OnFailure=shutdown.target
 
 [Service]
 Type=oneshot

++++++ yast2-installation-4.0.61.tar.bz2 -> yast2-installation-4.1.2.tar.bz2 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-4.0.61/package/YaST2-Firstboot.service 
new/yast2-installation-4.1.2/package/YaST2-Firstboot.service
--- old/yast2-installation-4.0.61/package/YaST2-Firstboot.service       
2018-05-18 15:55:42.000000000 +0200
+++ new/yast2-installation-4.1.2/package/YaST2-Firstboot.service        
2018-06-12 17:30:05.000000000 +0200
@@ -5,6 +5,7 @@
 [email protected] [email protected] 
[email protected] [email protected]
 Before=display-manager.service
 ConditionPathExists=/var/lib/YaST2/reconfig_system
+OnFailure=shutdown.target
 
 [Service]
 Type=oneshot
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-4.0.61/package/yast2-installation.changes 
new/yast2-installation-4.1.2/package/yast2-installation.changes
--- old/yast2-installation-4.0.61/package/yast2-installation.changes    
2018-05-18 15:55:42.000000000 +0200
+++ new/yast2-installation-4.1.2/package/yast2-installation.changes     
2018-06-12 17:30:05.000000000 +0200
@@ -1,4 +1,34 @@
 -------------------------------------------------------------------
+Mon Jun 11 11:30:44 UTC 2018 - [email protected]
+
+- Firstboot.service: Shutdown on failure preventing the service to
+  hang because of a systemd dependency when trying to call halt
+  directly from the firsboot clients (bsc#1095253)
+- 4.1.2
+
+-------------------------------------------------------------------
+Wed Jun  6 14:21:02 UTC 2018 - [email protected]
+
+- Fixed possibly broken system after aborting upgrade running
+  over SSH (caused by a partially finished rollback) (bsc#1089643)
+
+-------------------------------------------------------------------
+Thu May 31 15:31:34 UTC 2018 - [email protected]
+
+- fix calling copy_files_finish to not crash
+  (related to bsc#1095323)
+- 4.1.1
+
+-------------------------------------------------------------------
+Thu May 31 10:17:19 UTC 2018 - [email protected]
+
+- Fix crash caused by previous fix when multipath is not available
+  (bsc#1095323)
+- Copy active_devices.txt for s390 to prevent blocking of
+  important devices when cio_ignore is active (bsc#1095033)
+- 4.1.0
+
+-------------------------------------------------------------------
 Fri May 18 13:16:30 UTC 2018 - [email protected]
 
 - Fix installation mode detection (related to bsc#1089547).
@@ -17,7 +47,7 @@
 
 - Log a warning when umounting a filesystem fails after
   installation/upgrade (related to bsc#1090018).
-- 4.0.59 
+- 4.0.59
 
 -------------------------------------------------------------------
 Tue May 08 12:04:00 CEST 2018 - [email protected]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-4.0.61/package/yast2-installation.spec 
new/yast2-installation-4.1.2/package/yast2-installation.spec
--- old/yast2-installation-4.0.61/package/yast2-installation.spec       
2018-05-18 15:55:42.000000000 +0200
+++ new/yast2-installation-4.1.2/package/yast2-installation.spec        
2018-06-12 17:30:05.000000000 +0200
@@ -16,7 +16,7 @@
 #
 
 Name:           yast2-installation
-Version:        4.0.61
+Version:        4.1.2
 Release:        0
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-4.0.61/src/clients/copy_files_finish.rb 
new/yast2-installation-4.1.2/src/clients/copy_files_finish.rb
--- old/yast2-installation-4.0.61/src/clients/copy_files_finish.rb      
2018-05-18 15:55:42.000000000 +0200
+++ new/yast2-installation-4.1.2/src/clients/copy_files_finish.rb       
2018-06-12 17:30:05.000000000 +0200
@@ -1,2 +1,2 @@
 require "installation/clients/copy_files_finish"
-Yast::CopyFilesFinishClient.new.main
+Yast::CopyFilesFinishClient.run
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-4.0.61/src/include/installation/misc.rb 
new/yast2-installation-4.1.2/src/include/installation/misc.rb
--- old/yast2-installation-4.0.61/src/include/installation/misc.rb      
2018-05-18 15:55:42.000000000 +0200
+++ new/yast2-installation-4.1.2/src/include/installation/misc.rb       
2018-06-12 17:30:05.000000000 +0200
@@ -58,76 +58,6 @@
       @modules_to_enable_with_AC_on = nil
     end
 
-    # Function appends blacklisted modules to the 
/etc/modprobe.d/50-blacklist.conf
-    # file.
-    #
-    # More information in bugzilla #221815 and #485980
-    def AdjustModprobeBlacklist
-      # check whether we need to run it
-      brokenmodules = Linuxrc.InstallInf("BrokenModules")
-      if brokenmodules == "" || brokenmodules.nil?
-        Builtins.y2milestone("No BrokenModules in install.inf, skipping...")
-        return
-      end
-
-      # comma-separated list of modules
-      blacklisted_modules = Builtins.splitstring(brokenmodules, ", ")
-
-      # run before SCR switch
-      blacklist_file = Ops.add(
-        Installation.destdir,
-        "/etc/modprobe.d/50-blacklist.conf"
-      )
-
-      # read the content
-      content = ""
-      if FileUtils.Exists(blacklist_file)
-        content = Convert.to_string(
-          SCR.Read(path(".target.string"), blacklist_file)
-        )
-        if content.nil?
-          Builtins.y2error("Cannot read %1 file", blacklist_file)
-          content = ""
-        end
-      else
-        Builtins.y2warning(
-          "File %1 does not exist, installation will create new one",
-          blacklist_file
-        )
-      end
-
-      # creating new entries with comment
-      blacklist_file_added = "# Note: Entries added during installation/update 
(Bug 221815)\n"
-      Builtins.foreach(blacklisted_modules) do |blacklisted_module|
-        blacklist_file_added = Ops.add(
-          blacklist_file_added,
-          Builtins.sformat("blacklist %1\n", blacklisted_module)
-        )
-      end
-
-      # newline if the file is not empty
-      content = Ops.add(
-        Ops.add(content, content != "" ? "\n\n" : ""),
-        blacklist_file_added
-      )
-
-      Builtins.y2milestone(
-        "Blacklisting modules: %1 in %2",
-        blacklisted_modules,
-        blacklist_file
-      )
-      if !SCR.Write(path(".target.string"), blacklist_file, content)
-        Builtins.y2error("Cannot write into %1 file", blacklist_file)
-      else
-        Builtins.y2milestone(
-          "Changes into file %1 were written successfully",
-          blacklist_file
-        )
-      end
-
-      nil
-    end
-
     def InjectFile(filename)
       command = "/bin/cp #{filename} #{Installation.destdir}#{filename}"
       Builtins.y2milestone("InjectFile: <%1>", filename)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-4.0.61/src/lib/installation/clients/copy_files_finish.rb 
new/yast2-installation-4.1.2/src/lib/installation/clients/copy_files_finish.rb
--- 
old/yast2-installation-4.0.61/src/lib/installation/clients/copy_files_finish.rb 
    2018-05-18 15:55:42.000000000 +0200
+++ 
new/yast2-installation-4.1.2/src/lib/installation/clients/copy_files_finish.rb  
    2018-06-12 17:30:05.000000000 +0200
@@ -19,313 +19,165 @@
 # current contact information at www.novell.com.
 # 
------------------------------------------------------------------------------
 
-# File:
-#  copy_files_finish.ycp
-#
-# Module:
-#  Step of base installation finish
-#
-# Authors:
-#  Jiri Srain <[email protected]>
-#
 require "fileutils"
 require "installation/ssh_importer"
+require "installation/finish_client"
 
-module Yast
-  class CopyFilesFinishClient < Client
-    include Yast::Logger
+Yast.import "Pkg"
+Yast.import "Arch"
+Yast.import "Linuxrc"
+Yast.import "Installation"
+Yast.import "Directory"
+Yast.import "Mode"
+Yast.import "Packages"
+Yast.import "ProductControl"
+Yast.import "ProductProfile"
+Yast.import "String"
+Yast.import "WorkflowManager"
+Yast.import "SystemFilesCopy"
+Yast.import "InstFunctions"
 
-    def main
-      Yast.import "Pkg"
-      Yast.import "UI"
+module Yast
+  # Step of base installation finish including mainly files to copy from 
insts-sys to target system
+  # @note This client expect that SCR is not yet switched.
+  #   Expect the hell to be frozen if you call it with switched SCR.
+  class CopyFilesFinishClient < ::Installation::FinishClient
+    include Yast::I18n
 
+    def initialize
       textdomain "installation"
+    end
 
-      Yast.import "AddOnProduct"
-      Yast.import "Linuxrc"
-      Yast.import "Installation"
-      Yast.import "Directory"
-      Yast.import "Mode"
-      Yast.import "Packages"
-      Yast.import "ProductControl"
-      Yast.import "ProductProfile"
-      Yast.import "FileUtils"
-      Yast.import "String"
-      Yast.import "WorkflowManager"
-      Yast.import "SystemFilesCopy"
-      Yast.import "ProductFeatures"
-      Yast.import "InstFunctions"
-
-      Yast.include self, "installation/misc.rb"
-
-      @ret = nil
-      @func = ""
-      @param = {}
-
-      # Check arguments
-      if Ops.greater_than(Builtins.size(WFM.Args), 0) &&
-          Ops.is_string?(WFM.Args(0))
-        @func = Convert.to_string(WFM.Args(0))
-        if Ops.greater_than(Builtins.size(WFM.Args), 1) &&
-            Ops.is_map?(WFM.Args(1))
-          @param = Convert.to_map(WFM.Args(1))
-        end
-      end
-
-      Builtins.y2milestone("starting copy_files_finish")
-      Builtins.y2debug("func=%1", @func)
-      Builtins.y2debug("param=%1", @param)
-
-      if @func == "Info"
-        return {
-          "steps" => 1,
-          # progress step title
-          "title" => _(
-            "Copying files to installed system..."
-          ),
-          "when"  => [:installation, :update, :autoinst]
-        }
-      elsif @func == "Write"
-        # bugzilla #221815 and #485980
-        # Adding blacklisted modules into the /etc/modprobe.d/50-blacklist.conf
-        # This should run before the SCR::switch function
-        AdjustModprobeBlacklist()
+    def modes
+      [:installation, :update, :autoinst]
+    end
 
-        # copy hardware status to installed system
-        Builtins.y2milestone("Copying hardware information")
-        WFM.Execute(
-          path(".local.bash"),
-          Builtins.sformat(
-            # BNC #596938: Files / dirs might be symlinks
-            "mkdir -p '%1/var/lib/'; /bin/cp -a --recursive --dereference 
'/var/lib/hardware' '%1/var/lib/'",
-            String.Quote(Installation.destdir)
-          )
-        )
+    def title
+      _("Copying files to installed system...")
+    end
 
-        # if VNC, copy setup data
-        if Linuxrc.vnc
-          Builtins.y2milestone("Copying VNC settings")
-          WFM.Execute(
-            path(".local.bash"),
-            Builtins.sformat(
-              "/bin/cp -a '/root/.vnc' '%1/root/'",
-              String.Quote(Installation.destdir)
-            )
-          )
-        end
+    # @raise RuntimeError if called with switched SCR to have defined behavior 
and prevent
+    #   accidental overwrite and data loss
+    def write
+      if Yast::WFM.scr_chrooted?
+        raise "Calling CopyFilesFinish client with SCR switched to 
#{Yast::WFM.scr_root}"
+      end
+
+      # bugzilla #221815 and #485980
+      # Adding blacklisted modules into the /etc/modprobe.d/50-blacklist.conf
+      # This should run before the SCR::switch function
+      adjust_modprobe_blacklist
+
+      copy_hardware_status
+      copy_vnc
+      copy_multipath
+      # Copy cio_ignore whitelist (bsc#1095033)
+      copy_active_devices
+
+      handle_second_stage
+
+      # Copy control.xml so it can be read once again during continue mode
+      # FIXME: probably won't work as expected with new multimedia layout.
+      #   Ideally final modified control.xml should be saved.
+      copy_control_file
+      # Copy /media.1/build to the installed system (fate#311377)
+      copy_build_file
+      copy_product_profiles
+
+      # List of files used as additional workflow definitions
+      # TODO check if it is still needed
+      copy_all_workflow_files
+
+      # Copy files from inst-sys to the just installed system
+      # FATE #301937, items are defined in the control file
+      SystemFilesCopy.SaveInstSysContent
+
+      # bugzila #328126
+      # Copy 70-persistent-cd.rules ... if not updating
+      copy_hardware_udev_rules
+
+      # fate#319624
+      copy_ssh_files
+    end
 
-        # Copy multipath stuff (bnc#885628)
-        # Only in install, as update should keep its old config
-        if Mode.installation
-          multipath_config = "/etc/multipath/wwids"
-          if File.exist?(multipath_config)
-            log.info "Copying multipath blacklist '#{multipath_config}'"
-            target_path = File.join(Installation.destdir, multipath_config)
-            ::FileUtils.mkdir_p(File.dirname(target_path))
-            ::FileUtils.cp(multipath_config, target_path)
-          end
-        end
-
-        # --------------------------------------------------------------
-        # Copy /etc/install.inf into built system so that the
-        # second phase of the installation can find it.
-        if InstFunctions.second_stage_required?
-          Linuxrc.SaveInstallInf(Installation.destdir)
-        else
-          SCR.Execute(path(".target.remove"), "/etc/install.inf")
-        end
+  private
 
-        # Copy control.xml so it can be read once again during continue mode
-        Builtins.y2milestone("Copying YaST control file")
+    def copy_product_profiles
+      all_profiles = ProductProfile.all_profiles
+      # copy all product profiles to the installed system (fate#310730)
+      return if all_profiles.empty?
+
+      target_dir = File.join(Installation.destdir, "/etc/productprofiles.d")
+      ::FileUtils.mkdir_p(target_dir)
+      all_profiles.each do |profile_path|
+        log.info "Copying '#{profile_path}' to #{target_dir}"
         WFM.Execute(
           path(".local.bash"),
           Builtins.sformat(
-            "/bin/cp '%1' '%2%3/control.xml' && /bin/chmod 0644 
'%2%3/control.xml'",
-            String.Quote(ProductControl.current_control_file),
-            String.Quote(Installation.destdir),
-            String.Quote(Directory.etcdir)
+            "/bin/cp -a '%1' '%2/'",
+            String.Quote(profile_path),
+            String.Quote(target_dir)
           )
         )
-
-        # Copy /media.1/build to the installed system (fate#311377)
-        @src_id = Packages.GetBaseSourceID
-        @build_file = Pkg.SourceProvideOptionalFile(
-          @src_id,
-          1,
-          "/media.1/build"
-        )
-        if !@build_file.nil?
-          Builtins.y2milestone("Copying /media.1/build file")
-          WFM.Execute(
-            path(".local.bash"),
-            Builtins.sformat(
-              "/bin/cp '%1' '%2%3/' && /bin/chmod 0644 '%2%3/build'",
-              String.Quote(@build_file),
-              String.Quote(Installation.destdir),
-              String.Quote(Directory.etcdir)
-            )
-          )
-        end
-
-        # copy all product profiles to the installed system (fate#310730)
-        if ProductProfile.all_profiles != []
-          @target_dir = Builtins.sformat(
-            "%1/etc/productprofiles.d",
-            Installation.destdir
-          )
-          if !FileUtils.Exists(@target_dir)
-            SCR.Execute(path(".target.mkdir"), @target_dir)
-          end
-          Builtins.foreach(ProductProfile.all_profiles) do |profile_path|
-            Builtins.y2milestone(
-              "Copying '%1' to %2/",
-              profile_path,
-              @target_dir
-            )
-            WFM.Execute(
-              path(".local.bash"),
-              Builtins.sformat(
-                "/bin/cp -a '%1' '%2/'",
-                String.Quote(profile_path),
-                String.Quote(@target_dir)
-              )
-            )
-          end
-        end
-
-        # List of files used as additional workflow definitions
-        CopyAllWorkflowFiles()
-
-        # Copy files from inst-sys to the just installed system
-        # FATE #301937, items are defined in the control file
-        SystemFilesCopy.SaveInstSysContent
-
-        # bugzila #328126
-        # Copy 70-persistent-cd.rules ... if not updating
-        CopyHardwareUdevRules() if !Mode.update
-
-        # fate#319624
-        copy_ssh_files
-      else
-        Builtins.y2error("unknown function: %1", @func)
-        @ret = nil
       end
+    end
 
-      Builtins.y2debug("ret=%1", @ret)
-      Builtins.y2milestone("copy_files_finish finished")
-      deep_copy(@ret)
+    def copy_hardware_status
+      log.info "Copying hardware information"
+      destdir = ::File.join(installation_destination, "/var/lib")
+      ::FileUtils.mkdir_p(destdir)
+      WFM.Execute(
+        path(".local.bash"),
+        Builtins.sformat(
+          # BNC #596938: Files / dirs might be symlinks
+          "/bin/cp -a --recursive --dereference '/var/lib/hardware' '%1'",
+          ::Yast::String.Quote(destdir)
+        )
+      )
     end
 
-    def CopyAllWorkflowFiles
-      if Builtins.size(WorkflowManager.GetAllUsedControlFiles) == 0
-        Builtins.y2milestone("No additional workflows")
+    def copy_all_workflow_files
+      control_files = WorkflowManager.GetAllUsedControlFiles
+      if !control_files || control_files.empty?
+        log.info "No additional workflows"
         return
       end
 
-      Builtins.y2milestone(
-        "Coping additional control files %1",
-        WorkflowManager.GetAllUsedControlFiles
-      )
-      workflows_list = []
-
-      Builtins.foreach(WorkflowManager.GetAllUsedControlFiles) do 
|one_filename|
-        if Builtins.regexpmatch(one_filename, "/")
-          one_filename = Builtins.regexpsub(one_filename, "^.*/(.*)", "\\1")
-        end
-        workflows_list = Builtins.add(workflows_list, one_filename)
+      log.info "Copying additional control files #{control_files.inspect}"
+      workflows_list = control_files.map do |one_filename|
+        ::File.basename(one_filename)
       end
 
       # Remove the directory with all additional control files (if exists)
       # and create it again (empty). BNC #471454
-      SCR.Execute(
-        path(".target.bash"),
-        Builtins.sformat(
-          "rm -rf '%1'; /bin/mkdir -p '%1'",
-          String.Quote(
-            Ops.add(
-              Ops.add(Installation.destdir, Directory.etcdir),
-              "/control_files"
-            )
-          )
-        )
-      )
+      control_files_directory = ::File.join(installation_destination, 
Directory.etcdir, "control_files")
+      ::FileUtils.rm_rf(control_files_directory)
+      ::FileUtils.mkdir_p(control_files_directory)
 
       # BNC #475516: Writing the control-files-order index 'after' removing 
the directory
       # Control files need to follow the exact order, only those liseted here 
are used
-      SCR.Write(
+      order_file = ::File.join(control_files_directory, "order.ycp")
+      Yast::SCR.Write(
         path(".target.ycp"),
-        Ops.add(
-          Ops.add(Installation.destdir, Directory.etcdir),
-          "/control_files/order.ycp"
-        ),
+        order_file,
         workflows_list
       )
-      SCR.Execute(
-        path(".target.bash"),
-        Ops.add(
-          Ops.add(
-            Ops.add(
-              "/bin/chmod 0644 " + "'",
-              String.Quote(Installation.destdir)
-            ),
-            Directory.etcdir
-          ),
-          "/control_files/order.ycp'"
-        )
-      )
+      ::FileUtils.chmod(0o644, ::File.join(order_file))
 
       # Now copy all the additional control files to the just installed system
-      Builtins.foreach(WorkflowManager.GetAllUsedControlFiles) do |file|
-        SCR.Execute(
-          path(".target.bash"),
-          Ops.add(
-            Ops.add(
-              Ops.add(
-                Ops.add(
-                  Ops.add(Ops.add("/bin/cp '", String.Quote(file)), "' "),
-                  "'"
-                ),
-                String.Quote(Installation.destdir)
-              ),
-              Directory.etcdir
-            ),
-            "/control_files/'"
-          )
-        )
-        SCR.Execute(
-          path(".target.bash"),
-          Ops.add(
-            Ops.add(
-              Ops.add(
-                Ops.add(
-                  Ops.add(
-                    "/bin/chmod 0644 " + "'",
-                    String.Quote(Installation.destdir)
-                  ),
-                  Directory.etcdir
-                ),
-                "/control_files/"
-              ),
-              String.Quote(file)
-            ),
-            "'"
-          )
-        )
+      control_files.each do |file|
+        ::FileUtils.cp(file, control_files_directory)
+        ::FileUtils.chmod(0o644, ::File.join(control_files_directory, 
::File.basename(file)))
       end
-
-      nil
     end
 
     UDEV_RULES_DIR = "/etc/udev/rules.d".freeze
 
     # see bugzilla #328126
-    def CopyHardwareUdevRules
-      udev_rules_destdir = File.join(Installation.destdir, UDEV_RULES_DIR)
-
-      if !FileUtils.Exists(udev_rules_destdir)
-        log.info "Directory #{udev_rules_destdir} does not exist yet, creating 
it"
-        WFM.Execute(path(".local.bash"), "mkdir -p #{udev_rules_destdir}")
-      end
+    def copy_hardware_udev_rules
+      return if Mode.update
+      udev_rules_destdir = ::File.join(installation_destination, 
UDEV_RULES_DIR)
+      ::FileUtils.mkdir_p(udev_rules_destdir)
 
       # Copy all udev files, but do not overwrite those that already exist
       # on the system bnc#860089
@@ -334,17 +186,134 @@
       log.info "Copying all udev rules from #{UDEV_RULES_DIR} to 
#{udev_rules_destdir}"
       cmd_out = WFM.Execute(path(".local.bash_output"), cmd)
 
-      log.error "Error copying udev rules" if cmd_out["exit"] != 0
-
-      nil
+      log.error "Error copying udev rules with #{cmd_out.inspect}" if 
cmd_out["exit"] != 0
     end
 
     def copy_ssh_files
       log.info "Copying SSH keys and config files"
-      ::Installation::SshImporter.instance.write(Installation.destdir)
+      ::Installation::SshImporter.instance.write(installation_destination)
+    end
+
+    # Function appends blacklisted modules to the 
/etc/modprobe.d/50-blacklist.conf
+    # file.
+    #
+    # More information in bugzilla #221815 and #485980
+    def adjust_modprobe_blacklist
+      # check whether we need to run it
+      brokenmodules = Linuxrc.InstallInf("BrokenModules")
+      if !brokenmodules || brokenmodules.empty?
+        log.info "No BrokenModules in install.inf, skipping..."
+        return
+      end
+
+      # comma-separated list of modules
+      blacklisted_modules = brokenmodules.split(", ")
+
+      # run before SCR switch
+      blacklist_file = ::File.join(
+        installation_destination,
+        "/etc/modprobe.d/50-blacklist.conf"
+      )
+
+      # read the content
+      content = ""
+      if ::File.exist?(blacklist_file)
+        content = ::File.read(blacklist_file)
+      else
+        log.warn "File #{blacklist_file} does not exist, installation will 
create new one"
+      end
+
+      # creating new entries with comment
+      blacklist_file_append = "# Note: Entries added during 
installation/update (Bug 221815)\n"
+      blacklisted_modules.each do |blacklisted_module|
+        blacklist_file_append << "blacklist #{blacklisted_module}\n"
+      end
+
+      # newline if the file is not empty
+      content << "\n\n" unless content.empty?
+      content << blacklist_file_append
+
+      log.info "Blacklisting modules: #{blacklisted_modules} in 
#{blacklist_file}"
+      ::File.write(blacklist_file, content)
+    end
+
+    def installation_destination
+      ::Yast::Installation.destdir
     end
 
-    # Prevent from re-defining client class
-    # Re-defining would produce warnings that constants were already 
initialized
-  end unless defined? CopyFilesFinishClient
+    def copy_vnc
+      # if VNC, copy setup data
+      return unless Linuxrc.vnc
+
+      log.info "Copying VNC settings"
+      WFM.Execute(
+        path(".local.bash"),
+        Builtins.sformat(
+          "/bin/cp -a '/root/.vnc' '%1/root/'",
+          ::Yast::String.Quote(installation_destination)
+        )
+      )
+    end
+
+    def copy_multipath
+      # Copy multipath stuff (bnc#885628)
+      # Only in install, as update should keep its old config
+      return unless Mode.installation
+
+      multipath_config = "/etc/multipath/wwids"
+      if File.exist?(multipath_config)
+        log.info "Copying multipath blacklist '#{multipath_config}'"
+        target_path = File.join(Installation.destdir, multipath_config)
+        ::FileUtils.mkdir_p(File.dirname(target_path))
+        ::FileUtils.cp(multipath_config, target_path)
+      end
+    end
+
+    def copy_active_devices
+      # Only in install, as update should keep its old config
+      return unless Mode.installation
+      return unless Arch.s390
+
+      path = "/boot/zipl/active_devices.txt"
+      if File.exist?(path)
+        log.info "Copying zipl active devices '#{path}'"
+        target_path = File.join(Installation.destdir, path)
+        ::FileUtils.mkdir_p(File.dirname(target_path))
+        ::FileUtils.cp(path, target_path)
+      end
+    end
+
+    def handle_second_stage
+      # Copy /etc/install.inf into built system so that the
+      # second phase of the installation can find it.
+      if InstFunctions.second_stage_required?
+        Linuxrc.SaveInstallInf(Installation.destdir)
+      else
+        # TODO: write why it is needed
+        ::FileUtils.rm "/etc/install.inf"
+      end
+    end
+
+    def copy_control_file
+      log.info "Copying YaST control file"
+      destination = File.join(Installation.destdir, Directory.etcdir, 
"control.xml")
+      ::FileUtils.cp(ProductControl.current_control_file, destination)
+      ::FileUtils.chmod(0o644, destination)
+    end
+
+    def copy_build_file
+      build_file = Pkg.SourceProvideOptionalFile(
+        Packages.GetBaseSourceID,
+        1,
+        "/media.1/build"
+      )
+
+      return unless build_file
+
+      log.info "Copying /media.1/build file"
+      destination = File.join(Installation.destdir, Directory.etcdir, "build")
+      ::FileUtils.cp(build_file, destination)
+      ::FileUtils.chmod(0o644, destination)
+    end
+  end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-4.0.61/src/lib/installation/clients/inst_congratulate.rb 
new/yast2-installation-4.1.2/src/lib/installation/clients/inst_congratulate.rb
--- 
old/yast2-installation-4.0.61/src/lib/installation/clients/inst_congratulate.rb 
    2018-05-18 15:55:42.000000000 +0200
+++ 
new/yast2-installation-4.1.2/src/lib/installation/clients/inst_congratulate.rb  
    2018-06-12 17:30:05.000000000 +0200
@@ -233,6 +233,10 @@
 
       Wizard.SetNextButton(:next, Label.FinishButton)
       Wizard.RestoreAbortButton
+      # At this point the configuration is already applied and aborting doesn't
+      # make sense at all, at least for firstboot. For that reason we will
+      # hide the option (bsc#1095253)
+      Wizard.HideAbortButton if Stage.firstboot
       Wizard.SetFocusToNextButton
       if UI.WidgetExists(Id(:do_clone))
         UI.ChangeWidget(Id(:do_clone), :Enabled, @clone_enabled)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-installation-4.0.61/startup/YaST2.call 
new/yast2-installation-4.1.2/startup/YaST2.call
--- old/yast2-installation-4.0.61/startup/YaST2.call    2018-05-18 
15:55:42.000000000 +0200
+++ new/yast2-installation-4.1.2/startup/YaST2.call     2018-06-12 
17:30:05.000000000 +0200
@@ -358,10 +358,6 @@
                start_yast_and_reboot
                start_yast_again
        fi
-       if [ $SELECTED_MEDIUM = "SSH" ] && [ ! "$VNC" = 1 ];then
-               ssh_reboot_message
-               echo $Y2_EXIT_CODE > /tmp/YaST2_ssh_installation_finished
-       fi
        log "\tReset memory allocation: overcommit_memory=$overcommit"
        echo $overcommit > /proc/sys/vm/overcommit_memory
 }
@@ -667,6 +663,14 @@
         grep -q -i -v -e "^Aborted:" -e "^Root:" /etc/yast.inf && 
restore_backup
 fi
 
+if [ $SELECTED_MEDIUM = "SSH" ] && [ ! "$VNC" = 1 ];then
+       ssh_reboot_message
+       # the inst-sys is waiting for the /tmp/YaST2_ssh_installation_finished 
file and
+       # when found the ssh daemon is killed, so create this file as the very 
last step!!
+       # 
(https://github.com/openSUSE/installation-images/blob/c57181329ab7040369da705c5b0ddd78e2960bf0/data/root/etc/inst_setup#L221-L229)
+       echo $Y2_EXIT_CODE > /tmp/YaST2_ssh_installation_finished
+fi
+
 #=============================================
 # 10) exit with YaST2 exit code
 #---------------------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-4.0.61/test/copy_files_finish_test.rb 
new/yast2-installation-4.1.2/test/copy_files_finish_test.rb
--- old/yast2-installation-4.0.61/test/copy_files_finish_test.rb        
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-4.1.2/test/copy_files_finish_test.rb 2018-06-12 
17:30:05.000000000 +0200
@@ -0,0 +1,243 @@
+require_relative "./test_helper.rb"
+
+require "installation/clients/copy_files_finish"
+
+describe Yast::CopyFilesFinishClient do
+  describe "#modes" do
+    it "defines that it runs in installation" do
+      expect(subject.modes).to include(:installation)
+    end
+
+    it "defines that it runs in update" do
+      expect(subject.modes).to include(:update)
+    end
+
+    it "defines that it runs in autoinstallation" do
+      expect(subject.modes).to include(:autoinst)
+    end
+  end
+
+  describe "#title" do
+    it "returns string with localized title" do
+      expect(subject.title).to be_a(::String)
+    end
+  end
+
+  describe "#write" do
+    before do
+      # ensure that nothing will be written to system
+      stub_const("::FileUtils", double.as_null_object)
+      stub_const("::Yast::SCR", double.as_null_object)
+      stub_const("::Yast::WFM", double.as_null_object)
+      allow(::Yast::WFM).to receive(:scr_chrooted?).and_return(false)
+      allow(Yast::Installation).to receive(:destdir).and_return("/mnt")
+      allow(::File).to receive(:exist?).and_return(false)
+      allow(::File).to receive(:read).and_return("")
+      allow(::File).to receive(:write)
+      allow(Yast::Linuxrc).to receive(:InstallInf)
+      allow(Yast::Packages).to receive(:GetBaseSourceID).and_return(1)
+      allow(::Installation::SshImporter).to 
receive(:instance).and_return(double.as_null_object)
+    end
+
+    it "raises RuntimeError if called with switched SCR" do
+      allow(::Yast::WFM).to receive(:scr_chrooted?).and_return(true)
+      allow(::Yast::WFM).to receive(:scr_root).and_return("/tmp")
+
+      expect { subject.write }.to raise_error(RuntimeError)
+    end
+
+    let(:blacklist_file) { "/mnt/etc/modprobe.d/50-blacklist.conf" }
+    it "appends modules blacklisted in linuxrc to target system blacklist" do
+      allow(Yast::Linuxrc).to 
receive(:InstallInf).with("BrokenModules").and_return("moduleA, moduleB")
+      allow(::File).to receive(:exist?).with(blacklist_file).and_return(true)
+      expect(::File).to receive(:read).with(blacklist_file).and_return("First 
Line")
+      expect(::File).to receive(:write).with(blacklist_file, String) do 
|_path, content|
+        expect(content).to match(/# Note: Entries added during 
installation\/update/)
+        expect(content).to match(/blacklist moduleA/)
+        expect(content).to match(/blacklist moduleB/)
+      end
+
+      subject.write
+    end
+
+    it "creates blacklist file if target system does not contain it" do
+      allow(Yast::Linuxrc).to 
receive(:InstallInf).with("BrokenModules").and_return("moduleA, moduleB")
+      allow(::File).to receive(:exist?).with(blacklist_file).and_return(false)
+
+      expect(::File).to_not receive(:read)
+      expect(::File).to receive(:write).with(blacklist_file, String) do 
|_path, content|
+        expect(content).to_not match(/^$/) # no empty lines
+        expect(content).to match(/# Note: Entries added during 
installation\/update/)
+        expect(content).to match(/blacklist moduleA/)
+        expect(content).to match(/blacklist moduleB/)
+      end
+
+      subject.write
+    end
+
+    it "copies information about hardware status" do
+      expect(::FileUtils).to receive(:mkdir_p).with("/mnt/var/lib")
+      expect(Yast::WFM).to receive(:Execute).with(path(".local.bash"), 
/cp.*\/var\/lib\/hardware/)
+
+      subject.write
+    end
+
+    it "copies VNC setup data when VNC installation is used" do
+      allow(Yast::Linuxrc).to receive(:vnc).and_return(true)
+
+      expect(Yast::WFM).to receive(:Execute).with(path(".local.bash"), 
/cp.*\/root\/.vnc/)
+
+      subject.write
+    end
+
+    it "copies multipath stuff in installation only" do
+      allow(Yast::Mode).to receive(:installation).and_return(true)
+      allow(::FileUtils).to receive(:cp)
+      allow(::FileUtils).to receive(:mkdir_p)
+      allow(::File).to 
receive(:exist?).with("/etc/multipath/wwids").and_return(true)
+
+      expect(::FileUtils).to receive(:mkdir_p).with("/mnt/etc/multipath")
+      expect(::FileUtils).to receive(:cp).with("/etc/multipath/wwids", 
"/mnt/etc/multipath/wwids")
+
+      subject.write
+    end
+
+    it "copies cio_ignore whitelist in installation of s390 only" do
+      allow(Yast::Mode).to receive(:installation).and_return(true)
+      allow(Yast::Arch).to receive(:architecture).and_return("s390_64")
+      allow(::FileUtils).to receive(:cp)
+      allow(::FileUtils).to receive(:mkdir_p)
+      allow(::File).to 
receive(:exist?).with("/boot/zipl/active_devices.txt").and_return(true)
+
+      expect(::FileUtils).to receive(:mkdir_p).with("/mnt/boot/zipl")
+      expect(::FileUtils).to 
receive(:cp).with("/boot/zipl/active_devices.txt", 
"/mnt/boot/zipl/active_devices.txt")
+
+      subject.write
+    end
+
+    it "saves install.inf if second stage is required" do
+      allow(Yast::InstFunctions).to 
receive(:second_stage_required?).and_return(true)
+
+      expect(Yast::Linuxrc).to receive(:SaveInstallInf).with("/mnt")
+
+      subject.write
+    end
+
+    it "deletes install.inf if second stage is not required" do
+      allow(Yast::InstFunctions).to 
receive(:second_stage_required?).and_return(false)
+
+      expect(::FileUtils).to receive(:rm).with("/etc/install.inf")
+
+      subject.write
+    end
+
+    it "copies control.xml" do
+      allow(::FileUtils).to receive(:cp)
+      allow(Yast::ProductControl).to 
receive(:current_control_file).and_return("/control.xml")
+
+      expect(::FileUtils).to receive(:cp).with("/control.xml", 
"/mnt/etc/YaST2/control.xml")
+
+      subject.write
+    end
+
+    it "ensures proper permission on copied control.xml" do
+      allow(Yast::ProductControl).to 
receive(:current_control_file).and_return("/control.xml")
+
+      expect(::FileUtils).to receive(:chmod).with(0o644, 
"/mnt/etc/YaST2/control.xml")
+
+      subject.write
+    end
+
+    it "copies build file" do
+      allow(Yast::Pkg).to receive(:SourceProvideOptionalFile).with(1, 1, 
"/media.1/build")
+        .and_return("/media.1/build")
+
+      expect(::FileUtils).to receive(:cp).with("/media.1/build", 
"/mnt/etc/YaST2/build")
+
+      subject.write
+    end
+
+    it "ensures proper permission on copied build file" do
+      allow(Yast::Pkg).to receive(:SourceProvideOptionalFile).with(1, 1, 
"/media.1/build")
+        .and_return("/media.1/build")
+
+      expect(::FileUtils).to receive(:chmod).with(0o644, 
"/mnt/etc/YaST2/build")
+
+      subject.write
+    end
+
+    it "copies all product profiles" do
+      allow(Yast::ProductProfile).to 
receive(:all_profiles).and_return(["/product1.xml", "/product2.xml"])
+      allow(::FileUtils).to receive(:mkdir_p)
+
+      expect(::FileUtils).to 
receive(:mkdir_p).with("/mnt/etc/productprofiles.d")
+      expect(::Yast::WFM).to receive(:Execute).with(path(".local.bash"), 
/cp.*\/product1.xml/)
+      expect(::Yast::WFM).to receive(:Execute).with(path(".local.bash"), 
/cp.*\/product2.xml/)
+
+      subject.write
+    end
+
+    it "copies all used control files" do
+      allow(Yast::WorkflowManager).to 
receive(:GetAllUsedControlFiles).and_return(["/control.xml", 
"/addon/addon.xml"])
+
+      expect(::FileUtils).to 
receive(:rm_rf).with("/mnt/etc/YaST2/control_files")
+      expect(::FileUtils).to 
receive(:mkdir_p).with("/mnt/etc/YaST2/control_files")
+
+      expect(::FileUtils).to receive(:cp).with("/control.xml", 
"/mnt/etc/YaST2/control_files")
+      expect(::FileUtils).to receive(:cp).with("/addon/addon.xml", 
"/mnt/etc/YaST2/control_files")
+
+      subject.write
+    end
+
+    it "ensures proper permissions of copied used control files" do
+      allow(Yast::WorkflowManager).to 
receive(:GetAllUsedControlFiles).and_return(["/control.xml", 
"/addon/addon.xml"])
+
+      expect(::FileUtils).to receive(:chmod).with(0o644, 
"/mnt/etc/YaST2/control_files/control.xml")
+      expect(::FileUtils).to receive(:chmod).with(0o644, 
"/mnt/etc/YaST2/control_files/addon.xml")
+
+      subject.write
+    end
+
+    it "writes order of control files to order.ycp" do
+      allow(Yast::WorkflowManager).to 
receive(:GetAllUsedControlFiles).and_return(["/control.xml", 
"/addon/addon.xml"])
+
+      expect(Yast::SCR).to receive(:Write).with(
+        path(".target.ycp"),
+        "/mnt/etc/YaST2/control_files/order.ycp",
+        ["control.xml", "addon.xml"]
+      )
+
+      subject.write
+    end
+
+    it "ensures proper permission for order.ycp" do
+      allow(Yast::WorkflowManager).to 
receive(:GetAllUsedControlFiles).and_return(["/control.xml", 
"/addon/addon.xml"])
+
+      expect(::FileUtils).to receive(:chmod).with(0o644, 
"/mnt/etc/YaST2/control_files/order.ycp")
+
+      subject.write
+    end
+
+    it "save insts-sys content specified in control file" do
+      expect(Yast::SystemFilesCopy).to receive(:SaveInstSysContent)
+
+      subject.write
+    end
+
+    it "copies udev rules in installation" do
+      allow(Yast::Mode).to receive(:update).and_return(false)
+
+      expect(::FileUtils).to receive(:mkdir_p).with("/mnt/etc/udev/rules.d")
+      expect(::Yast::WFM).to 
receive(:Execute).with(path(".local.bash_output"), /cp.*\/etc\/udev\/rules.d/)
+        .and_return("exit" => 0)
+
+      subject.write
+    end
+
+    it "copies ssh files" do
+      expect(::Installation::SshImporter.instance).to 
receive(:write).with("/mnt")
+
+      subject.write
+    end
+  end
+end


Reply via email to