library/general/src/lib/installation/auto_client.rb
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}.
#
# The workflow for interactive editing in the UI
# (`Mode.config == true`, see {Yast::ModeClass})
# is more complicated. The user can choose to perform any action, and
# a corresponding method is called:
#
# - {#summary}: clicking on the icon of the module.
# - {#reset}: clicking Clear.
# - if the user clicks to Edit a module, at first {#export} is called,
# then {#change} is called for UI interaction, which can end up
# in multiple situations:
# - if cancelled/aborted, {#import} is called (on the previous result of
# {#export})
# - otherwise {#export} is called. If the output is different from the
# previous call, then {#modified} is called.
# - {#write}: clicking Apply to System.
# - {#read}: clicking Clone.
# - {#import}: selecting File/Open to load an autoyast profile
# - it calls {#modified?} to recognize if a given module is modified and needs
# its section with content of {#export} when saving the profile
# - the order of all calls is independent, so the client should not depend
# on a certain order unless it is defined here as a workflow call
#
#
# @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
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"
target = param["target"] if param.is_a?(Hash)
target ||= "default"
m = method(:export)
m.arity.zero? ? export : export(target: target.to_sym)
when "Summary"
summary
when "Reset"
reset
nil # return type is ignored, so always return nil to avoid issues with ycp component system
when "Change"
change
when "Write"
write
when "Packages"
packages
when "Read"
read
nil # return type is ignored, so always return nil to avoid issues with ycp component system
when "GetModified"
modified?
when "SetModified"
modified
nil # return type is ignored, so always return nil to avoid issues with ycp component system
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`
# @param target [Symbol] Control how much information should be exported
# (e.g., :default or :compact).
# @return [Hash, Array] profile data
def export(target:)
raise NotImplementedError, "Calling abstract method 'export' with target '#{target}'"
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
# Return a hash with packages that need to be installed or removed for
# configuration.
#
# @example
#
# def packages
# { "install" => ["package1"], "remove" => ["package2"] }
# end
#
# The default implementation returns an empty hash.
# @return [Hash] of packages to be installed and removed
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