diff --git a/library/desktop/groups/hardware.desktop b/library/desktop/groups/hardware.desktop index 864748357..10a756f44 100644 --- a/library/desktop/groups/hardware.desktop +++ b/library/desktop/groups/hardware.desktop @@ -4,7 +4,6 @@ Categories=Qt;X-SuSE-YaST; X-KDE-ModuleType=Library X-KDE-HasReadOnlyMode=true -X-KDE-Library=yast2 X-SuSE-YaST-Group=Hardware X-SuSE-YaST-SortKey=20 diff --git a/library/desktop/groups/high_availability.desktop b/library/desktop/groups/high_availability.desktop index c9aa7eebc..0b21f5567 100644 --- a/library/desktop/groups/high_availability.desktop +++ b/library/desktop/groups/high_availability.desktop @@ -4,7 +4,6 @@ Categories=Qt;X-SuSE-YaST; X-KDE-ModuleType=Library X-KDE-HasReadOnlyMode=true -X-KDE-Library=yast2 X-SuSE-YaST-Group=High_Availability X-SuSE-YaST-SortKey=20 diff --git a/library/desktop/groups/misc.desktop b/library/desktop/groups/misc.desktop index 91e365b20..18044495c 100644 --- a/library/desktop/groups/misc.desktop +++ b/library/desktop/groups/misc.desktop @@ -4,7 +4,6 @@ Categories=Qt;X-SuSE-YaST; X-KDE-ModuleType=Library X-KDE-HasReadOnlyMode=true -X-KDE-Library=yast2 X-SuSE-YaST-Group=Misc X-SuSE-YaST-SortKey=99 diff --git a/library/desktop/groups/network_devices.desktop b/library/desktop/groups/network_devices.desktop index fe6f35d9d..f38f18115 100644 --- a/library/desktop/groups/network_devices.desktop +++ b/library/desktop/groups/network_devices.desktop @@ -4,7 +4,6 @@ Categories=Qt;X-SuSE-YaST; X-KDE-ModuleType=Library X-KDE-HasReadOnlyMode=true -X-KDE-Library=yast2 X-SuSE-YaST-Group=Network X-SuSE-YaST-SortKey=30 diff --git a/library/desktop/groups/network_services.desktop b/library/desktop/groups/network_services.desktop index 63f1f7349..06dc16695 100644 --- a/library/desktop/groups/network_services.desktop +++ b/library/desktop/groups/network_services.desktop @@ -4,7 +4,6 @@ Categories=Qt;X-SuSE-YaST; X-KDE-ModuleType=Library X-KDE-HasReadOnlyMode=true -X-KDE-Library=yast2 X-SuSE-YaST-Group=Net_advanced X-SuSE-YaST-SortKey=40 diff --git a/library/desktop/groups/security.desktop b/library/desktop/groups/security.desktop index 991bf0ed5..272f952ae 100644 --- a/library/desktop/groups/security.desktop +++ b/library/desktop/groups/security.desktop @@ -4,7 +4,6 @@ Categories=Qt;X-SuSE-YaST; X-KDE-ModuleType=Library X-KDE-HasReadOnlyMode=true -X-KDE-Library=yast2 X-SuSE-YaST-Group=Security X-SuSE-YaST-SortKey=50 diff --git a/library/desktop/groups/software.desktop b/library/desktop/groups/software.desktop index d20b0f232..2a455600e 100644 --- a/library/desktop/groups/software.desktop +++ b/library/desktop/groups/software.desktop @@ -4,7 +4,6 @@ Categories=Qt;X-SuSE-YaST; X-KDE-ModuleType=Library X-KDE-HasReadOnlyMode=true -X-KDE-Library=yast2 X-SuSE-YaST-Group=Software X-SuSE-YaST-SortKey=10 diff --git a/library/desktop/groups/support.desktop b/library/desktop/groups/support.desktop index 733c77e2a..f08dece71 100644 --- a/library/desktop/groups/support.desktop +++ b/library/desktop/groups/support.desktop @@ -4,7 +4,6 @@ Categories=Qt;X-SuSE-YaST; X-KDE-ModuleType=Library X-KDE-HasReadOnlyMode=true -X-KDE-Library=yast2 X-SuSE-YaST-Group=Support X-SuSE-YaST-SortKey=90 diff --git a/library/desktop/groups/system.desktop b/library/desktop/groups/system.desktop index 493884372..bd5b823ef 100644 --- a/library/desktop/groups/system.desktop +++ b/library/desktop/groups/system.desktop @@ -4,7 +4,6 @@ Categories=Qt;X-SuSE-YaST; X-KDE-ModuleType=Library X-KDE-HasReadOnlyMode=true -X-KDE-Library=yast2 X-SuSE-YaST-Group=System X-SuSE-YaST-SortKey=20 diff --git a/library/general/src/Makefile.am b/library/general/src/Makefile.am index 3140364b9..21f80f880 100644 --- a/library/general/src/Makefile.am +++ b/library/general/src/Makefile.am @@ -81,6 +81,12 @@ ydata_DATA = \ fillup_DATA = \ fillup/sysconfig.yast2 -EXTRA_DIST = $(module_DATA) $(client_DATA) $(scrconf_DATA) $(agent_SCRIPTS) $(ydata_DATA) $(fillup_DATA) +ylibdir = "${yast2dir}/lib/installation" +ylib_DATA = \ + lib/installation/auto_client.rb \ + lib/installation/finish_client.rb \ + lib/installation/proposal_client.rb + +EXTRA_DIST = $(module_DATA) $(client_DATA) $(scrconf_DATA) $(agent_SCRIPTS) $(ydata_DATA) $(fillup_DATA) $(ylib_DATA) include $(top_srcdir)/Makefile.am.common diff --git a/library/general/src/fillup/sysconfig.yast2 b/library/general/src/fillup/sysconfig.yast2 index 4876eb2b9..4498911fc 100644 --- a/library/general/src/fillup/sysconfig.yast2 +++ b/library/general/src/fillup/sysconfig.yast2 @@ -13,7 +13,7 @@ # presence and adapt accordingly WANTED_SHELL="auto" -## Type: list(auto,qt,gtk,ncurses) +## Type: list(auto,qt,ncurses) ## Default: "auto" # Default UI backend for YaST # selects the GUI plugin to be used to render yast widgets diff --git a/library/general/src/lib/installation/auto_client.rb b/library/general/src/lib/installation/auto_client.rb new file mode 100644 index 000000000..82b581443 --- /dev/null +++ b/library/general/src/lib/installation/auto_client.rb @@ -0,0 +1,146 @@ +require "yast" + +module Installation + # An abstract class that simplifies writing `*_auto.rb` clients for AutoYaST. + # + # It provides a single entry point + # which dispatches calls to the abstract methods that all proposal clients + # need to implement. + # + # You need to implement all the methods, except {#packages}. + # + # "Autoinstall" basically means {#import}, then {#write}. + # "Clone" means {#read}, then {#export}. + # + # @example how to run a client + # require "installation/example_auto" + # ::Installation::ExampleAuto.run + # + # @see https://github.com/yast/yast-bootloader/blob/master/src/clients/bootloader_auto.rb + # Example client, bootloader_auto.rb + # @see http://users.suse.com/~ug/autoyast_doc/devel/ar01s05.html + # Code-related configuration and some old documenation. + class AutoClient < Yast::Client + include Yast::Logger + + # Entry point for calling the client. + # The only part needed in client rb file. + # @return response from abstract methods + def self.run + self.new.run + end + + # Dispatches to abstract method based on passed Arguments to client + def run + func, param = Yast::WFM.Args + log.info "Called #{self.class}.run with #{func} and params #{param}" + + case func + when "Import" + import(param) + when "Export" + export + when "Summary" + summary + when "Reset" + reset + when "Change" + change + when "Write" + write + when "Packages" + packages + when "Read" + read + when "GetModified" + modified? + when "SetModified" + modified + else + raise ArgumentError, "Invalid action for auto client '#{func.inspect}'" + end + end + + protected + + # Import data from AutoYaST profile. + # + # The profile is a Hash or an Array according to the configuration item + # `X-SuSE-YaST-AutoInstDataType` + # @param profile [Hash, Array] profile data specific to this module. + # @return true on success + def import(profile) + raise NotImplementedError, "Calling abstract method 'import'" + end + + # Export profile data from AutoYaST. + # + # The profile is a Hash or an Array according to the configuration item + # `X-SuSE-YaST-AutoInstDataType` + # @return [Hash, Array] profile data + def export + raise NotImplementedError, "Calling abstract method 'export'" + end + + # Provide a brief summary of configuration. + # @return [String] description in RichText format + def summary + raise NotImplementedError, "Calling abstract method 'summary'" + end + + # Reset configuration to default state. + # @return [void] + def reset + raise NotImplementedError, "Calling abstract method 'reset'" + end + + # Run UI to modify the configuration. + # @return [Symbol] If one of `:accept`, `:next`, `:finish` is returned, + # the changes are accepted, otherwise they are discarded. + def change + raise NotImplementedError, "Calling abstract method 'change'" + end + + + # Write settings to the target system. + # @return [Boolean] true on success + def write + raise NotImplementedError, "Calling abstract method 'write'" + end + + # Get a list of packages needed for configuration. + # + # The default implementation returns an empty list. + # @return [Array] list of required packages + def packages + log.info "#{self.class}#packages not implemented, returning []." + + [] + end + + # Read settings from the target system. + # + # It is used to initialize configuration from the current system + # for further represent in AutoYaST profile. + # @return [void] + def read + raise NotImplementedError, "Calling abstract method 'write'" + end + + # Set that the profile data has beed modified + # and should be exported from the interactive editor, + # or included in the cloned data. + # @return [void] + def modified + raise NotImplementedError, "Calling abstract method 'modified'" + end + + # Query whether the profile data has beed modified + # and should be exported from the interactive editor, + # or included in the cloned data. + # @return [Boolean] + def modified? + raise NotImplementedError, "Calling abstract method 'modified?'" + end + end +end diff --git a/library/general/src/lib/installation/finish_client.rb b/library/general/src/lib/installation/finish_client.rb new file mode 100644 index 000000000..ebc7c3e32 --- /dev/null +++ b/library/general/src/lib/installation/finish_client.rb @@ -0,0 +1,99 @@ +require "yast" + +module Installation + # Abstract class that simplify writting finish clients for installation. + # It provides single entry point and abstract methods, that all finish clients + # need to implement. + # @example how to run client + # require "installation/example_finish" + # ::Installation::ExampleFinish.run + # @see for example client in installation clone_finish.rb + # + # # Inst-Finish Scripts + # ## About + # They are called by the inst_finish.ycp installation client at the end of the + # first stage installation. + # + # Part of these clients are called with SCR connected to inst-sys, the others + # are called after SCR gets switched to the installed system (chrooted). + # + # Script inst_finish.ycp contains several stages, every has + # + # * label - visible in the writing progress + # + # * steps - list of additional inst_finish scripts that are called + # ("bingo" -> "bingo_finish.ycp") + # Important script is "switch_scr", after that call, SCR is connected to the + # just installed system. + # + # ## Finish Scripts + # + # Every single finish script is a non-interactive script (write-only). It's + # basically called twice: + # + # * At first "Info" returns in which modes "Write" should be called + # + # * Then "Write" should be called to do the job + # + class FinishClient < Yast::Client + include Yast::Logger + + # Entry point for calling client. + # The only part needed in client rb file. + # @return response from abstract methods + def self.run + self.new.run + end + + # Dispatches to abstract method based on passed arguments to client + def run + func = Yast::WFM.Args.first + log.info "Called #{self.class}.run with #{func}" + + case func + when "Info" + info + when "Write" + write + else + raise ArgumentError, "Invalid action for proposal '#{func.inspect}'" + end + end + + protected + + # Write configuration. + def write + raise NotImplementedError, "Calling abstract method 'write'" + end + + # Restrict in which modes it should run. + # @return [Array, nil] + # Valid values are `:autoinst`, `:autoupg`, `:installation`, + # `:live_installation`, and `:update`. NOTE that these values + # are NOT consistent with the names used in {Yast::ModeClass Mode}. + # By default it returns `nil`, meaning to run always. + def modes + nil + end + + # @return [Integer] the number of client steps. + def steps + 1 + end + + # @return [String] a title used to display to the user what is happening. + def title + raise NotImplementedError, "Calling abstract method 'title'" + end + + # Adapt the metadata for inst_finish API + def info + { + "when " => modes, + "steps" => steps, + "title" => title + } + end + end +end diff --git a/library/general/src/lib/installation/proposal_client.rb b/library/general/src/lib/installation/proposal_client.rb new file mode 100644 index 000000000..67162a820 --- /dev/null +++ b/library/general/src/lib/installation/proposal_client.rb @@ -0,0 +1,240 @@ +require "yast" + +module Installation + # Abstract class that simplifies writing proposal clients for installation. + # It provides a single entry point + # which dispatches calls to the abstract methods that all proposal clients + # need to implement. + # + # It is recommended to use {Installation::ProposalClient} as base class for + # new clients. + # + # @example how to run a client + # require "installation/example_proposal" + # ::Installation::ExampleProposal.run + # @see for example client in installation clone_proposal.rb + # + # # API for YaST2 installation proposal + # + # ## Motivation + # + # After five releases, YaST2 is now smart enough to make reasonable + # proposals for (nearly) every installation setting, thus it is no longer + # necessary to ask the user that many questions during installation: + # Most users simply hit the [next] button anyway. + # + # Hence, YaST2 now collects all the individual proposals from its submodules + # and presents them for confirmation right away. The user can change each + # individual setting, but he is no longer required to go through all the + # steps just to change some simple things. The only that (currently) really + # has to be queried is the installation language - this cannot reasonably be + # guessed (yet?). + # + # ## Overview + # + # YaST2 installation modules should cooperate with the main program in a + # consistent API. General usage: + # + # * inst_proposal (main program) creates an empty dialog with RichText widget + # + # * inst_proposal calls each sub-module in turn to make a proposal + # + # * the user may choose to change individual settings + # (by clicking on a hyperlink) + # + # * inst_proposal starts that module's sub-workflow which runs + # independently. After this, inst_proposal tells all subsequent (all?) + # modules to check their states and return whether a change of their + # proposal is necessary after the user interaction. + # + # * main program calls each sub-module to write the settings to the system + # + class ProposalClient < Yast::Client + include Yast::Logger + + # The entry point for calling a client. + # The only part needed in client rb file. + # @return response from abstract methods + def self.run + self.new.run + end + + # Dispatches to abstract method based on passed Arguments to client + def run + func, param = Yast::WFM.Args + log.info "Called #{self.class}.run with #{func} and params #{param}" + + case func + when "MakeProposal" + make_proposal(param) + when "AskUser" + ask_user(param) + when "Description" + description + when "Write" + write(param) + else + raise ArgumentError, "Invalid action for proposal '#{func.inspect}'" + end + end + + protected + + # Abstract method to create proposal suggestion for installation + # + # @option attrs [Boolean] "force_reset" + # If `true`, discard anything that may be cached + # and start over from scratch. + # If `false`, use cached values from the last invocation if there are any. + # + # @option attrs [Boolean] "language_changed" + # The installation language has changed since the last call of + # {#make_proposal}. + # This is important only if there is a language change mechanism + # in one of the other submodules. + # If this parameter is "true", any texts the user can see in + # the proposal need to be retranslated. The internal translator mechanism + # will take care of this itself if the corresponding strings are once more + # put through it (the `_("...")` function). Only very few + # submodules that translate any strings internally based on internal maps + # (e.g., keyboard etc.) need to take more action. + # + # @return [Hash] containing: + # + # * **`"links"`** [Array] --- + # A list of additional hyperlink IDs used in summaries returned by this + # section. All possible values must be included. + # + # * **`"preformatted_proposal"`** [String, nil] --- + # Human readable proposal preformatted in HTML. It is possible to use + # the {Yast::HTMLClass Yast::HTML} module for such formatting. + # + # * **`"raw_proposal"`** [Array, nil] + # (only used if `preformatted_proposal` is not present) --- + # Human readable proposal, not formatted yet. + # The caller will format each item as a HTML list item (`
  • `). The + # proposal can contain hyperlinks with IDs listed in the list `links`. + # + # * **`"warning"`** [String, nil] --- + # Warning in human readable format without HTML tags other than `\
    `. + # The warning will be embedded in appropriate HTML format specifications + # according to `warning_level` below. + # + # * **`"warning_level"`** [Symbol, nil] --- + # Determines the severity and the visual display of the warning. + # The valid values are + # `:notice`, `:warning` (default), `:error`, `:blocker` and `:fatal`. + # A _blocker_ will prevent the user from continuing the installation. + # If any proposal contains a _blocker_ warning, the Accept + # button in the proposal dialog will be disabled - the user needs + # to fix that blocker before continuing. + # _Fatal_ is like _blocker_ but also stops building the proposal. + # + # * **`"language_changed"`** [Boolean] --- + # This module just caused a change of the installation language. + # This is only relevant for the "language" module. + # + # * **`"mode_changed"`** [Boolean, nil] --- + # This module just caused a change of the installation mode. + # This is only relevant for the "inst mode" module. + # + # * **`"rootpart_changed"`** [Boolean, nil] --- + # This module just caused a change of the root partition. + # This is only relevant for the "root part" module. + # + # * **`"help"`** [String, nil] --- + # Help text for this module which appears in the standard dialog + # help (particular helps for modules sorted by presentation order). + # + def make_proposal(attrs) + raise NotImplementedError, "Calling abstract method 'make_proposal'" + end + + # An abstract method to run an interactive workflow -- let the user + # decide upon values he might want to change. + # + # It may contain one single dialog, a sequence of dialogs, or one master + # dialog with one or more "expert" dialogs. It can also be a non-interactive + # response to clicking on a hyperlink. The module is responsible for + # controlling the workflow sequence (i.e., "Next", "Back" buttons etc.). + # + # Submodules do not provide an "Abort" button to abort the entire + # installation. If the user wishes to do that, he can always go back to + # the main dialog (the installation proposal) and choose "Abort" there. + # + # @option attrs [Boolean] "has_next" + # Use a "Next" button even if the module by itself has only one step, thus + # would normally have an "OK" button - or would rename the "Next" button + # to something like "Finish" or "Accept". + # + # @option attrs [String, nil] "chosen_id" + # If a section proposal contains hyperlinks and the user clicks + # on one of them, this defines the ID of the hyperlink. + # All hyperlink IDs must be set in the map returned by {#description}. + # If the user did not click on a proposal hyperlink, + # this parameter is not defined. + # + # @return [Hash] containing: + # + # * **`"workflow_sequence"`** [Symbol] with these possible values: + # + # * `:next` (default) --- Everything OK - continue with the next + # step in workflow sequence. + # + # * `:back` --- User requested to go back in the workflow sequence. + # + # * `:again` --- Call this submodule again + # (i.e., re-initialize the submodule) + # + # * `:auto` --- Continue with the workflow sequence in the current + # direction: forward if the last submodule returned + # `:next`, backward otherwise. + # + # * `:finish` --- Finish the installation. This is specific + # to "inst_mode.ycp" when the user selected + # "boot system" there. + # + # * **`"language_changed"`** [Boolean, nil] --- + # This module just caused a change of the installation language. + # This is only relevant for the "language" module. + # + def ask_user(attrs) + raise NotImplementedError, "Calling abstract method 'ask_user'" + end + + + # An abstract method to return human readable titles both for the RichText + # (HTML) widget and for menu entries. It also specifies an ID which is used + # when the user selects the module. + # + # @return [Hash] containing: + # + # * **`"rich_text_title"`** [String] --- + # A translated human readable title for this section in + # the `RichText` widget without any HTML formatting. + # This will be embedded in `

    ...

    ` + # so make sure not to add any additional HTML formatting. + # Keyboard shortcuts are not (yet?) supported, so do not include + # any `&` characters. + # + # * **`"menu_title"`** [String] --- + # A translated human readable menu entry for this section. + # It must contain a keyboard shortcut (`&`). It should NOT contain + # a trailing ellipsis (`...`), the caller will add it. + # + # * **`"id"`** [String] --- + # A programmer-readable unique identifier for this section. This is not + # auto-generated to keep the log file readable. + # + # This map may be empty. In this case, this proposal section will silently + # be ignored. Proposal modules may use this if there is no useful proposal + # at all. Use with caution - this may be confusing for the user. + # + # In this case, all other proposal functions must return a useful success + # value so they can be called without problems. + # + def description + raise NotImplementedError, "Calling abstract method 'description'" + end + end +end diff --git a/library/general/src/modules/Arch.rb b/library/general/src/modules/Arch.rb index 939eb4fab..b31729f9b 100644 --- a/library/general/src/modules/Arch.rb +++ b/library/general/src/modules/Arch.rb @@ -63,7 +63,7 @@ def main # ************************************************************ # system architecture - # Returns full architecture type (one of i386, sparc, sparc64, mips, mips64, ppc, ppc64, alpha, s390_32, s390_64, ia64, x86_64) + # Returns full architecture type (one of i386, sparc, sparc64, mips, mips64, ppc, ppc64, alpha, s390_32, s390_64, ia64, x86_64, aarch64) # # @return [String] architecture def architecture @@ -179,7 +179,12 @@ def x86_64 architecture == "x86_64" end - # Returns general architecture type (one of sparc, mips, ppc, s390, i386, alpha, ia64, x86_64) + # true for all aarch64 (ARM64) architectures + def aarch64 + architecture == "aarch64" + end + + # Returns general architecture type (one of sparc, mips, ppc, s390, i386, alpha, ia64, x86_64, aarch64) # # @return [String] arch_short def arch_short @@ -510,6 +515,7 @@ def x11_setup_needed publish :function => :s390, :type => "boolean ()" publish :function => :ia64, :type => "boolean ()" publish :function => :x86_64, :type => "boolean ()" + publish :function => :aarch64, :type => "boolean ()" publish :function => :arch_short, :type => "string ()" publish :function => :board_compatible, :type => "string ()" publish :function => :board_mac, :type => "boolean ()" diff --git a/library/general/test/Makefile.am b/library/general/test/Makefile.am index 4896e7e1c..541bde147 100644 --- a/library/general/test/Makefile.am +++ b/library/general/test/Makefile.am @@ -1,9 +1,12 @@ TESTS = \ asciifile_test.rb \ + auto_client_test.rb \ + finish_client_test.rb \ hooks_test.rb \ linuxrc_test.rb \ os_release_test.rb \ popup_test.rb \ + proposal_client_test.rb \ agents_test/proc_meminfo_agent_test.rb TEST_EXTENSIONS = .rb diff --git a/library/general/test/asciifile_test.rb b/library/general/test/asciifile_test.rb index 249b264d1..bd3db5fbd 100755 --- a/library/general/test/asciifile_test.rb +++ b/library/general/test/asciifile_test.rb @@ -1,8 +1,7 @@ #! /usr/bin/env rspec -require File.expand_path("../test_helper.rb", __FILE__) +require_relative "test_helper" -require "yast" include Yast Yast.import "AsciiFile" diff --git a/library/general/test/auto_client_test.rb b/library/general/test/auto_client_test.rb new file mode 100755 index 000000000..91aadc9e6 --- /dev/null +++ b/library/general/test/auto_client_test.rb @@ -0,0 +1,176 @@ +#! /usr/bin/env rspec + +require_relative "test_helper" + +require "installation/auto_client" + +class TestAuto < ::Installation::AutoClient + def import(args) + args.empty? ? "import" : args + end + + ["export", "summary", "reset", "change", "write", "packages", "read", "modified?", "modified"].each do |m| + define_method(m.to_sym) { m } + end +end + +describe ::Installation::AutoClient do + subject { ::TestAuto } + describe ".run" do + it "raise ArgumentError exception if unknown first argument is passed" do + allow(Yast::WFM).to receive(:Args).and_return(["Unknown", {}]) + expect{::Installation::AutoClient.run}.to raise_error(ArgumentError) + end + + context "first client argument is Import" do + before do + allow(Yast::WFM).to receive(:Args).and_return(["Import", {}]) + end + + it "dispatch call to abstract method import" do + expect(subject.run).to eq "import" + end + + it "passes argument hash to abstract method" do + test_params = { :a => :b, :c => :d } + allow(Yast::WFM).to receive(:Args).and_return(["Import", test_params]) + + expect(subject.run).to eq test_params + end + + it "raise NotImplementedError exception if abstract method not defined" do + expect{::Installation::AutoClient.run}.to raise_error(NotImplementedError) + end + end + + context "first client argument is Export" do + before do + allow(Yast::WFM).to receive(:Args).and_return(["Export", {}]) + end + + it "dispatch call to abstract method export" do + expect(subject.run).to eq "export" + end + + it "raise NotImplementedError exception if abstract method not defined" do + expect{::Installation::AutoClient.run}.to raise_error(NotImplementedError) + end + end + + context "first client argument is Summary" do + before do + allow(Yast::WFM).to receive(:Args).and_return(["Summary", {}]) + end + + it "dispatch call to abstract method summary" do + expect(subject.run).to eq "summary" + end + + it "raise NotImplementedError exception if abstract method not defined" do + expect{::Installation::AutoClient.run}.to raise_error(NotImplementedError) + end + end + + context "first client argument is Reset" do + before do + allow(Yast::WFM).to receive(:Args).and_return(["Reset", {}]) + end + + it "dispatch call to abstract method reset" do + expect(subject.run).to eq "reset" + end + + it "raise NotImplementedError exception if abstract method not defined" do + expect{::Installation::AutoClient.run}.to raise_error(NotImplementedError) + end + end + + context "first client argument is Change" do + before do + allow(Yast::WFM).to receive(:Args).and_return(["Change", {}]) + end + + it "dispatch call to abstract method change" do + expect(subject.run).to eq "change" + end + + it "raise NotImplementedError exception if abstract method not defined" do + expect{::Installation::AutoClient.run}.to raise_error(NotImplementedError) + end + end + + context "first client argument is Write" do + before do + allow(Yast::WFM).to receive(:Args).and_return(["Write", {}]) + end + + it "dispatch call to abstract method write" do + expect(subject.run).to eq "write" + end + + it "raise NotImplementedError exception if abstract method not defined" do + expect{::Installation::AutoClient.run}.to raise_error(NotImplementedError) + end + end + + context "first client argument is Read" do + before do + allow(Yast::WFM).to receive(:Args).and_return(["Read", {}]) + end + + it "dispatch call to abstract method read" do + expect(subject.run).to eq "read" + end + + it "raise NotImplementedError exception if abstract method not defined" do + expect{::Installation::AutoClient.run}.to raise_error(NotImplementedError) + end + end + + context "first client argument is GetModified" do + before do + allow(Yast::WFM).to receive(:Args).and_return(["GetModified", {}]) + end + + it "dispatch call to abstract method modified?" do + expect(subject.run).to eq "modified?" + end + + it "raise NotImplementedError exception if abstract method not defined" do + expect{::Installation::AutoClient.run}.to raise_error(NotImplementedError) + end + end + + context "first client argument is SetModified" do + before do + allow(Yast::WFM).to receive(:Args).and_return(["SetModified", {}]) + end + + it "dispatch call to abstract method modified" do + expect(subject.run).to eq "modified" + end + + it "raise NotImplementedError exception if abstract method not defined" do + expect{::Installation::AutoClient.run}.to raise_error(NotImplementedError) + end + end + + context "first client argument is Packages" do + before do + allow(Yast::WFM).to receive(:Args).and_return(["Packages", {}]) + end + + it "dispatch call to abstract method packages" do + expect(subject.run).to eq "packages" + end + + it "just log if optional abstract method not defined" do + expect{::Installation::AutoClient.run}.to_not raise_error + end + + it "returns empty array if optional abstract method not defined" do + expect(::Installation::AutoClient.run).to eq [] + end + end + end +end diff --git a/library/general/test/finish_client_test.rb b/library/general/test/finish_client_test.rb new file mode 100755 index 000000000..21e8e0b86 --- /dev/null +++ b/library/general/test/finish_client_test.rb @@ -0,0 +1,53 @@ +#! /usr/bin/env rspec + +require_relative "test_helper" + +require "installation/finish_client" + +class TestFinish < ::Installation::FinishClient + def info + "info" + end + + def write + "write" + end +end + +describe ::Installation::FinishClient do + subject { ::TestFinish } + describe ".run" do + it "raise ArgumentError exception if unknown first argument is passed" do + allow(Yast::WFM).to receive(:Args).and_return(["Unknown", {}]) + expect{::Installation::FinishClient.run}.to raise_error(ArgumentError) + end + + context "first client argument is Info" do + before do + allow(Yast::WFM).to receive(:Args).and_return(["Info"]) + end + + it "dispatch call to abstract method info" do + expect(subject.run).to eq "info" + end + + it "raise NotImplementedError exception if abstract method not defined" do + expect{::Installation::FinishClient.run}.to raise_error(NotImplementedError) + end + end + + context "first client argument is Write" do + before do + allow(Yast::WFM).to receive(:Args).and_return(["Write"]) + end + + it "dispatch call to abstract method write" do + expect(subject.run).to eq "write" + end + + it "raise NotImplementedError exception if abstract method not defined" do + expect{::Installation::FinishClient.run}.to raise_error(NotImplementedError) + end + end + end +end diff --git a/library/general/test/hooks_test.rb b/library/general/test/hooks_test.rb index 65364249c..075887112 100755 --- a/library/general/test/hooks_test.rb +++ b/library/general/test/hooks_test.rb @@ -1,8 +1,6 @@ #! /usr/bin/env rspec -require File.expand_path("../test_helper.rb", __FILE__) - -require "yast" +require_relative "test_helper" module Yast import 'Hooks' diff --git a/library/general/test/linuxrc_test.rb b/library/general/test/linuxrc_test.rb index 9592d8a22..acfd705b9 100755 --- a/library/general/test/linuxrc_test.rb +++ b/library/general/test/linuxrc_test.rb @@ -1,8 +1,7 @@ #!/usr/bin/env rspec -require File.expand_path("../test_helper.rb", __FILE__) +require_relative "test_helper" -require "yast" include Yast Yast.import "Linuxrc" diff --git a/library/general/test/os_release_test.rb b/library/general/test/os_release_test.rb index d4490ee84..595d85da0 100755 --- a/library/general/test/os_release_test.rb +++ b/library/general/test/os_release_test.rb @@ -1,8 +1,6 @@ #! /usr/bin/env rspec -require File.expand_path("../test_helper.rb", __FILE__) - -require "yast" +require_relative "test_helper" Yast.import "OSRelease" Yast.import "FileUtils" diff --git a/library/general/test/popup_test.rb b/library/general/test/popup_test.rb index ca908e14b..6ca28844e 100755 --- a/library/general/test/popup_test.rb +++ b/library/general/test/popup_test.rb @@ -1,8 +1,7 @@ #! /usr/bin/env rspec -require File.expand_path("../test_helper.rb", __FILE__) +require_relative "test_helper" -require "yast" include Yast Yast.import "Popup" diff --git a/library/general/test/proposal_client_test.rb b/library/general/test/proposal_client_test.rb new file mode 100755 index 000000000..01bb970fc --- /dev/null +++ b/library/general/test/proposal_client_test.rb @@ -0,0 +1,89 @@ +#! /usr/bin/env rspec + +require_relative "test_helper" + +require "installation/proposal_client" + +class TestProposal < ::Installation::ProposalClient + def make_proposal(args) + args.empty? ? "make_proposal" : args + end + + def ask_user(args) + args.empty? ? "ask_user" : args + end + + def description + "description" + end + + def write(args) + args.empty? ? "write" : args + end +end + +describe ::Installation::ProposalClient do + subject { ::TestProposal } + describe ".run" do + it "raise ArgumentError exception if unknown first argument is passed" do + allow(Yast::WFM).to receive(:Args).and_return(["Unknown", {}]) + expect{::Installation::ProposalClient.run}.to raise_error(ArgumentError) + end + + context "first client argument is MakeProposal" do + before do + allow(Yast::WFM).to receive(:Args).and_return(["MakeProposal", {}]) + end + + it "dispatch call to abstract method make_proposal" do + expect(subject.run).to eq "make_proposal" + end + + it "passes argument hash to abstract method" do + test_params = { :a => :b, :c => :d } + allow(Yast::WFM).to receive(:Args).and_return(["MakeProposal", test_params]) + + expect(subject.run).to eq test_params + end + + it "raise NotImplementedError exception if abstract method not defined" do + expect{::Installation::ProposalClient.run}.to raise_error(NotImplementedError) + end + end + + context "first client argument is AskUser" do + before do + allow(Yast::WFM).to receive(:Args).and_return(["AskUser", {}]) + end + + it "dispatch call to abstract method ask_user" do + expect(subject.run).to eq "ask_user" + end + + it "passes argument hash to abstract method" do + test_params = { :a => :b, :c => :d } + allow(Yast::WFM).to receive(:Args).and_return(["AskUser", test_params]) + + expect(subject.run).to eq test_params + end + + it "raise NotImplementedError exception if abstract method not defined" do + expect{::Installation::ProposalClient.run}.to raise_error(NotImplementedError) + end + end + + context "first client argument is Description" do + before do + allow(Yast::WFM).to receive(:Args).and_return(["Description", {}]) + end + + it "dispatch call to abstract method description" do + expect(subject.run).to eq "description" + end + + it "raise NotImplementedError exception if abstract method not defined" do + expect{::Installation::ProposalClient.run}.to raise_error(NotImplementedError) + end + end + end +end diff --git a/library/general/test/test_helper.rb b/library/general/test/test_helper.rb index a18ab1583..7e7b4920e 100644 --- a/library/general/test/test_helper.rb +++ b/library/general/test/test_helper.rb @@ -1,8 +1,9 @@ - top_srcdir = File.expand_path("../../../..", __FILE__) inc_dirs = Dir.glob("#{top_srcdir}/library/*/src") ENV["Y2DIR"] = inc_dirs.join(":") +require "yast" + def set_root_path(directory) check_version = false handle = Yast::WFM.SCROpen("chroot=#{directory}:scr", check_version) diff --git a/library/packages/src/modules/PackageCallbacks.rb b/library/packages/src/modules/PackageCallbacks.rb index 70632b302..f5e80f0ad 100644 --- a/library/packages/src/modules/PackageCallbacks.rb +++ b/library/packages/src/modules/PackageCallbacks.rb @@ -2777,8 +2777,9 @@ def ProcessStart(task, stages, help) opened = true end - # set 100% as max value - Progress.New(task, "", 100, stages, [], help) + # set 100 + number of stages as the max value, + # Progress module counts stages as extra steps + Progress.New(task, "", 100 + stages.size, stages, [], help) Progress.Title(task) @last_stage = 0 end diff --git a/library/system/src/desktop/messages.desktop b/library/system/src/desktop/messages.desktop index 2d8871cf7..15ba7395f 100644 --- a/library/system/src/desktop/messages.desktop +++ b/library/system/src/desktop/messages.desktop @@ -5,7 +5,6 @@ Categories=Settings;System;Qt;X-SuSE-YaST;X-SuSE-YaST-Misc; X-KDE-ModuleType=Library X-KDE-RootOnly=true X-KDE-HasReadOnlyMode=true -X-KDE-Library=yast2 X-SuSE-YaST-Call=view_anymsg X-SuSE-YaST-Group=Misc diff --git a/library/system/src/modules/Kernel.rb b/library/system/src/modules/Kernel.rb index 4f2d6fb9a..2e508fbb8 100644 --- a/library/system/src/modules/Kernel.rb +++ b/library/system/src/modules/Kernel.rb @@ -214,6 +214,11 @@ def ExtractCmdlineParameters(line) discardlist = Builtins.add(discardlist, "ramdisk_size") end + # get rid of live-installer-specific parameters + if Mode.live_installation + discardlist.push("initrd", "ramdisk_size", "ramdisk_blocksize", "liveinstall", "splash", "quiet", "lang") + end + # backdoor to re-enable update on UL/SLES if Builtins.contains(cmdlist, "suse_update") discardlist = Builtins.add(discardlist, "suse_update") @@ -247,7 +252,14 @@ def ExtractCmdlineParameters(line) def ParseInstallationKernelCmdline @cmdline_parsed = true return if !(Stage.initial || Stage.cont) - tmp = Convert.to_string(SCR.Read(path(".etc.install_inf.Cmdline"))) + # live installation does not create /etc/install.inf (bsc#793065) + if Mode.live_installation + # not using dedicated agent in order to use the same parser for cmdline + # independently on whether it comes from /proc/cmdline or /etc/install.inf + tmp = Convert.to_string(SCR.Read(path(".target.string"), "/proc/cmdline")) + else + tmp = Convert.to_string(SCR.Read(path(".etc.install_inf.Cmdline"))) + end Builtins.y2milestone( "cmdline from install.inf is: %1", diff --git a/package/yast2.changes b/package/yast2.changes index 89de23a47..141c971c2 100644 --- a/package/yast2.changes +++ b/package/yast2.changes @@ -1,3 +1,47 @@ +------------------------------------------------------------------- +Tue Jan 13 13:43:40 UTC 2015 - cwh@suse.com + +- Use native Ruby implementation (IPAddr) for Yast::IP. +- 3.1.116 + +------------------------------------------------------------------- +Wed Jan 7 10:55:13 UTC 2015 - jsrain@suse.cz + +- keep kernel cmdline options during live installation (bsc#793065) + +------------------------------------------------------------------- +Thu Dec 18 19:55:46 UTC 2014 - lslezak@suse.cz + +- 3.1.115 + +------------------------------------------------------------------- +Wed Dec 17 14:00:42 UTC 2014 - schwab@suse.de + +- Add Arch.aarch64 + +------------------------------------------------------------------- +Thu Dec 4 09:51:50 UTC 2014 - jreidinger@suse.com + +- remove X-KDE-Library from desktop file (bnc#899104) + +------------------------------------------------------------------- +Mon Dec 1 12:23:34 UTC 2014 - lslezak@suse.cz + +- PackageCallbacks: fixed progress reporting (progress overflow was + caused by missing stage count) +- 3.1.113 + +------------------------------------------------------------------- +Wed Nov 26 09:49:19 UTC 2014 - jreidinger@suse.com + +- Add base class for installation proposal and finish clients +- 3.1.112 + +------------------------------------------------------------------- +Wed Nov 26 09:31:55 UTC 2014 - gber@opensuse.org + +- remove support for the unmaintained GTK UI plugin (bnc#901511) + ------------------------------------------------------------------- Wed Nov 12 14:04:51 UTC 2014 - lslezak@suse.cz diff --git a/package/yast2.spec b/package/yast2.spec index fd80c70af..a0277c534 100644 --- a/package/yast2.spec +++ b/package/yast2.spec @@ -17,7 +17,7 @@ Name: yast2 -Version: 3.1.110 +Version: 3.1.116 Release: 0 URL: https://github.com/yast/yast-yast2 diff --git a/remote/remotechooser.desktop b/remote/remotechooser.desktop index db1f95ab9..289b4f2cb 100644 --- a/remote/remotechooser.desktop +++ b/remote/remotechooser.desktop @@ -4,7 +4,6 @@ Categories=Settings;System;Qt;X-SuSE-YaST;X-SuSE-YaST-Misc; X-KDE-ModuleType=Library X-KDE-HasReadOnlyMode=true -X-KDE-Library=yast2 X-SuSE-YaST-Call=remotechooser X-SuSE-YaST-Group=Misc diff --git a/remote/remoteinstall.desktop b/remote/remoteinstall.desktop index cc3534583..800479c73 100644 --- a/remote/remoteinstall.desktop +++ b/remote/remoteinstall.desktop @@ -4,7 +4,6 @@ Categories=Settings;System;Qt;X-SuSE-YaST;X-SuSE-YaST-Misc; X-KDE-ModuleType=Library X-KDE-HasReadOnlyMode=true -X-KDE-Library=yast2 X-SuSE-YaST-Call=remoteinstall X-SuSE-YaST-Group=Misc diff --git a/scripts/yast2 b/scripts/yast2 index b19cae355..c162f6d8f 100755 --- a/scripts/yast2 +++ b/scripts/yast2 @@ -140,37 +140,25 @@ select_gui_frontend() { if [ "$WANTED_GUI" = "auto" ]; then probe_desktop_gui - WANTED_GUI=$DESKTOP_GUI + WANTED_GUI=qt GUI_SELECTION=auto fi if [ "$WANTED_GUI" = "gtk" ]; then - if check_gtk; then - SELECTED_GUI=gtk - else - if check_qt; then - SELECTED_GUI=qt - WANTED_GUI=qt - if [ "$GUI_SELECTION" != "auto" ]; then - echo >&2 "GTK GUI wanted but not found, falling back to Qt." - fi - else - echo >&2 "GTK GUI wanted but not found, falling back to ncurses." + if check_qt; then + SELECTED_GUI=qt + WANTED_GUI=qt + if [ "$GUI_SELECTION" != "auto" ]; then + echo >&2 "The GTK GUI has been retired, falling back to Qt." fi + else + echo >&2 "The GTK GUI has been retired, falling back to ncurses." fi elif [ "$WANTED_GUI" = "qt" ]; then if check_qt; then SELECTED_GUI=qt else - if check_gtk; then - SELECTED_GUI=gtk - WANTED_GUI=gtk - if [ "$GUI_SELECTION" != "auto" ]; then - echo >&2 "Qt GUI wanted but not found, falling back to GTK." - fi - else - echo >&2 "Qt GUI wanted but not found, falling back to ncurses." - fi + echo >&2 "Qt GUI wanted but not found, falling back to ncurses." fi elif [ "$SELECTED_GUI" != "gtk" -a "$WANTED_GUI" != "ncurses" ]; then echo >&2 "Unknown GUI '$WANTED_GUI', falling back to ncurses." @@ -391,11 +379,9 @@ if [ "$SELECTED_GUI" = "ncurses" ]; then echo "Something is wrong with the YaST user interface, NCurses selected but no terminal available." >&2 exit_code=1 # also skips y2base later fi -elif [ "$SELECTED_GUI" = "qt" -o "$SELECTED_GUI" = "gtk" ]; then +elif [ "$SELECTED_GUI" = "qt" ]; then - if [ "$SELECTED_GUI" = "qt" ]; then - set_qt_home_dir - fi + set_qt_home_dir # find which control center shell we want, if there is none we # fall back to the built-in ycp menu diff --git a/scripts/yast2-funcs b/scripts/yast2-funcs index a657d170b..290a4529e 100644 --- a/scripts/yast2-funcs +++ b/scripts/yast2-funcs @@ -68,14 +68,6 @@ function check_qt() check_libyui_plugin qt || check_plugin libpy2qt.so.2 "the qt frontend" } -# -# check if the gtk plugin and all necessary libraries are present -# -function check_gtk() -{ - check_libyui_plugin gtk || check_plugin libpy2gtk.so.2 "the gtk frontend" -} - # # check if the ncurses plugin and all necessary libraries are present #