Hello community,

here is the log from the commit of package yast2-installation for 
openSUSE:Factory checked in at 2017-01-23 11:26:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-installation (Old)
 and      /work/SRC/openSUSE:Factory/.yast2-installation.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yast2-installation"

Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-installation/yast2-installation.changes    
2017-01-10 10:34:27.547698315 +0100
+++ 
/work/SRC/openSUSE:Factory/.yast2-installation.new/yast2-installation.changes   
    2017-01-23 11:26:42.732717382 +0100
@@ -1,0 +2,21 @@
+Tue Jan 17 15:34:22 UTC 2017 - [email protected]
+
+- Do not retry to download release notes if a previous attempt
+  failed (bsc#1015794)
+- 3.2.15
+
+-------------------------------------------------------------------
+Mon Jan 16 12:42:52 UTC 2017 - [email protected]
+
+- add ability to roles to enable list of services when selected
+  (FATE#321754)
+
+-------------------------------------------------------------------
+Mon Jan 16 12:17:38 UTC 2017 - [email protected]
+
+- fate#321739
+  - Made user's interaction possible in case of error in read-only
+    proposal.
+- 3.2.14
+
+-------------------------------------------------------------------

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

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

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

Other differences:
------------------
++++++ yast2-installation.spec ++++++
--- /var/tmp/diff_new_pack.gc6M5u/_old  2017-01-23 11:26:43.192652183 +0100
+++ /var/tmp/diff_new_pack.gc6M5u/_new  2017-01-23 11:26:43.196651616 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-installation
-Version:        3.2.13
+Version:        3.2.15
 Release:        0
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build

++++++ yast2-installation-3.2.13.tar.bz2 -> yast2-installation-3.2.15.tar.bz2 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-installation-3.2.13/.travis.yml 
new/yast2-installation-3.2.15/.travis.yml
--- old/yast2-installation-3.2.13/.travis.yml   2017-01-09 10:17:15.083803000 
+0100
+++ new/yast2-installation-3.2.15/.travis.yml   2017-01-18 11:09:49.192521000 
+0100
@@ -1,14 +1,11 @@
-language: cpp
-compiler:
-    - gcc
+sudo: required
+language: bash
+services:
+  - docker
+
 before_install:
-    # disable rvm, use system Ruby
-    - rvm reset
-    - wget 
https://raw.githubusercontent.com/yast/yast-devtools/master/travis-tools/travis_setup.sh
-    - sh ./travis_setup.sh -p "rake yast2-devtools yast2-testsuite 
yast2-core-dev yast2 yast2-network yast2-transfer yast2-users yast2-country" -g 
"rspec:3.3.0 yast-rake gettext rubocop:0.41.2 simplecov coveralls cheetah"
+  - docker build -t yast-installation-image .
 script:
-    - rake check:syntax
-    - rake check:pot
-    - rubocop
-    - COVERAGE=1 rake test:unit
-    - sudo rake install
+  # the "yast-travis-ruby" script is included in the base yastdevel/ruby image
+  # see https://github.com/yast/docker-yast-ruby/blob/master/yast-travis-ruby
+  - docker run -it -e TRAVIS=1 -e TRAVIS_JOB_ID="$TRAVIS_JOB_ID" 
yast-installation-image yast-travis-ruby
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-installation-3.2.13/Dockerfile 
new/yast2-installation-3.2.15/Dockerfile
--- old/yast2-installation-3.2.13/Dockerfile    1970-01-01 01:00:00.000000000 
+0100
+++ new/yast2-installation-3.2.15/Dockerfile    2017-01-18 11:09:49.192521000 
+0100
@@ -0,0 +1,3 @@
+FROM yastdevel/ruby
+COPY . /usr/src/app
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-installation-3.2.13/doc/control-file.md 
new/yast2-installation-3.2.15/doc/control-file.md
--- old/yast2-installation-3.2.13/doc/control-file.md   2017-01-09 
10:17:15.135803000 +0100
+++ new/yast2-installation-3.2.15/doc/control-file.md   2017-01-18 
11:09:49.196521000 +0100
@@ -98,7 +98,7 @@
 > Note that the control file is not an optional tool to help customize
 > installation, it is required during installation and without the file,
 > installation may fail or lead to unexpected results. Control file on 
 > installed
-> system located in `/etc/YaST2/control.xml` is owned by ${PRODUCT}-release
+> system located in `/etc/YaST2/control.xml` is owned by `${PRODUCT}-release`
 > package.
 
 During installation, *linuxrc* searches for a file named
@@ -554,6 +554,10 @@
 -   *clone\_install\_recommended\_default* - Default entry for
     "install_recommended" in created AutoYaST configuration file.
 
+-   *minimalistic_libzypp_config* - adjust the libzypp configuration
+    to reduce the amount of packages to install: only required
+    packages are considered, no documentation and no multiversion.
+
 Additionally, you can configure how updating of packages should be
 performed. The following options are available:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/package/yast2-installation.changes 
new/yast2-installation-3.2.15/package/yast2-installation.changes
--- old/yast2-installation-3.2.13/package/yast2-installation.changes    
2017-01-09 10:17:15.239803000 +0100
+++ new/yast2-installation-3.2.15/package/yast2-installation.changes    
2017-01-18 11:09:49.212521000 +0100
@@ -1,4 +1,25 @@
 -------------------------------------------------------------------
+Tue Jan 17 15:34:22 UTC 2017 - [email protected]
+
+- Do not retry to download release notes if a previous attempt
+  failed (bsc#1015794)
+- 3.2.15
+
+-------------------------------------------------------------------
+Mon Jan 16 12:42:52 UTC 2017 - [email protected]
+
+- add ability to roles to enable list of services when selected
+  (FATE#321754)
+
+-------------------------------------------------------------------
+Mon Jan 16 12:17:38 UTC 2017 - [email protected]
+
+- fate#321739
+  - Made user's interaction possible in case of error in read-only
+    proposal.
+- 3.2.14
+
+-------------------------------------------------------------------
 Thu Jan  5 13:16:08 CET 2017 - [email protected]
 
 - AutoYaST after second stage: Initialize tty1 in order to remove
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/package/yast2-installation.spec 
new/yast2-installation-3.2.15/package/yast2-installation.spec
--- old/yast2-installation-3.2.13/package/yast2-installation.spec       
2017-01-09 10:17:15.239803000 +0100
+++ new/yast2-installation-3.2.15/package/yast2-installation.spec       
2017-01-18 11:09:49.212521000 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-installation
-Version:        3.2.13
+Version:        3.2.15
 Release:        0
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/src/clients/services_finish.rb 
new/yast2-installation-3.2.15/src/clients/services_finish.rb
--- old/yast2-installation-3.2.13/src/clients/services_finish.rb        
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.2.15/src/clients/services_finish.rb        
2017-01-18 11:09:49.216521000 +0100
@@ -0,0 +1,3 @@
+require "installation/clients/services_finish"
+
+::Installation::Clients::ServicesFinish.run
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/src/lib/installation/clients/inst_download_release_notes.rb
 
new/yast2-installation-3.2.15/src/lib/installation/clients/inst_download_release_notes.rb
--- 
old/yast2-installation-3.2.13/src/lib/installation/clients/inst_download_release_notes.rb
   2017-01-09 10:17:15.455803000 +0100
+++ 
new/yast2-installation-3.2.15/src/lib/installation/clients/inst_download_release_notes.rb
   2017-01-18 11:09:49.224521000 +0100
@@ -29,6 +29,12 @@
   class InstDownloadReleaseNotesClient < Client
     include Yast::Logger
 
+    # When cURL returns one of those codes, the download won't be retried
+    # @see man curl
+    #  7 = Failed to connect to host.
+    # 28 = Operation timeout.
+    CURL_GIVE_UP_RETURN_CODES = [7, 28].freeze
+
     # Download all release notes mentioned in Product::relnotesurl_all
     #
     # @return true when successful
@@ -89,12 +95,18 @@
         url_base = url[0, pos]
         url_template = url_base + filename_templ
         log.info("URL template: #{url_base}")
-        [Language.language, Language.language[0..1], "en"].each do |lang|
+        [Language.language, Language.language[0..1], "en"].uniq.each do |lang|
           url = Builtins.sformat(url_template, lang)
           log.info("URL: #{url}")
           # Where we want to store the downloaded release notes
           filename = Builtins.sformat("%1/relnotes",
             SCR.Read(path(".target.tmpdir")))
+
+          if InstData.failed_release_notes.include?(url)
+            log.info("Skipping download of already failed release notes at 
#{url}")
+            next
+          end
+
           # download release notes now
           cmd = Builtins.sformat(
             "/usr/bin/curl --location --verbose --fail --max-time 300 
--connect-timeout 15  %1 '%2' --output '%3' > '%4/%5' 2>&1",
@@ -111,13 +123,12 @@
             InstData.release_notes[product["short_name"]] = 
SCR.Read(path(".target.string"), filename)
             InstData.downloaded_release_notes << product["short_name"]
             break
-          # exit codes (see "man curl"):
-          #  7 = Failed to connect to host.
-          # 28 = Operation timeout.
-          elsif ret == 7 || ret == 28
+          elsif CURL_GIVE_UP_RETURN_CODES.include?(ret)
             log.info "Communication with server for release notes download 
failed, skipping further attempts."
             InstData.stop_relnotes_download = true
             break
+          else
+            InstData.failed_release_notes << url
           end
         end
       end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/src/lib/installation/clients/inst_extrasources.rb 
new/yast2-installation-3.2.15/src/lib/installation/clients/inst_extrasources.rb
--- 
old/yast2-installation-3.2.13/src/lib/installation/clients/inst_extrasources.rb 
    2017-01-09 10:17:15.467803000 +0100
+++ 
new/yast2-installation-3.2.15/src/lib/installation/clients/inst_extrasources.rb 
    2017-01-18 11:09:49.224521000 +0100
@@ -245,7 +245,10 @@
     # Register the installation sources in offline mode (no network connection 
required).
     # The repository metadata will be downloaded by sw_single (or another yast 
module) when the repostory is enabled
     #
-    # @param list <map> list of the sources to register
+    # @param url_list [Array<Hash>] list of the sources to register. Following
+    #   keys are recognized with default in brackets:
+    #   "enabled" (false), "autorefresh" (true), "name" 
("alias"("baseurl"(""))),
+    #   "alias ("baseurl"("")), "baseurl" (["baseurls"]), "prod_dir", 
"priority"
     # @return [Array<Fixnum>] list of created source IDs
     def RegisterRepos(url_list)
       url_list = deep_copy(url_list)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/src/lib/installation/clients/inst_finish.rb 
new/yast2-installation-3.2.15/src/lib/installation/clients/inst_finish.rb
--- old/yast2-installation-3.2.13/src/lib/installation/clients/inst_finish.rb   
2017-01-09 10:17:15.471803000 +0100
+++ new/yast2-installation-3.2.15/src/lib/installation/clients/inst_finish.rb   
2017-01-18 11:09:49.224521000 +0100
@@ -388,7 +388,8 @@
         "save_hw_status",
         "users",
         "autoinst_scripts2",
-        "installation_settings"
+        "installation_settings",
+        "services"
       ].freeze
 
     def save_settings_steps
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/src/lib/installation/clients/inst_update_installer.rb
 
new/yast2-installation-3.2.15/src/lib/installation/clients/inst_update_installer.rb
--- 
old/yast2-installation-3.2.13/src/lib/installation/clients/inst_update_installer.rb
 2017-01-09 10:17:15.527803000 +0100
+++ 
new/yast2-installation-3.2.15/src/lib/installation/clients/inst_update_installer.rb
 2017-01-18 11:09:49.228521000 +0100
@@ -418,7 +418,7 @@
     # Ask the user about checking network configuration. If she/he accepts,
     # the `inst_lan` client will be launched.
     #
-    # @param url [URI] URL to show in the message
+    # @param reason [String] reason why user want to check his network 
configuration
     # @return [Boolean] true if the network configuration client was launched;
     #                   false if the network is not configured.
     def configure_network?(reason)
@@ -459,7 +459,7 @@
 
     # Return a message to be shown when the updates repo could not be probed
     #
-    # @param [URI,String] Repository URI
+    # @param url [URI,String] Repository URI
     # @return [String] Message including the repository URL
     #
     # @see #self_update_url
@@ -491,7 +491,7 @@
 
     # Store URL of registration server to be used by inst_scc client
     #
-    # @params [URI] Registration server URL.
+    # @param url [URI] Registration server URL.
     def store_registration_url(url)
       data = { "custom_url" => url.to_s }
       File.write(REGISTRATION_DATA_PATH, data.to_yaml)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/src/lib/installation/clients/services_finish.rb 
new/yast2-installation-3.2.15/src/lib/installation/clients/services_finish.rb
--- 
old/yast2-installation-3.2.13/src/lib/installation/clients/services_finish.rb   
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/yast2-installation-3.2.15/src/lib/installation/clients/services_finish.rb   
    2017-01-18 11:09:49.228521000 +0100
@@ -0,0 +1,17 @@
+require "installation/finish_client"
+require "installation/services"
+
+module Installation
+  module Clients
+    class ServicesFinish < ::Installation::FinishClient
+      def title
+        textdomain "installation"
+        _("Adapting system services ...")
+      end
+
+      def write
+        ::Installation::Services.write
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/src/lib/installation/driver_update.rb 
new/yast2-installation-3.2.15/src/lib/installation/driver_update.rb
--- old/yast2-installation-3.2.13/src/lib/installation/driver_update.rb 
2017-01-09 10:17:15.563803000 +0100
+++ new/yast2-installation-3.2.15/src/lib/installation/driver_update.rb 
2017-01-18 11:09:49.232521000 +0100
@@ -50,7 +50,7 @@
     class << self
       # Find driver updates in a given set of directories
       #
-      # @param dirs [Array<Pathname>,Pathname] Directories to search for 
driver updates
+      # @param update_dirs [Array<Pathname>,Pathname] Directories to search 
for driver updates
       # @return [Array<DriverUpdate>] Found driver updates
       def find(update_dirs)
         dirs = Array(update_dirs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/src/lib/installation/proposal_runner.rb 
new/yast2-installation-3.2.15/src/lib/installation/proposal_runner.rb
--- old/yast2-installation-3.2.13/src/lib/installation/proposal_runner.rb       
2017-01-09 10:17:15.591803000 +0100
+++ new/yast2-installation-3.2.15/src/lib/installation/proposal_runner.rb       
2017-01-18 11:09:49.232521000 +0100
@@ -323,8 +323,7 @@
 
     # Call a submodule's AskUser() function.
     #
-    # @param [String] submodule        name of the submodule's proposal 
dispatcher
-    # @param  has_next         force a "next" button even if the submodule 
would otherwise rename it
+    # @param [String] input passed link from proposal dispatcher
     # @return workflow_sequence see proposal-API.txt, or nil if the link 
cannot be handled
     #   (is read-only)
     def submod_ask_user(input)
@@ -365,6 +364,15 @@
       workflow_sequence
     end
 
+    # Checks if given proposal map contains an error report
+    #
+    # @param [Hash] proposal map as returned by make_proposal
+    # @return [Boolean] true if the map reports an issue in proposal
+    # @see ProposalClient#make_proposal
+    def proposal_failed?(proposal)
+      proposal && [:blocker, :fatal, 
:error].include?(proposal["warning_level"])
+    end
+
     def make_proposal(force_reset, language_changed)
       tab_to_switch = 999
       current_tab_affected = false
@@ -404,14 +412,14 @@
       make_proposal_callback = proc do |submod, prop_map|
         submodule_nr += 1
         Yast::UI.ChangeWidget(Id("pb_ip"), :Value, submodule_nr)
-        prop = html_header(submod)
+        force_rw = proposal_failed?(prop_map) && @store.soft_read_only?(submod)
+        prop = html_header(submod, force_rw: force_rw)
 
         # check if it is needed to switch to another tab
         # because of an error
         if Yast::Builtins.haskey(@mod2tab, submod)
           log.info "Mod2Tab: '#{@mod2tab[submod]}'"
-          warn_level = prop_map["warning_level"]
-          if [:blocker, :fatal, :error].include?(warn_level)
+          if proposal_failed?(prop_map)
             # bugzilla #237291
             # always switch to more detailed tab only
             # value 999 means to keep current tab, in case of error,
@@ -803,11 +811,11 @@
     # Get the header for the specific proposal module
     # @param submod [String] the proposal module name
     # @return [String] richtext string with the proposal header
-    def html_header(submod)
+    def html_header(submod, force_rw: false)
       title = @store.title_for(submod)
 
       # do not add a link if the module is read-only or link is already 
included
-      heading = if @store.read_only?(submod) || title.include?("<a")
+      heading = if (!force_rw && @store.read_only?(submod)) || 
title.include?("<a")
         title
       else
         Yast::HTML.Link(title, @store.id_for(submod))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/src/lib/installation/proposal_store.rb 
new/yast2-installation-3.2.15/src/lib/installation/proposal_store.rb
--- old/yast2-installation-3.2.13/src/lib/installation/proposal_store.rb        
2017-01-09 10:17:15.591803000 +0100
+++ new/yast2-installation-3.2.15/src/lib/installation/proposal_store.rb        
2017-01-18 11:09:49.232521000 +0100
@@ -250,12 +250,40 @@
       title.gsub(/<a.*?>(.*?)<\/a>/, "\\1")
     end
 
-    # Returns the read-only flag
+    # Checks if the client's proposal is configured as "hard" or "soft" 
read-only
     #
-    # @param [String] client
-    # @return [String] a title provided by the description API
+    # "hard" read-only means that the proposal is always read-only
+    # "soft" read-only means that the proposal is made changeable when an error
+    #
+    # @return [Boolean] true if client is "hard" or "soft" read-only
+    # @see soft_read_only
+    # @see hard_read_only
     def read_only?(client)
-      read_only_proposals.include?(client)
+      hard_read_only?(client) || soft_read_only?(client)
+    end
+
+    # Checks if the client's proposal is configured as "hard" read-only
+    #
+    # "hard" read-only means that the proposal is always read-only
+    # "soft" read-only means that the proposal is made changeable when an error
+    # in proposal is detected.
+    #
+    # @param [String] client
+    # @return [Boolean] if the client is marked as "hard" read only
+    def hard_read_only?(client)
+      read_only_proposals[:hard].include?(client)
+    end
+
+    # Checks if the client's proposal is configured as "soft" read-only
+    #
+    # "hard" read-only means that the proposal is always read-only
+    # "soft" read-only means that the proposal is made changeable when an error
+    # in proposal is detected.
+    #
+    # @param [String] client
+    # @return [Boolean] if the client is marked as "soft" read only
+    def soft_read_only?(client)
+      read_only_proposals[:soft].include?(client)
     end
 
     # Calls client('AskUser'), to change a setting interactively (if link is 
the
@@ -297,16 +325,30 @@
       matching_client.first
     end
 
+    # Reads read-only proposals from the control file
+    #
+    # @return [Hash] map with keys :hard and :soft. Values are names
+    # of proposals with "hard" or "soft" read_only flag set.
     def read_only_proposals
       return @read_only_proposals if @read_only_proposals
 
-      @read_only_proposals = []
+      @read_only_proposals = { hard: [], soft: [] }
 
       properties.fetch("proposal_modules", []).each do |proposal|
         next unless proposal["read_only"]
 
         name = full_module_name(proposal["name"])
-        @read_only_proposals << name
+
+        ro_type = proposal["read_only"]
+
+        case ro_type
+        when "hard"
+          @read_only_proposals[:hard] << name
+        when "soft"
+          @read_only_proposals[:soft] << name
+        else
+          log.info("Uknown value for read_only node: #{ro_type}")
+        end
       end
 
       log.info "Found read-only proposals: #{@read_only_proposals}"
@@ -372,8 +414,8 @@
     # Returns whether given trigger definition is correct
     # e.g., all mandatory parts are there
     #
-    # @param [Hash] trigger definition
-    # @rturn [Boolean] whether it is correct
+    # @param [Hash] trigger_def definition
+    # @return [Boolean] whether it is correct
     def valid_trigger?(trigger_def)
       trigger_def.key?("expect") &&
         trigger_def["expect"].is_a?(Hash) &&
@@ -551,7 +593,7 @@
 
     # Build the full proposal module name including the "_proposal" suffix.
     # The sufix is not added when it is already present.
-    # @param [String] full or short proposal module name
+    # @param [String] name full or short proposal module name
     # @return [String] full proposal module name
     def full_module_name(name)
       # already a full name?
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/src/lib/installation/remote_finish_client.rb 
new/yast2-installation-3.2.15/src/lib/installation/remote_finish_client.rb
--- old/yast2-installation-3.2.13/src/lib/installation/remote_finish_client.rb  
2017-01-09 10:17:15.591803000 +0100
+++ new/yast2-installation-3.2.15/src/lib/installation/remote_finish_client.rb  
2017-01-18 11:09:49.232521000 +0100
@@ -69,7 +69,7 @@
 
     # Modes in which #enable_remote should be called
     #
-    # @return Array<Symbol>
+    # @return [Array<Symbol>]
     def modes
       Yast::Linuxrc.vnc ? [:installation, :autoinst] : []
     end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/src/lib/installation/select_system_role.rb 
new/yast2-installation-3.2.15/src/lib/installation/select_system_role.rb
--- old/yast2-installation-3.2.13/src/lib/installation/select_system_role.rb    
2017-01-09 10:17:15.591803000 +0100
+++ new/yast2-installation-3.2.15/src/lib/installation/select_system_role.rb    
2017-01-18 11:09:49.232521000 +0100
@@ -19,6 +19,7 @@
 
 require "yast"
 require "ui/installation_dialog"
+require "installation/services"
 
 Yast.import "GetInstArgs"
 Yast.import "Popup"
@@ -34,7 +35,8 @@
 
     NON_OVERLAY_ATTRIBUTES = [
       "additional_dialogs",
-      "id"
+      "id",
+      "services"
     ].freeze
 
     def initialize
@@ -182,12 +184,26 @@
       RadioButtonGroup(Id(:roles), ui_roles)
     end
 
+    # Applies given role to configuration
     def apply_role(role_id)
       log.info "Applying system role '#{role_id}'"
       features = raw_roles.find { |r| r["id"] == role_id }
       features = features.dup
       NON_OVERLAY_ATTRIBUTES.each { |a| features.delete(a) }
       Yast::ProductFeatures.SetOverlay(features)
+      adapt_services(role_id)
+    end
+
+    # for given role sets in {::Installation::Services} list of services to 
enable
+    # according to its config. Do not use alone and use apply_role instead.
+    def adapt_services(role_id)
+      services = raw_roles.find { |r| r["id"] == role_id }["services"]
+      services ||= []
+
+      to_enable = services.map { |s| s["name"] }
+      log.info "enable for #{role_id} these services: #{to_enable.inspect}"
+
+      Installation::Services.enabled = to_enable
     end
 
     # the contents is an overlay for ProductFeatures sections
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/src/lib/installation/services.rb 
new/yast2-installation-3.2.15/src/lib/installation/services.rb
--- old/yast2-installation-3.2.13/src/lib/installation/services.rb      
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.2.15/src/lib/installation/services.rb      
2017-01-18 11:09:49.232521000 +0100
@@ -0,0 +1,43 @@
+require "yast"
+
+Yast.import "SystemdService"
+
+module Installation
+  # Represents services manipulation in installation.
+  #
+  # @note For installed system use ServicesManagerServices from
+  # yast2-services-manager. But for installation it is not suitable as it
+  # expects list of all systemd services in advance and try to adapt all of it.
+  # On other hand goal of this module is to do just fine tuning of few single
+  # services and keep defaults for rest.
+  class Services
+    class << self
+      include Yast::Logger
+
+      # gets array of services to enable
+      def enabled
+        @enabled ||= []
+      end
+
+      # sets array of services to enable
+      # @raise [ArgumentError] when argument is not Array
+      def enabled=(services)
+        if !services.is_a?(::Array)
+          raise ArgumentError, "Services#enabled= allows only Array as " \
+            "argument, not #{services.inspect}"
+        end
+
+        @enabled = services
+      end
+
+      # does real enablement of services previously set
+      def write
+        enabled.each do |service|
+          log.info "Enabling service #{service}"
+          s = Yast::SystemdService.find!(service)
+          s.enable
+        end
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/src/lib/installation/update_repository.rb 
new/yast2-installation-3.2.15/src/lib/installation/update_repository.rb
--- old/yast2-installation-3.2.13/src/lib/installation/update_repository.rb     
2017-01-09 10:17:15.611803000 +0100
+++ new/yast2-installation-3.2.15/src/lib/installation/update_repository.rb     
2017-01-18 11:09:49.232521000 +0100
@@ -332,7 +332,8 @@
 
     # Mount the squashed filesystem containing updates
     #
-    # @param path [Pathname] Mountpoint
+    # @param file [Pathname] file with squashfs content
+    # @param mountpoint [Pathname] where to mount
     #
     # @raise CouldNotMountUpdate
     #
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/src/lib/installation/updates_manager.rb 
new/yast2-installation-3.2.15/src/lib/installation/updates_manager.rb
--- old/yast2-installation-3.2.13/src/lib/installation/updates_manager.rb       
2017-01-09 10:17:15.611803000 +0100
+++ new/yast2-installation-3.2.15/src/lib/installation/updates_manager.rb       
2017-01-18 11:09:49.232521000 +0100
@@ -62,7 +62,7 @@
     # At instantiation time, this class looks for existin driver
     # updates in the given `duds_path`.
     #
-    # @param duds_path [Pathname] Path where driver updates are supposed to 
live
+    # @param duds_paths [Pathname] Path where driver updates are supposed to 
live
     def initialize(duds_paths = DRIVER_UPDATES_PATHS)
       @repositories = []
       @driver_updates = Installation::DriverUpdate.find(duds_paths)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/src/lib/transfer/file_from_url.rb 
new/yast2-installation-3.2.15/src/lib/transfer/file_from_url.rb
--- old/yast2-installation-3.2.13/src/lib/transfer/file_from_url.rb     
2017-01-09 10:17:15.619803000 +0100
+++ new/yast2-installation-3.2.15/src/lib/transfer/file_from_url.rb     
2017-01-18 11:09:49.232521000 +0100
@@ -44,7 +44,7 @@
     end
 
     # Basename
-    # @param string path
+    # @param filePath [String] path
     # @return [String]  basename
     def basename(filePath)
       pathComponents = Builtins.splitstring(filePath, "/")
@@ -57,7 +57,7 @@
     end
 
     # Get directory name
-    # @param string path
+    # @param filePath [String] path
     # @return  [String] dirname
     def dirname(filePath)
       pathComponents = Builtins.splitstring(filePath, "/")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-installation-3.2.13/src/modules/InstData.rb 
new/yast2-installation-3.2.15/src/modules/InstData.rb
--- old/yast2-installation-3.2.13/src/modules/InstData.rb       2017-01-09 
10:17:15.619803000 +0100
+++ new/yast2-installation-3.2.15/src/modules/InstData.rb       2017-01-18 
11:09:49.236521000 +0100
@@ -96,6 +96,9 @@
       # only product names, not the actual RN text
       @downloaded_release_notes = []
 
+      # list of release notes that YaST failed to download
+      @failed_release_notes = []
+
       # remember that downloading release notes failed due to communication
       # issues with the server, avoid further attempts then
       @stop_relnotes_download = false
@@ -118,6 +121,7 @@
     publish variable: :release_notes, type: "map<string,string>"
     publish variable: :downloaded_release_notes, type: "list<string>"
     publish variable: :stop_relnotes_download, type: "boolean"
+    publish variable: :failed_release_notes, type: "list<string>"
   end
 
   InstData = InstDataClass.new
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/src/modules/SystemFilesCopy.rb 
new/yast2-installation-3.2.15/src/modules/SystemFilesCopy.rb
--- old/yast2-installation-3.2.13/src/modules/SystemFilesCopy.rb        
2017-01-09 10:17:15.623803000 +0100
+++ new/yast2-installation-3.2.15/src/modules/SystemFilesCopy.rb        
2017-01-18 11:09:49.236521000 +0100
@@ -70,8 +70,7 @@
     # If the path exists but it is not a directory, it tries to create another
     # directory and returns its name. 'nil' is returned when everythig fails.
     #
-    # @param string mnt_tmpdir
-    # #return string mnt_tmpdir (maybe changed)
+    # @param create_directory [String] directory to create
     def CreateDirectoryIfMissing(create_directory)
       # path already exists
       if FileUtils.Exists(create_directory)
@@ -433,7 +432,7 @@
 
     # Sets whether to use copy_files from control file
     #
-    # @param boolean whether to use them
+    # @param new_value [Boolean] whether to use them
     # @see #GetUseControlFileDef
     def SetUseControlFileDef(new_value)
       if new_value.nil?
@@ -459,7 +458,7 @@
     # Sets new rules which files will be copied during installation.
     #
     # @see FATE #305019: configure the files to copy from a previous 
installation
-    # @param list <map> of new definitions
+    # @param new_copy_files[Array<Hash>] of new definitions
     #
     #
     # **Structure:**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/test/lib/inst_download_release_notes_test.rb 
new/yast2-installation-3.2.15/test/lib/inst_download_release_notes_test.rb
--- old/yast2-installation-3.2.13/test/lib/inst_download_release_notes_test.rb  
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.2.15/test/lib/inst_download_release_notes_test.rb  
2017-01-18 11:09:49.252521000 +0100
@@ -0,0 +1,151 @@
+#!/usr/bin/env rspec
+
+require_relative "../test_helper"
+require "installation/clients/inst_download_release_notes"
+
+Yast.import "InstData"
+Yast.import "Pkg"
+Yast.import "Language"
+
+describe Yast::InstDownloadReleaseNotesClient do
+  CURL_NOT_FOUND_CODE = 22
+  CURL_SUCCESS_CODE = 0
+  CURL_HARD_ERROR = 7
+
+  subject(:client) { described_class.new }
+
+  let(:relnotes_url) do
+    
"http://doc.opensuse.org/release-notes/x86_64/openSUSE/Leap42.1/release-notes-openSUSE.rpm";
+  end
+
+  let(:product) do
+    {
+      "arch" => "x86_64", "description" => "openSUSE Leap", "category" => 
"base",
+      "status" => :selected, "short_name" => "openSUSE",
+      "relnotes_url" => relnotes_url
+    }
+  end
+
+  describe "#main" do
+    let(:proxy) { double("proxy", "Read" => nil, "enabled" => false) }
+    let(:curl_code) { CURL_SUCCESS_CODE }
+    let(:language) { "en_US" }
+
+    before do
+      stub_const("Yast::Proxy", proxy)
+      allow(Yast::Pkg).to receive(:ResolvableProperties).with("", :product, "")
+        .and_return([product])
+
+      allow(Yast::SCR).to receive(:Execute)
+        .with(Yast::Path.new(".target.bash"), /curl.*relnotes/)
+        .and_return(curl_code)
+
+      allow(Yast::SCR).to receive(:Read)
+        .with(Yast::Path.new(".target.tmpdir"))
+      allow(Yast::SCR).to receive(:Read)
+        .with(Yast::Path.new(".target.string"), /relnotes/)
+        .and_return("RELNOTES CONTENT")
+
+      allow(Yast::Language).to receive(:language).and_return(language)
+
+      Yast::InstData.main # reset installation data
+    end
+
+    it "returns :auto" do
+      expect(client.main).to eq(:auto)
+    end
+
+    context "when release notes are downloaded correctly" do
+      let(:curl_code) { 0 }
+
+      it "saves release notes in InstData" do
+        client.main
+        expect(Yast::InstData.release_notes["openSUSE"]).to eq("RELNOTES 
CONTENT")
+      end
+    end
+
+    context "when release notes cannot be downloaded due to a hard error" do
+      let(:curl_code) { CURL_HARD_ERROR }
+
+      it "does not retry" do
+        expect(Yast::SCR).to receive(:Execute)
+          .with(Yast::Path.new(".target.bash"), /curl.*relnotes/)
+          .once.and_return(curl_code)
+        client.main
+      end
+
+      it "does not save release notes" do
+        allow(Yast::SCR).to receive(:Execute)
+          .with(Yast::Path.new(".target.bash"), /curl.*relnotes/)
+          .and_return(curl_code)
+        client.main
+        expect(Yast::InstData.release_notes["openSUSE"]).to be_nil
+      end
+    end
+
+    context "when release notes are not found for the default language" do
+      let(:language) { "es_ES" }
+
+      before do
+        allow(Yast::SCR).to receive(:Execute)
+          .with(Yast::Path.new(".target.bash"), 
/curl.*RELEASE-NOTES.#{language}/)
+          .and_return(CURL_NOT_FOUND_CODE) # not found
+      end
+
+      it "falls back to the generic language (es_ES -> es)" do
+        expect(Yast::SCR).to receive(:Execute).once
+          .with(Yast::Path.new(".target.bash"), 
/curl.*RELEASE-NOTES.#{language[0..1]}.rtf/)
+          .and_return(CURL_NOT_FOUND_CODE)
+        client.main
+      end
+
+      context "and are not found for the generic language" do
+        before do
+          allow(Yast::SCR).to receive(:Execute)
+            .with(Yast::Path.new(".target.bash"), 
/curl.*RELEASE-NOTES.#{language[0..1]}.rtf/)
+            .and_return(CURL_NOT_FOUND_CODE) # not found
+        end
+
+        it "falls back to 'en'" do
+          expect(Yast::SCR).to receive(:Execute).once
+            .with(Yast::Path.new(".target.bash"), /curl.*RELEASE-NOTES.en.rtf/)
+            .and_return(CURL_NOT_FOUND_CODE)
+          client.main
+        end
+      end
+
+      context "and default language is 'en_*'" do
+        let(:language) { "en_US" }
+
+        # bsc#1015794
+        it "tries only 1 time with 'en'" do
+          expect(Yast::SCR).to receive(:Execute).once
+            .with(Yast::Path.new(".target.bash"), /curl.*RELEASE-NOTES.en.rtf/)
+            .and_return(CURL_NOT_FOUND_CODE)
+          client.main
+        end
+      end
+    end
+
+    context "when called twice" do
+      let(:language) { "en" }
+      let(:curl_code) { 22 }
+
+      it "does not try to download again already failed release notes" do
+        expect(Yast::SCR).to receive(:Execute).once
+          .with(Yast::Path.new(".target.bash"), /curl.*RELEASE-NOTES.en.rtf/)
+          .and_return(CURL_NOT_FOUND_CODE)
+        client.main
+        client.main # call it a second time
+      end
+
+      it "does not download again already downloaded release notes" do
+        expect(Yast::SCR).to receive(:Execute).once
+          .with(Yast::Path.new(".target.bash"), /curl.*RELEASE-NOTES.en.rtf/)
+          .and_return(CURL_SUCCESS_CODE)
+        client.main
+        client.main # call it a second time
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/test/proposal_runner_test.rb 
new/yast2-installation-3.2.15/test/proposal_runner_test.rb
--- old/yast2-installation-3.2.13/test/proposal_runner_test.rb  2017-01-09 
10:17:15.823803000 +0100
+++ new/yast2-installation-3.2.15/test/proposal_runner_test.rb  2017-01-18 
11:09:49.252521000 +0100
@@ -75,6 +75,29 @@
       expect(subject.run).to eq :auto
     end
 
+    describe "#html_header" do
+      it "returns clickable header when forced" do
+        allow(Yast::GetInstArgs).to receive(:proposal).and_return("software")
+
+        expect_any_instance_of(::Installation::ProposalRunner)
+          .to receive(:submod_descriptions_and_build_menu)
+          .and_return(false)
+        expect_any_instance_of(::Installation::ProposalStore)
+          .to receive(:title_for)
+          .and_return("Software")
+        expect_any_instance_of(::Installation::ProposalStore)
+          .to receive(:id_for)
+          .and_return("software")
+        expect_any_instance_of(::Installation::ProposalStore)
+          .not_to receive(:read_only?)
+
+        # initialization of internal state
+        expect(subject.run).to eq :auto
+
+        expect(subject.send(:html_header, "software", force_rw: true)).to eql 
Yast::HTML.Heading(Yast::HTML.Link("Software", "software"))
+      end
+    end
+
     context "when proposal contains tabs" do
       let(:properties) do
         PROPERTIES.merge(
@@ -126,6 +149,43 @@
           expect(subject.run).to eq(:next)
         end
       end
+
+      context "and it enables soft r/o proposal in case of error" do
+        PROPERTIES = {
+          "enable_skip"      => "no",
+          "label"            => "Installation Settings",
+          "mode"             => "autoinstallation",
+          "name"             => "initial",
+          "stage"            => "initial",
+          "unique_id"        => "auto_inst_proposal",
+          "proposal_modules" => [
+            { "name" => "software", "presentation_order" => "15", "read_only" 
=> "soft" }
+          ]
+        }.freeze
+        let(:proposals) { [["software_proposal", 15]] }
+
+        it "makes a proposal" do
+          allow(subject)
+            .to receive(:html_header)
+            .with("software_proposal")
+            .and_call_original
+
+          # we need ProposalStore#make_proposal to call the callback
+          allow(Yast::WFM)
+            .to receive(:CallFunction)
+            .and_return(
+              "preformated_proposal" => "",
+              "warning_level"        => :error
+            )
+
+          expect(subject)
+            .to receive(:html_header)
+            .with("software_proposal", force_rw: true)
+            .at_least(:once)
+            .and_call_original
+          expect(subject.run).to eq(:next)
+        end
+      end
     end
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/test/proposal_store_test.rb 
new/yast2-installation-3.2.15/test/proposal_store_test.rb
--- old/yast2-installation-3.2.13/test/proposal_store_test.rb   2017-01-09 
10:17:15.823803000 +0100
+++ new/yast2-installation-3.2.15/test/proposal_store_test.rb   2017-01-18 
11:09:49.252521000 +0100
@@ -568,24 +568,51 @@
         # Proposals need to be cached first
         subject.make_proposals
 
-        expect(subject).to 
receive(:read_only?).with("proposal_a").and_return(true)
         allow(Yast::Report).to receive(:Warning)
       end
 
-      it "displays a warning" do
-        expect(Yast::Report).to receive(:Warning)
-
-        subject.handle_link("proposal_a")
-      end
-
-      it "does not run the proposal client" do
-        expect(Yast::WFM).to_not receive(:CallFunction)
-
-        subject.handle_link("proposal_a")
+      context "in case of hard read only proposal" do
+        before do
+          expect(subject).to 
receive(:hard_read_only?).with("proposal_a").and_return(true)
+        end
+
+        it "displays a warning" do
+          expect(Yast::Report).to receive(:Warning)
+
+          subject.handle_link("proposal_a")
+        end
+
+        it "does not run the proposal client" do
+          expect(Yast::WFM).to_not receive(:CallFunction)
+
+          subject.handle_link("proposal_a")
+        end
+
+        it "returns nil" do
+          expect(subject.handle_link("proposal_a")).to eq(nil)
+        end
       end
 
-      it "returns nil" do
-        expect(subject.handle_link("proposal_a")).to eq(nil)
+      context "in case of soft read only proposal" do
+        before do
+          expect(subject).to 
receive(:soft_read_only?).with("proposal_a").and_return(true)
+        end
+
+        it "displays a warning" do
+          expect(Yast::Report).to receive(:Warning)
+
+          subject.handle_link("proposal_a")
+        end
+
+        it "does not run the proposal client" do
+          expect(Yast::WFM).to_not receive(:CallFunction)
+
+          subject.handle_link("proposal_a")
+        end
+
+        it "returns nil" do
+          expect(subject.handle_link("proposal_a")).to eq(nil)
+        end
       end
     end
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-installation-3.2.13/test/services_finish_test.rb 
new/yast2-installation-3.2.15/test/services_finish_test.rb
--- old/yast2-installation-3.2.13/test/services_finish_test.rb  1970-01-01 
01:00:00.000000000 +0100
+++ new/yast2-installation-3.2.15/test/services_finish_test.rb  2017-01-18 
11:09:49.252521000 +0100
@@ -0,0 +1,21 @@
+#! /usr/bin/env rspec
+
+require_relative "./test_helper"
+
+require "installation/clients/services_finish"
+
+describe ::Installation::Clients::ServicesFinish do
+  describe "#title" do
+    it "returns string with title" do
+      expect(subject.title).to be_a ::String
+    end
+  end
+
+  describe "#write" do
+    it "writes installation services" do
+      expect(::Installation::Services).to receive(:write)
+
+      subject.write
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-installation-3.2.13/test/services_test.rb 
new/yast2-installation-3.2.15/test/services_test.rb
--- old/yast2-installation-3.2.13/test/services_test.rb 1970-01-01 
01:00:00.000000000 +0100
+++ new/yast2-installation-3.2.15/test/services_test.rb 2017-01-18 
11:09:49.252521000 +0100
@@ -0,0 +1,51 @@
+#! /usr/bin/env rspec
+
+require_relative "./test_helper"
+
+require "installation/services"
+
+describe ::Installation::Services do
+  before do
+    # simulate non used class
+    described_class.instance_variable_set(:@enabled, nil)
+  end
+
+  describe ".enabled" do
+    it "returns list of previously set services" do
+      described_class.enabled = ["test"]
+      expect(described_class.enabled).to eq ["test"]
+    end
+
+    it "returns empty list if not set previously" do
+      expect(described_class.enabled).to eq []
+    end
+  end
+
+  describe ".enabled=" do
+    it "sets list of services to enable" do
+      described_class.enabled = ["test"]
+      expect(described_class.enabled).to eq ["test"]
+    end
+
+    it "raise exception if non-array is passed" do
+      expect { described_class.enabled = "test" }.to raise_error(ArgumentError)
+    end
+  end
+
+  describe ".write" do
+    it "enables all services previously set" do
+      described_class.enabled = ["test"]
+      service = double(enable: true)
+      expect(Yast::SystemdService).to 
receive(:find!).with("test").and_return(service)
+      expect(service).to receive(:enable)
+
+      described_class.write
+    end
+
+    it "raises Yast::SystemdServiceNotFound exception if service to enable 
does not exist" do
+      described_class.enabled = ["non-existing-service"]
+
+      expect { described_class.write }.to 
raise_error(Yast::SystemdServiceNotFound)
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-installation-3.2.13/test/test_helper.rb 
new/yast2-installation-3.2.15/test/test_helper.rb
--- old/yast2-installation-3.2.13/test/test_helper.rb   2017-01-09 
10:17:15.859803000 +0100
+++ new/yast2-installation-3.2.15/test/test_helper.rb   2017-01-18 
11:09:49.252521000 +0100
@@ -23,6 +23,7 @@
 stub_module("Packages")
 stub_module("InstURL")
 stub_module("Language")
+stub_module("Keyboard")
 stub_module("AddOnProduct")
 stub_module("ProductLicense")
 stub_module("AutoinstGeneral")
@@ -37,11 +38,7 @@
   end
 
   # For coverage we need to load all ruby files
-  # Note that clients/ are excluded because they run too eagerly by
-  # design
-  Dir["#{srcdir}/{include,lib,modules}/**/*.rb"].each do |f|
-    require_relative f
-  end
+  SimpleCov.track_files("#{srcdir}/**/*.rb")
 
   # use coveralls for on-line code coverage reporting at Travis CI
   if ENV["TRAVIS"]


Reply via email to