Class: Installation::ProposalClient

Inherits:
Yast::Client
  • Object
show all
Includes:
Yast::Logger
Defined in:
library/general/src/lib/installation/proposal_client.rb

Overview

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 ProposalClient as base class for new clients.

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

The Write method

In addition to the methods defined (and documented) in ProposalClient, there's a method called Write which will write the proposed (and probably modified) settings to the system.

It is up to the proposal dispatcher how it remembers the settings. The errors must be reported using the Report:: module to have the possibility to control the behaviour from the main program.

This Write method is optional. The dispatcher module is required to allow this method to be called without returning an error value if it is not there.

Return Values

Returns true, if the settings were written successfully.

Examples:

how to run a client

require "installation/example_proposal"
::Installation::ExampleProposal.run

See Also:

  • example client in installation clone_proposal.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.runObject

The entry point for calling a client. The only part needed in client rb file.

Returns:

  • response from abstract methods


75
76
77
# File 'library/general/src/lib/installation/proposal_client.rb', line 75

def self.run
  new.run
end

Instance Method Details

#ask_user(_attrs) ⇒ Hash (protected)

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.

Parameters:

  • attrs (Hash)

    a customizable set of options

Returns:

  • (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.

Raises:

  • (NotImplementedError)

249
250
251
# File 'library/general/src/lib/installation/proposal_client.rb', line 249

def ask_user(_attrs)
  raise NotImplementedError, "Calling abstract method 'ask_user'"
end

#descriptionHash (protected)

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.

Returns:

  • (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 <h3><a href="#???"> ... </a></h3> 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.

Raises:

  • (NotImplementedError)

283
284
285
# File 'library/general/src/lib/installation/proposal_client.rb', line 283

def description
  raise NotImplementedError, "Calling abstract method 'description'"
end

#make_proposal(_attrs) ⇒ Hash (protected)

Abstract method to create proposal suggestion for installation

Examples:

Triggers definition

{
  "trigger" => {
    "expect" => {
      "class"  => "Yast::Packages",
      "method" => "CountSizeToBeDownloaded"
    },
    "value" => 88883333
  }
}

Parameters:

  • attrs (Hash)

    a customizable set of options

Returns:

  • (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::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 (<li>). The proposal can contain hyperlinks with IDs listed in the list links.

    • "label_proposal" [Array, nil] --- (only used for simple_mode) Human readable proposal. The caller will format each item as Label.

    • "warning" [String, nil] --- Warning in human readable format without HTML tags other than \<br>. 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. Error does not prevent continuing of the installation, but shows a popup that an user has to confirm to continue with the installation.

    • "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).

    • "trigger" [Hash, nil] defines circumstances when the proposal should be called again at the end. For instance, when partitioning or software selection changes. Mandatory keys of the trigger are:

      • "expect" [Hash] containing string class and string method that will be called and its result compared with value.
      • "value" [Object] expected value, if evaluated code does not match the value, proposal will be called again.

Raises:

  • (NotImplementedError)

197
198
199
# File 'library/general/src/lib/installation/proposal_client.rb', line 197

def make_proposal(_attrs)
  raise NotImplementedError, "Calling abstract method 'make_proposal'"
end

#runObject

Dispatches to abstract method based on passed Arguments to client


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'library/general/src/lib/installation/proposal_client.rb', line 80

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
  else
    raise ArgumentError, "Invalid action for proposal '#{func.inspect}'"
  end
end

#writeObject (protected)


287
288
289
# File 'library/general/src/lib/installation/proposal_client.rb', line 287

def write  # doing nothing is OK. or is it? clarify the API, the docs, actual usage!

end