Product Installation Control

Functionality

The product control file is used to customize the installation process. It allows to enable and disable features and it defines the workflow, that is, what is really shown to the user during the installation.

Besides workflow configuration, other system variables are configurable and can be predefined by the system administrator. To name a few: the software selection, environment settings such as language, time zone and keyboard can be configured and would override default variables provided with shipped products.

The idea of having a pre-defined installation workflow and pre-defined system settings provides a middle ground between manual installation and automated installation.

The product configuration file is provided as a text file on the installation media and defines various settings needed during installation. The following is a list of supported configuration options:

  • Workflow

    Replaces the static workflow list with a configurable list using the product configuration file. Entire sections of the workflow can be skipped.

    For example, it is possible to set the language variable in the configuration file if the installation language is to be forced for some reason, e.g. if an IT department wants to force French installations, say in Quebec, Canada, then the entire dialog can be skipped. If the IT department is to recommend some settings but still give the user the choice to change the default settings, the language dialog will be shown with French preselected.

    If none of the above options is used, the default dialog settings are shown.

  • Proposals

    As with the workflow, proposals are also configurable. For example, certain products would skip some proposals. In the proposal screen the pre-configured settings can be shown with the possibility to change them or with inactive links if the configuration is to be forced.

  • System Variables

    This lets the user define system variables like language, keyboard, time zone, window manager, display manager etc. The defined variables will be used as defaults in the respective dialogs.

  • Package Selections and additional individual packages

    This defines what base package selection and add-on selections should be used for the installation. Additionally this provides the possibility to define a list of additional packages. All packages and selections can be selected depending on the architecture using a special architecture attribute in the configuration file.

  • Partitioning

    This is to customize disk usage, including minimum and maximum useful size of the root filesystem, what filesystem type to use, whether or not to use LVM and encryption, and what subvolumes to create if Btrfs is used on the root filesystem.

  • Network

    This is used to customize some network configuration defaults like IP forwarding, new connections startmode or the use of NetworkManager.

  • Scripting and Hooks

    To customize installation further more, hooks and special slots can be defined where the user can execute scripts. For example, scripts can be executed at the very beginning of the installation (After processing the configuration file), in the installation system before initial boot, in the chroot-ed environment and after initial boot and before/after every step in the workflow. Scripting languages supported during installation are currently Shell, Perl.

Implementation

The control file is implemented in simple structured XML syntax which so far has been used for automated installation. The XML structure used can be mapped easily to YaST data structures and all data types available in YaST are supported for easy data access and manipulation.

The primary use of the control file is to configure the workflow of the installation, and it offers the possibility to predefine a certain setup, but it also defines product installation features and other product related variables.

Note

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. The control file on the installed system located in /etc/YaST2/control.xml is owned by the ${PRODUCT}-release package.

During installation, linuxrc searches for a file named control.xml on the installation medium (CD, NFS, FTP..) and copies the file into the installation system and makes the file available to YaST. YaST then starts and looks for the control file in 3 locations before it starts with the installation workflow:

  1. custom control file - runtime specified control file. Used only in special cases like wagon upgrade work-flow.

  2. /y2update/control.xml

    File in special directory to update installer on-fly. Needed only for work-arounds and customer specific solutions.

  3. /control.xml

    Usually the file is in the top directory after it has been copied by linuxrc and during the initial installation phase.

  4. /etc/YaST2/control.xml

    This is the location where the release package installs the file of the installed product.

One of the main reasons for using the control is to provide non-YaST developers the ability to change the installation behavior and customize various settings without the need to change and re-build YaST packages.

This way it is possible to define different behavior and different installation defaults in SLE and openSUSE products.

The control files for SUSE products are maintained at specific Git repositories (e.g. for SLES, SLED or openSUSE ).

Configuration

Workflows

Using the control file, multiple workflows can be defined for different modes and installation stages. Thus, the element workflows in the control file evaluates to a list of workflows.

Beside defining what YaST clients should be executed during installation, the workflow configuration also lets you specify the wizard steps and how they should appear during graphical installation.

A workflow list element is a map with the following elements:

  • label

    The label of the workflow as it appears on the left side of the wizard. For example Base Installation.

  • defaults

    The default arguments to the clients. This is a map element.

  • stage

    This options defines the stage or phase of the installation. Possible values are initial for the initial stage and continue for the workflow of the installation after reboot.

  • mode

    Defines the installation mode. Several modes are available; the most important modes are:

    • installation
    • update
    • autoinst
  • modules

    This is the actual workflow and is a list of elements describing the order in which the installation should proceed.

    A module element is a map with the following configuration options:

    • name: The name of the module. All installation clients and modules have a unified prefix (inst_) which can be omitted here. The name is often used as an ID, so it should be unique within the whole control file. That is why there is the execute parameter (see below). For example, if the YaST file for the module is called inst_test, then the name in the control file is test.
    • label: The label of the module in the step dialog. This is an optional element. If it is not set, the label of the previous module is used.
    • arguments: The arguments for the module. This is a comma-separated list which can accept booleans and symbols.
    • execute: If it is needed to call a script with a name that does not start with inst_ or you need to call the same script several times with a different name parameter.

The following listing shows a typical installation workflow:

    <workflows config:type="list">
        <workflow>
            <!-- 'label' is what the user will see -->
            <label>Base Installation</label>
            <!-- default settings for all modules -->
            <defaults>
                <!-- arguments for the clients -->
                <arguments>false,false</arguments>
                <!-- allowed architectures "all", "i386", "i386,ia64,x86_64", see
                  Arch module in yast-yast2 for all possible options  -->
                <archs>all</archs>
            </defaults>
            <stage>initial</stage>
            <mode>installation,update</mode>
            <modules  config:type="list">
                <module>
                    <name>info</name>
                    <arguments>false,true</arguments>
                </module>
                <module>
                    <name>proposal</name>
                    <arguments>true,true,`ini</arguments>
                    <label>Installation Settings</label>
                </module>
                <module>
                    <name>do_resize</name>
                    <update config:type="boolean">false</update>
                    <archs>i386,x86_64,ia64</archs>
                    <label>Perform Installation</label>
                </module>
                <module>
                    <name>prepdisk</name>
                    <!-- Multiple modules with the same 'label' will be
                         collapsed to one single user-visible step.
                         The step is considered finished when the last module
                         with the same 'label' is finished.  -->
                    <label>Perform Installation</label>
                </module>
                <module>
                    <name>kickoff</name>
                    <label>Perform Installation</label>
                </module>
                <module>
                    <name>rpmcopy</name>
                    <label>Perform Installation</label>
                </module>
                <module>
                    <name>finish</name>
                    <label>Perform Installation</label>
                </module>
            </modules>
        </workflow>
    </workflows>

Proposals

Part of the installation workflows are proposal screens, which consist of a group of related configuration settings. For example Network, Hardware and the initial Installation proposal.

If you want for some reason to add or modify a proposal, which is discouraged because of configuration dependencies, then this would be possible using the control file.

<proposal>
    <label>Installation Settings</label>
    <mode>installation</mode>
    <stage>initial</stage>
    <name>initial</name>
    <unique_id>inst_initial</unique_id>
    <enable_skip>no</enable_skip>
    <proposal_modules config:type="list">
        <proposal_module>
            <name>bootloader</name>
            <presentation_order>20</presentation_order>
        </proposal_module>
        <proposal_module>
            <name>hwinfo</name>
            <presentation_order>80</presentation_order>
        </proposal_module>
        ...
    </proposal_modules>
</proposal>

Each proposal definition can contain these values:

<proposal_module>
    <name>module_name</name>
    <presentation_order>50</presentation_order>
    <read_only config:type="boolean">true</read_only>
</proposal_module>

Details:

  • name (string) - proposal client name without the _proposal suffix (the code actually allows writing it but that makes the definitions longer and less readable).
  • presentation_order (integer, optional) - the number defines the display order in the proposal. The absolute value is not important; it depends on the relative value when compared against the other proposal modules.
  • read_only (boolean, optional) - the module is treated as read only, and any user interaction with the proposal module is disabled.

In the workflow, the proposals are called as any workflow step with an additional argument identifying the proposal screen to be started. (`net for network, `hw for hardware and `service for service proposals. The following examples shows how the network proposal is called as a workflow step:

    <module>
        <label>Network</label>
        <name>proposal</name>
        <arguments>true,true,`net</arguments>
    </module>

Installation and Product Variables

It is possible to define some installation variables (language, timezone, keyboard,.. ) and force them in the proposal. The user will still be able to change them, however.

The following variables can be set:

  • Timezone

  • Language

  • Keyboard

  • Auto Login (not recommended for multi-user environments and server installations)

  • IO Scheduler

    The default is as.

  • Desktop Scheduler

The following example shows all options above:

    <globals>
        <enable_autologin config:type="boolean">true</enable_autologin>
        <language>de_DE</language>
        <timezone>Canada/Eastern</timezone>
        <use_desktop_scheduler config:type="boolean">true</use_desktop_scheduler>
        <io_scheduler>as</io_scheduler>
    </globals>

Special Installation and Product Variables

These options usually enable or disable some installation feature.

  • (boolean) enable_firewall - the firewall will proposed as either enabled or disabled in the network proposal.

  • (boolean) enable_clone - the cloning feature will be either enabled or disabled.

  • (integer) boot_timeout - Allows to specify a different boot timeout for product or system role. Default is 8.

  • (boolean) skip_language_dialog - the language dialog might be skipped (if language already selected).

  • (boolean) show_online_repositories - either shows or hides the "online repositories" feature check-box.

  • (boolean) root_password_as_first_user - automatically selects or deselects the checkbox that makes the users configuration set the password entered for a first user also for the user root. The default is false.

  • (boolean) enable_local_users - enable creating local user accounts during installation. If false, the corresponding dialog is skipped, and root_password_as_first_user is set to false as well. The default is true.

  • (boolean) enable_autoconfiguration - enables a check box in the dialog that offers to switch the automatic configuration either on or off. The default is false.

  • (boolean) autoconfiguration_default - defines a default value whether to use the automatic configuration. It works even if enable_autoconfiguration is turned off, but the user would not be able to change it. The default is false.

  • (string) base_product_license_directory - directory where the base-product licenses are stored (license.txt, license.de_DE.txt, ...).

  • (boolean) rle_offer_runlevel_4 - defines whether runlevel 4 should be offered in the Runlevel Editor. The default is false.

  • (boolean) enable_kdump - defines whether kdump is proposed as enabled in the installation proposal. The kdump_proposal client call has to be added to proposal; otherwise this variable does not have any effect.

  • (boolean) write_hostname_to_hosts - defines whether the currently assigned hostname is written to /etc/hosts with IPv4 address 127.0.0.2. The default is false.

  • (boolean) dhclient_set_hostname - defines the default of DHCLIENT_SET_HOSTNAME in /etc/sysconfing/network/dhcp which is preloading at the beginning of the installation. It can be disabled by linuxrc cmdline with sethostname=0.

  • (boolean) default_ntp_setup - the NTP configuration proposes a default ntp server if set to true. The default is false.

  • (string) polkit_default_privs - Sets /etc/sysconfig/security/POLKIT_DEFAULT_PRIVS to the defined value. If not set or empty, sysconfig is untouched.

  • (boolean) require_registration - Require registration of add-on product (ignored in the base product).

  • (boolean) readonly_timezone - The timezone cannot be changed by the user during installation or upgrade. The default value is determined using the timezone element in the globals section. If not specified, UTC will be used.

  • (boolean) readonly_language - The user only could change the language of the installer, but not for the installed system which will use en_US by default.

Installation Helpers

In the globals section, there are also helper variables for the installation and debugging:

  • save_instsys_content - this is a list of entries that should be copied from the installation system to the just installed system before the first stage is finished and the system reboots to the second stage.

    This example shows how the content of the /root/ directory is copied to the /root/inst-sys/ directory on the installed system:

    <globals>
        <save_instsys_content config:type="list">
            <save_instsys_item>
                <instsys_directory>/root/</instsys_directory>
                <system_directory>/root/inst-sys/</system_directory>
            </save_instsys_item>
        </save_instsys_content>
    </globals>
  • (boolean) debug_workflow - defines whether steps with the very same name in the workflow should not be collapsed. If true, those steps are not collapsed and a step ID is added after the step name. The default is false. This feature should be off in the production phase.

  • (boolean) debug_deploying - defines whether deploying should write more debug logs and some more debugging features in the workflow. The default is false. This feature should be off in the production phase.

Look & Feel

The globals section also offers some settings to configure the layout of the installer. There are three possible layouts:

  • With a left sidebar including the list of installation steps.
  • Without a sidebar and placing the title of the dialogs on the left side.
  • Without a sidebar and placing the title of the dialogs on top.

These settings can be used for configuring the layout:

  • (string) installation_ui - only accepts sidebar value. When used, the layout is configured to include a left sidebar with the installation steps. This setting is deprecated in favor of installation_layout.

  • installation_layout: this section includes a set of individual settings to configure the layout.

In the installation_layout section, these settings are available:

  • (string) mode - configures the layout mode and accepts these values: steps, title-on-left and title-on-top.
  • (boolean) banner - indicates whether a top banner should be included. The banner is typically used for placing a logo.

Note that installation_layout takes precedence over installation_ui. When nothing is configured, the default layout is rendered with title on the left and with the top banner (SLE flavor).

Examples

Some examples of different configurations and its visual result are shown below:

Example 1
<globals>
    <!-- installation_ui is ignored because installation_layout is used -->
    <installation_ui>sidebar</installation_ui>
    <installation_layout>
        <mode>title-on-top</mode>
        <banner config:type="boolean">true</banner>
    </installation_layout>
</globals>

Example 2
<globals>
    <!-- installation_ui is used because nothing is defined by installation_layout -->
    <installation_ui>sidebar</installation_ui>
    <installation_layout></installation_layout>
</globals>

Example 3
<globals>
    <installation_layout>
        <mode>steps</mode>
        <banner config:type="boolean">true</banner>
    </installation_layout>
</globals>

Example 4
<globals>
    <installation_layout>
        <mode>title-on-top</mode>
        <banner config:type="boolean">true</banner>
    </installation_layout>
</globals>

Example 5
<globals>
    <installation_layout>
        <mode>title-on-left</mode>
        <banner config:type="boolean">false</banner>
    </installation_layout>
</globals>

Software

The software section defines the selection of software during installation or update.

This is a list of supported entries in software:

  • default_desktop - defines a desktop selected by default during installation.

  • clone_install_recommended_default - Default entry for "install_recommended" in the 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:

  • delete_old_packages

    Do not delete old RPMs when updating.

  • delete_old_packages_reverse_list

    Inverts the delete_old_packages rule for products defined as list of regular expressions matching installed product name (SuSE-release).

    <!-- Delete old packages of all products but OES, SLES 9, SLE 10 and SLD 10 -->
    <software>
    <delete_old_packages config:type="boolean">true</delete_old_packages>
    <delete_old_packages_reverse_list config:type="list">
        <regexp_item>^UnitedLinux .*$</regexp_item>
        <regexp_item>^Novell Open Enterprise Server Linux.*</regexp_item>
        <regexp_item>^SUSE (LINUX|Linux) Enterprise Server 9$</regexp_item>
        <regexp_item>^SUSE (LINUX|Linux) Enterprise Server 9 .*$</regexp_item>
        <regexp_item>^SUSE (LINUX|Linux) Enterprise Server 10.*$</regexp_item>
        <regexp_item>^SUSE (LINUX|Linux) Enterprise Desktop 10.*$</regexp_item>
        <!-- Don't forget to define product itself (Service Pack) -->
        <regexp_item>^SUSE (LINUX|Linux) Enterprise Server 10 SP.*$</regexp_item>
        <regexp_item>^SUSE (LINUX|Linux) Enterprise Desktop 10 SP.*$</regexp_item>
    </delete_old_packages_reverse_list>
    </software>
  • silently_downgrade_packages

    Allows the packager to downgrade installed packages during the upgrade workflow.

  • silently_downgrade_packages_reverse_list

    Inverts the silently_downgrade_packages rule for products defined as list of regular expressions matching the installed product name (SuSE-release).

    <!-- For SLES10, packages are not downgraded -->
    <software>
    <silently_downgrade_packages config:type="boolean">true</silently_downgrade_packages>
    <silently_downgrade_packages_reverse_list config:type="list">
        <regexp_item>^SUSE (LINUX|Linux) Enterprise Server 10.*$</regexp_item>
    </silently_downgrade_packages_reverse_list>
    </software>
  • products_supported_for_upgrade

    List of known products supported for upgrade (SuSE-release). Old releases or other distributions will report a warning. All products (regular expressions) are matching the string which can be found in /etc/*-release file.

    Regular expressions in <regexp_item>s can contain standard regular expressions, such as

    • The circumflex ^ and the dollar sign \$ as boundary characters for strings
    • asterisk *, plus + and question mark ? for repeating or existence.
    • dot . as a wild-card character
    • square brackets [] for a list of possible characters
    • circle brackets () for listing possibilities
    • special all-locale class-expressions [:alnum:], [:alpha:], [:blank:], [:cntrl:], [:digit:], [:graph:], [:lower:], [:print:], [:punct:], [:space:], [:upper:], [:xdigit:]

    These regular expressions are evaluated as POSIX regex.

    <software>
        <products_supported_for_upgrade config:type="list">
            <regexp_item>^Novell LINUX Desktop 9.*</regexp_item>
            <regexp_item>^SUSE LINUX Enterprise Server 10.*</regexp_item>
            <regexp_item>^SUSE LINUX Enterprise Desktop 10.*</regexp_item>
            <regexp_item>^openSUSE .*</regexp_item>
        </products_supported_for_upgrade>
    </software>
    
  • online_repos_preselected

    Online Repositories are pre-selected by default to be used. This item can change the default behavior.

  • upgrade\/product_upgrades

    List of product upgrades where defined vendor changes are possible without asking the user for confirmation.

    <software>
        <upgrade>
            <!-- Do not ask for vendor change during this defined upgrades -->
            <product_upgrades config:type="list">
                <product_upgrade>
                    <from>openSUSE Leap</from>
                    <to>openSUSE Jump</to>
                    <compatible_vendors config:type="list">
                      <compatible_vendor>openSUSE</compatible_vendor>
                      <compatible_vendor>SUSE LLC</compatible_vendor>
                    </compatible_vendors>
                </product_upgrade>
        </product_upgrades>
        </upgrade>
    </software>
    

Supported Desktops

This part defines not only all the desktops for Desktop Selection dialog during installation, but also the default_desktop must be defined.

Example of supported desktops:

    <productDefines  xmlns="http://www.suse.com/1.0/yast2ns"
        xmlns:config="http://www.suse.com/1.0/configns">
        <software>

            <supported_desktops config:type="list">

                <one_supported_desktop>
                    <name>gnome</name>
                    <desktop>gnome</desktop>
                    <label_id>desktop_gnome</label_id>
                    <logon>gdm</logon>
                    <cursor>DMZ</cursor>
                    <packages>gdm</packages>
                    <order config:type="integer">1</order>
                    <patterns>gnome x11 base</patterns>
                    <icon>pattern-gnome</icon>
                    <description_id>description_gnome</description_id>
                </one_supported_desktop>

                <one_supported_desktop>
                    <name>kde</name>
                    <desktop>kde4</desktop>
                    <!-- Generic ID used in texts below -->
                    <label_id>desktop_kde</label_id>
                    <logon>kdm4</logon>
                    <cursor>DMZ</cursor>
                    <packages>kde4-kdm</packages>
                    <order config:type="integer">1</order>
                    <patterns>kde x11 base</patterns>
                    <icon>pattern-kde4</icon>
                    <!-- Generic ID used in texts below -->
                    <description_id>description_kde</description_id>
                </one_supported_desktop>

            </supported_desktops>

        </software>

        <texts>

            <desktop_gnome><label>GNOME</label></desktop_gnome>
            <!-- See 'desktop_kde' in 'supported_desktops' -->
            <desktop_kde><label>KDE 4.1</label></desktop_kde>

            <description_gnome><label>Some description</label></description_gnome>
            <!-- See 'description_kde' in 'supported_desktops' -->
            <description_kde><label>Some description</label></description_kde>

        </texts>
    </productDefines>

The supported_desktops section contains a list of one or more one_supported_desktop sections.

  • (string) name

    Unique ID.

  • (string) desktop

    Desktop to start (gnome, kde4, kde, xfce, ...).

  • (string) label_id

    Text ID used for desktop selection label.

  • (string) logon

    Login manager to start (gdm, kdm4, kdm3, xdm, ...).

  • (string) cursor

    Cursor theme.

  • (string) packages

    List of packages (whitespace-separated) that identify and verify which desktop was selected by the user (or automatically). These packages are not selected for installation by Yast; use patterns for that.

  • (integer) order

    Numeric order of the desktop in the Desktop Selection dialog. Number 1 is reserved for major desktops that are displayed with description (description_id is required). If the very same order is used for more than one desktops, they are sorted alphabetically.

  • (string) patterns

    Software patterns to select for a particular desktop (whitespace-separated). These patterns are optional and will not be reported as an error by the software proposal if missing.

  • (string) icon

    Icon used in Desktop Selection dialog. This is just the name of an icon from \$current_theme/icons/64x64/apps/ directory, without the .png suffix.

  • (string) description_id

    Text ID used for the desktop selection label.

System Roles

System Roles, if defined in the control file, are presented during the first stage of the installation. The user will select one of them, and they will affect the proposed configuration of partitioning, network and software. It also allows to modify the configuration of systemd services.

A role can also define additional dialogs that are shown when a given role is selected. It is a common installation dialog with Abort, Cancel and Next buttons. It supports and uses all parameters from the GetInstArgs module. When going back, it will first show the last additional dialog; when going back through all additional dialogs, it will show the roles selection again.

System roles by default preselect the first defined entry, unless the user sets it. If the first role has an attribute no_default then no role will be preselected.

Example snippet for no_default:

<system_roles config:type="list">
  <system_role>
    <id>plain</id>
    <no_default config:type="boolean"> true </no_default>
  </system_role>
<system_roles>

They were requested in FATE#317481 and they are an evolution of the earlier concept of Server Scenarios used in SLE 11. The server scenarios were dropped.

Example:

<productDefines  xmlns="http://www.suse.com/1.0/yast2ns"
    xmlns:config="http://www.suse.com/1.0/configns">
    <!-- ... -->
    <system_roles config:type="list">
      <system_role>
        <id>plain</id>
        <!-- nothing else here, no overrides -->
      </system_role>

      <system_role>
        <id>virtualization_host_kvm</id>
        <!-- partitioning override -->
        <partitioning>
          <proposal>
            <lvm config:type="boolean">true</lvm>
          </proposal>
        </partitioning>
        <!-- software override -->
        <software>
          <default_patterns>base Minimal kvm_server</default_patterns>
        </software>
        <!-- a few additional dialogs are needed for this role -->
        <additional_dialogs>kvm_setup,virt_manager_setup </additional_dialogs>
        <!-- enable a few additional services -->
        <services config:type="list">
          <service>
            <name>salt-minion</name>
          </service>
          <service>
            <name>devil-master</name>
          </service>
        </services>
        <network>
          <ipv4_forward config:type="boolean">true</ipv4_forward>
          <ipv6_forward config:type="boolean">true</ipv6_forward>
        </network>
      </system_role>
    </system_roles>

    <texts>
      <!-- Caption of the whole dialog -->
      <roles_caption><label>System Role</label></roles_caption>
      <!-- A few lines of text above the selection of the roles -->
      <roles_text>
        <label>System Roles are predefined use cases which adjust the system
to be installed tailored for the selected scenario.
Choose the one which matches your system best.</label>
      </roles_text>
      <!-- Help text of the roles dialog -->
      <roles_help>
        <label>&lt;p&gt;The system roles adjustments are in the range from package selection up
to disk partitioning. By choosing a system role, the system is
configured accordingly to match the use case of the role. The settings
defined by a role can be overridden in the next steps if necessary.&lt;/p&gt;</label>
      </roles_help>



      <plain><label>General Server</label></plain>
      <plain_description>
        <label>Suitable for physical machines.</label>
      </plain_description>
      <virtualization_host_kvm>
        <label>KVM Virtualization Host</label>
      </virtualization_host_kvm>
      <virtualization_host_kvm_description>
        <label>Will install the appropriate packages.
Will use LVM disk layout.</label>
      </virtualization_host_kvm_description>
    </texts>
</productDefines>

Each role has a short label and a few lines of description in the texts section, identified by a matching id element. The contents of partitioning, network, software and globals are merged with the corresponding top-level definitions. See Partitioning, Network and Software.

The services part currently only supports enabling additional services which is done by specifying service with its name as seen in the example.

Partitioning

The partitioning section contains settings used to define how the local storage system should be configured. On its more external level it contains just one setting:

  • expert_partitioner_warning *(boolean, default: false) If true, an extra warning pop-up is displayed if the user enters the expert partitioner during installation.

In addition to that, there are two subsections: proposal and volumes.

The proposal subsection

The proposal subsection is used to configure some general aspects of the storage proposal (referenced as "Guided Setup" in the UI). In order to fully understand this section and its implications is important to have read and understood the section titled "How the proposal distributes the space" in the proposal document at the yast-storage-ng repository.

This subsection contains the following options.

  • lvm (boolean, default: false) Whether LVM should be used by default.
  • separate_vgs (boolean, default: false) Whether every volume specifying a separate_vg_name should be created as isolated LVM Volume Group instead include them in the "system" group.
  • allocate_volume_mode (auto, device, default: auto) When set to auto, the proposal expects a set of candidate disks in which it will distribute the volumes automatically as needed. If set to device, the proposal needs to know in which disk must place each volume. As a consequence, the interface presented to the user by default will be different (containing different questions) depending of the value of this property.
  • multidisk_first (boolean, default: false) When set to true, the initial proposal considers all disks as possible destination for the volumes to allocate. If set to false, the proposal tries to use individual disks to allocate the volumes, and it only uses all disks together when the volumes cannot be allocated in any individual disk.
  • delete_resize_configurable (boolean, default: true) Whether the user can modify the options related to delete or resize partitions. When this option is set to false, the user cannot change the value of windows_delete_mode, linux_delete_mode, other_delete_mode and resize_windows.
  • windows_delete_mode (none, ondemand, all, default: ondemand) Default value for the automatic delete mode for Windows partitions. It can be none, all or ondemand. For more information, see the description of the new proposal above.
  • linux_delete_mode (none, ondemand, all, default: ondemand) Default value for the automatic delete mode for Linux partitions. Again, it can be none, all or ondemand.
  • other_delete_mode (none, ondemand, all, default: ondemand) Default value for the automatic delete mode for other partitions. Once again, it can be none, all or ondemand.
  • resize_windows (boolean, default: true) Default value for the user setting deciding whether to resize Windows systems if needed.
  • lvm_vg_strategy (use_available, use_needed, default: use_available) If the user decides to use LVM, strategy to decide the size of the volume group (and, thus, the number and size of created physical volumes). There are three possible values.
    • use_available The VG will be created to use all the available space, thus the VG size could be greater than the sum of LVs sizes.
    • use_needed The created VG will match the requirements 1:1, so its size will be exactly the sum of all the LVs sizes.
    • use_vg_size FIXME: this is not implemented so far The VG will have exactly the size specified in lvm_vg_size.
  • lvm_vg_size FIXME: this is not implemented so far Specifies the predefined size of the LVM volume group if lvm_vg_strategy is use_vg_size.

The volumes subsection

The volumes subsection is responsible of specifying the partitions (or logical volumes if LVM is chosen) to create during the proposal and also the behavior of the expert partitioner regarding them.

It is a collection of volume subsections, each of them with the options listed here. Having read the document mentioned above about the proposal behavior may be important to fully understand some of them.

  • mount_point (string, no default value) Directory where the volume will be mounted in the system.
  • mount_options (string, no default value) Fstab options separated by comma. If this option is not given, then YaST will set default mount options depending on the mount point and the filesystem type.
  • proposed (boolean, default: true) Default value of the user setting deciding whether this volume should be created or skipped.
  • proposed_configurable (boolean, default: false) Whether the user can change the previous setting in the UI. I.e. whether the user can activate/deactivate the volume. Of course, setting proposed to false and proposed_configurable also to false has the same effect than deleting the whole <volume> entry.
  • fs_types (string, default: internal fallback list for '/' and '/home' volumes, empty list otherwise. In addition, the value of 'fs_type' is always included in the list) A collection of acceptable file system types. If no list is given, YaST will use a fallback based on the mount point.
  • fs_type (string, no default value) Default file system type to format the volume.
  • desired_size (disksize, default: 0 B) Initial size to use in the first proposal attempt.
  • min_size (disksize, default: 0 B) Initial size to use in the second proposal attempt.
  • max_size (disksize, default: unlimited) Maximum size to assign to the volume. It can also contain the value unlimited (meaning as big as possible). This will be considered the default value if the option is not present.
  • max_size_lvm (disksize, default: 0 B) When LVM is used, this option can be used to override the value at max_size.
  • weight (integer, default: 0, so extra size is not assigned) Value used to distribute the extra space (after assigning the initial ones) among the volumes.
  • adjust_by_ram (boolean, default: false) Default value for the user setting deciding whether the initial and max sizes of each attempt should be adjusted based in the RAM size. So far the adaptation consists in ensuring all the sizes are, at least, as big as the RAM. In the future, an extra adjust_by_ram_mode option could be added to allow other approaches. Note that this setting has an special behavior for Z Systems. The option to resume from RAM is not available for this kind of systems. And for this reason, in s390 the default value of adjust_by_ram is forced to false for the swap volume (mount point is "swap"), even when it was set to true in the control file.
  • adjust_by_ram_configurable (boolean, default: false) Whether the user can change the previous setting in the UI.
  • fallback_for_min_size (string, default: no fallback) Mount point of another volume. If the volume being defined is disabled, the min_size of that another volume will be increased by the min_size of this disabled volume.
  • fallback_for_desired_size (string, default: no fallback) Same than before, but for desired_size.
  • fallback_for_max_size (string, default: no fallback) Same than before, but for max_size.
  • fallback_for_max_size_lvm (string, default: no fallback) Same than before, but for max_size_lvm.
  • fallback_for_weight (string, default: no fallback) Same than before, but for the volume weight.
  • separate_vg_name (string, default: no name, so the volume will be created in the general "system" volume group) Name of the separate LVM volume group that will be created to host only this volume when the option separate_vgs is active in the settings.

Apart from all those relatively straightforward entries, there is another option that can be specified for each volume and that deserves a slightly more detailed explanation.

  • disable_order (integer, default: never disabled) Volumes with some value here will be disabled (or snapshots deactivated) if needed to make the initial proposal. See detailed explanation below.

Before any user interaction, an initial proposal with the default settings is calculated. If YaST is not able to make space for all the volumes required by those default settings, it will perform new attempts altering the settings. For that, it will follow the disable_order for each volume with that field.

In the first iteration, it will look for the lowest number there. If adjust_by_ram_configurable is true in that volume, it will disable adjust_by_ram. If that is not enough and snapshots are optional but enabled, it will disable them and try again (assuming Btrfs is being used). If that's still not enough, it will disable the whole volume if it's optional.

If that's not enough, it will keep those settings and look for the next volume with some value in disable_order to perform the same operation in a cumulative fashion.

Last but not least, some options only apply if the chosen filesystem type for the volume is Btrfs. Apart from their influence in the proposal, they are also relevant in the Expert Partitioner - if a Btrfs filesystem is created and assigned to the mount point of the volume, these settings will also be used to suggest the filesystem options.

  • snapshots (boolean, default: false) Default value for the user setting deciding whether snapshots should be activated.
  • snapshots_configurable (boolean, default: false) Whether the user can change the previous setting in the Guided Setup UI.
  • snapshots_size (disksize, default: 0 B) The initial and maximum sizes for the volume will be increased accordingly if snapshots are being used.
  • snapshots_percentage (integer, default: 0) Like snapshots_size but as a percentage of the original sizes
  • subvolumes (subsection, default: either empty list or internal fallback list for '/' volume) Optional list of Btrfs subvolumes. If it is missing, a hard-coded list is used for the root filesystem. If the section is there but empty, no subvolumes are created. Each subvolume section has a mandatory path and optional copy_on_write and archs elements, as described below.
  • btrfs_default_subvolume (string, default: no special default subvolume) The default subvolume is not represented by an entry in the subvolumes list, but with a separate option that specifies only its path. The path of the default subvolume is prepended to the path of all the other subvolumes in the filesystem, no matter if they come from the previous list or are manually added by the user of the partitioner.
  • btrfs_read_only (boolean, default: false) Whether the root subvolume should be mounted read-only in /etc/fstab and its 'ro' Btrfs property should be set to true. This works only for Btrfs root filesystems. If another root filesystem type is chosen, this property is ignored. Its default value is false.

As mentioned, each subvolume subsection within the subvolumes list has a mandatory path and optional copy_on_write and archs elements.

  • path The directory path of the subvolume without a starting slash ("/"), e.g. var/cache. The value of btrfs_default_subvolume and a slash are prepended, i.e. the result will be something like @/var/cache.
  • copy_on_write Optional and true by default. Specify false for NoCOW subvolumes. NoCOW is recommended for database directories where a rollback together with the rest of the filesystem (in case of a system or kernel update that did not quite go as well as expected) is not desired.
  • archs Comma-separated list of system architectures (e.g. i386, x86_64, ppc, s390) to which a subvolume is restricted. The default is "all architectures" if not specified. Notice that "all" is not a legal value for this element; if a subvolume is relevant for all architectures, omit archs.

Use an exclamation mark ("!") to exclude the subvolume on an architecture:

<archs>ppc,!board_powernv</archs>

This means "use for ppc, but not for board_powervr" (board_powervr is a PPC with a special board).

Normally, architectures are combined with logical OR, i.e.

<archs>i386,x86_64</archs>

means "if architecture i386 or x86_64". If the current architecture is an architecture that was excluded with "!", that subvolume is not used no matter what other architectures are specified that might also apply.

Example:

This is the full list of SLE-15 SP2:

<subvolumes config:type="list">
    <subvolume>
        <path>home</path>
    </subvolume>
    <subvolume>
        <path>opt</path>
    </subvolume>
    <subvolume>
        <path>srv</path>
    </subvolume>
    <subvolume>
        <path>tmp</path>
    </subvolume>
    <subvolume>
        <path>usr/local</path>
    </subvolume>
    <subvolume>
        <path>var</path>
        <copy_on_write config:type="boolean">false</copy_on_write>
    </subvolume>

    <!-- architecture specific subvolumes -->

    <subvolume>
        <path>boot/grub2/i386-pc</path>
        <archs>i386,x86_64</archs>
    </subvolume>
    <subvolume>
        <path>boot/grub2/x86_64-efi</path>
        <archs>x86_64</archs>
    </subvolume>
    <subvolume>
        <path>boot/grub2/powerpc-ieee1275</path>
        <archs>ppc,!board_powernv</archs>
    </subvolume>
    <subvolume>
        <path>boot/grub2/x86_64-efi</path>
        <archs>x86_64</archs>
    </subvolume>
    <subvolume>
        <path>boot/grub2/s390x-emu</path>
        <archs>s390</archs>
    </subvolume>
    <subvolume>
        <path>boot/grub2/arm64-efi</path>
        <archs>aarch64</archs>
    </subvolume>
</subvolumes>

Network

Some options to modify network configuration defaults.

  • force_static_ip (boolean, default: false) Initialize new connections using a static bootproto.
  • startmode (string) When to bring up an interface. Possible values are hotplug, auto, ifplugd, manual, nfsroot or off.
  • network_manager Whether NetworkManager should be the default backend. Possible values are always, never or laptop which will be true in case the computer being installed is a laptop.
  • ipv4_forward (boolean, no default value) Sets IPv4 Forwarding to be enabled.
  • ipv6_forward (boolean, no default value) Sets IPv6 Forwarding to be enabled.

Self Update

To enable the self update feature (FATE#319716), the location of the update repository should be defined in the control file.

    <self_update_url>https://updates.suse.com/SUSE/Updates/SLE-INSTALLER/$os_release_version/$arch/update</self_update_url</self_update_url>

$os_release_version will be replaced by the VERSION entry in /etc/os-release file. E.g. "15-SP2" $arch reflects the architecture of the current installation system.

This is the fallback which is used if the self-update repository is not specified on the boot command line or if the registration module is not available.

See more details in the self-update documentation.

Hooks

It is possible to add hooks before and after any workflow step for further customization of the installed system and to to perform non-standard tasks during the installation.

Two additional elements define custom script hooks:

  • prescript: Executed before the module is called.

  • postscript: Executed after the module is called.

Both script types accept two elements: The interpreter used (shell or perl) and the source of the scripts which is embedded in the XML file using CDATA sections to avoid confusion with the XML syntax. The following example shows how scripts can be embedded in the control file:

    <module>
        <name>info</name>
        <arguments>false,true</arguments>
        <prescript>
            <interpreter>shell</interpreter>
            <source>
<![CDATA[#!/bin/sh
touch /tmp/anas
echo anas > /tmp/anas
]]>
            </source>
        </prescript>
    </module>

Texts

Some kind of texts can be, of course, placed in several parts of the control file but they wouldn't be translated. This control file section makes it possible to mark some texts for translation.

The structure is rather simple:

    <texts>
        <!-- Unique tag that identifies the text -->
        <some_text_id>
            <label>Some XML-escaped text: &lt;b&gt;bold &lt;/b&gt;.</label>
        </some_text_id>

        <congratulate>
            <label>&lt;p&gt;&lt;b&gt;Congratulations!&lt;/b&gt;&lt;/p&gt;</label>
        </congratulate>
    </texts>

Translated texts can be got using ProductControl.GetTranslatedText (text_id) call.

CONTROL-SECTION

Add-on Product Installation Workflow Specification

Introduction

Product dependency

Everywhere, product B depends on product A, there is no dependency related to product C. A, B and C are add-on products.

Order of updates of the workflow/wizard

If there are two add-on products which want to insert their steps into the same location of the installation workflow (or proposal), they are inserted in the same order as the products are added. A must be added before B (otherwise adding B fails), steps of A are always prior to steps of B.

Steps/Proposal Items Naming

In order to avoid collisions of internal names of proposal items or sequence steps, all items should have its internal name prefixed by the add-on product name.

Update possibilities

Insert an item into proposal

Item is always added at the end of the proposal. Multiple items are possible.

Remove an item from proposal

Specified item(s) are removed from proposal. Useful when add-on product extends functionality of the base product. If product B wants to remove an item of product A, must specify the name of the product as well. Product C cannot remove items of products A or B (and vice versa), product A cannot remove items of product B.

Replace an item in proposal

Usable in the same cases as the case above. If an item has been replaced by another item(s) of product A before applying changes of product B, the item(s) of product A will be replaced by item(s) of product B. Items of product C cannot be replaced by items of product A or B (and vice versa), such combination of products cannot be installed at the same time.

Insert steps to installation sequence

Before each step of base product installation, additional step can be inserted (e.g. another proposal). For the order of additionally added steps, the same rules as for items of proposal will be applied.

Append steps to installation sequence

The steps can be appended at the end of installation sequence.

Remove and replace steps in installation sequence

The same rules for removing and replacing steps of the installation workflow as for proposal items will be applied.

Add, remove, replace items in inst_finish.ycp

The same rules as for steps of the installation workflow are valid here. There will be some points in the inst_finish where performing additional actions makes sense (at least one before moving SCR to chroot and one after).

Replace whole second-stage workflow

Add-on product may replace whole second stage of installation. It should be used only in rare cases, as there is no possibility to merge two workflows completely written from scratch. If a product replaces the workflow, all changes of all products which replaced it before (in case of installation of multiple products) are gone. Add-on products selected after this product update the new workflow (which may not work, as the steps usually have different naming). This is perfectly OK if there are dependencies between add-on products.

The workflow can be replaced only for specified installation mode. If it is replaced, it must be replaced for all architectures.

Adding a new proposal

New proposal can be added, as the proposal handling routines are generic. The information which is for current product in control.xml file has to be provided, and the proposal must be added as a step into the installation workflow. Basically, adding proposal has two steps:

  • defining the proposal (name, items,...)

  • adding a new step to the workflow referring to the new added proposal

Replace or remove whole proposal

Is possible as replacing or removing a step of the installation workflow.

Adding new system roles

Add-ons are allowed to define additional system roles. Those roles will be shown at the bottom of the list of already existing roles. For the time being, modifying or removing system roles is not possible.

File layout

Add-on Product CD

There will be following files in the root directory of the add-on product's CD:

  • servicepack.tar.gz – tarball with files which are needed for the installation, both together with base product and separatelly. Special files inside this tarball:

    • installation.xml – the control file of the add-on product
    • the whole tarball or installation.xml can be missing if add-on product doesn't provide any custom installer, in this case, only its packages are added to the package manager dialog, and packages/patterns/... required by the product are selected by the solver
  • (optional) setup.sh – script which starts the installation automatically once the CD is in the drive

  • (optional) files needed to make the CD bootable (kernel, initrd, isolinux,...)

  • (optional) y2update.tgz can contain all files that are needed for installation itself. Both for first stage installation and also for the running system.

RPM

It is possible to also modify behavior of installation by RPM. There are few requirements for that RPM:

  • It needs to provide the installer_module_extension symbol.
  • It needs to specify for which product is the extension defined. This is done by providing the extension_for_product() symbol.
  • It needs an XML control file. The recommended location is /usr/share/system-roles/<role_name>.xml, alternatively you can use deprecated path /installation.xml (not recommended for new products).

Example of spec file for RPM:

Provides:       installer_module_extension() = system-role-hpc-compute
Provides:       extension_for_product() = SLE_HPC

%files
/usr/share/system-roles/hpc-compute.xml

Workflow Adaptation

There is only a single control file to describe both an add-on and standalone product installation. It is called installation.xml. In principle, it contains a diff description containing the changes to be applied to the installation workflow plus a workflow, which is used for standalone product installation. The reason why both installation methods are stored in a single file is that the product features has to be shared as well as some proposals and clients can be reused.

The proposals which are defined for standalone installation are also available for the installation together with the base product. They don't have to be defined twice.

The files are located in the top directory of the add-on product installation source.

Diff File Format

Because there were no really usable open source XML diff tools (the existing ones are typically written in Java), we define a special purpose file format aimed to cover the cases as described in the previous chapter.

In principle, the format is a list of directives to be applied to the existing control.xml. In principle, the file is a control file defining its own proposals, workflows etc. The control file has a special section, which defines changes to the existing workflow and proposals.

    <?xml version="1.0"?>
    <productDefines  xmlns="http://www.suse.com/1.0/yast2ns"
        xmlns:config="http://www.suse.com/1.0/configns">
        <!-- .mo-file must be in installation tarball -->
        <textdomain>OES</textdomain>
        <!-- these options override base product's ones -->
        <globals>
            <additional_kernel_parameters></additional_kernel_parameters>
        </globals>
        <software>
            <selection_type config:type="symbol">auto</selection_type>
        </software>
        <partitioning>
            <volumes config:type="list">
                <volume>
                    <mount_point>/</mount_point>
                    <max_size config:type="disksize">10 GiB</max_size>
                </volume>
            </volumes>
        </partitioning>
        <network>
            <force_static_ip config:type="boolean">false</force_static_ip>
            <network_manager>laptop</network_manager>
        </network>
        <!-- base product's list is preserved, these are appended -->
        <clone_modules config:type="list">
            <clone_module>printer</clone_module>
        </clone_modules>
        <proposals config:type="list">
      <!-- put proposals for standalone product installation here -->
        </proposals>
      <!-- workflow for standalone product installation -->
        <workflows config:type="list">
            <workflow>
                <defaults>
                    <archs>all</archs>
                </defaults>
                <label>Preparation</label>
                <!-- mode and stage must be set this way -->
                <mode>installation</mode>
                <stage>normal</stage>
                <modules config:type="list">
                    <module>
                         <label>License Agreement</label>
                         <name>license</name>
                         <enable_back>no</enable_back>
                         <enable_next>yes</enable_next>
                    </module>
                </modules>
            </workflow>
        </workflows>
        <!-- stuff for installation together with base products -->
        <update>
            <proposals config:type="list">
                <proposal>
                    <label>OES Installation Settings</label>
                    <mode>installation,demo,autoinstallation</mode>
                    <stage>initial</stage>
                    <name>initial</name>
                    <enable_skip>no</enable_skip>
                    <append_modules config:type="list">
                        <append_module>module_1</append_module>
                        <append_module>module_2</append_module>
                    </append_modules>
                    <remove_modules config:type="list">
                        <remove_module>module_3</remove_module>
                        <remove_module>module_4</remove_module>
                    </remove_modules>
                    <replace_modules config:type="list">
                        <replace_module>
                            <replace>old_module</replace>
                            <new_modules config:type="list">
                                <new_module>module_5</new_module>
                                <new_module>module_6</new_module>
                            </new_modules>
                        </replace_module>
                    </replace_modules>
                </proposal>
            </proposals>
            <workflows config:type="list">
                <workflow>
                    <defaults>
                        <archs>all</archs>
                        <enable_back>no</enable_back>
                        <enable_next>no</enable_next>
                    </defaults>
                    <mode>installation</mode>
                    <stage>initial</stage>
                    <append_modules config:type="list">
                        <module>
                            <heading>yes</heading>
                            <label>OES configuration</label>
                        </module>
                        <module>
                            <label>Perform Installation</label>
                            <name>a1_netsetup</name>
                        </module>
                        <module>
                            <label>Perform Installation</label>
                            <name>a2_netprobe</name>
                        </module>
                    </append_modules>
                    <remove_modules config:type="list">
                        <remove_module>finish</remove_module>
                    </remove_modules>
                    <insert_modules config:type="list">
                        <insert_module>
                            <before>perform</before>
                            <modules config:type="list">
                                 <module>
                                 <label>Perform Installation</label>
                                    <name>i1_netprobe</name>
                                </module>
                            </modules>
                        </insert_module>
                    </insert_modules>
                    <replace_modules config:type="list">
                        <replace_module>
                            <replace>language</replace>
                            <modules config:type="list">
                                 <module>
                                 <label>Perform Installation</label>
                                    <name>r1_language</name>
                                </module>
                            </modules>
                        </replace_module>
                    </replace_modules>
                </workflow>
            </workflows>
            <inst_finish>
                <before_chroot config:type=”list”>
                    <module>before_chroot_1</module>
                    <module>before_chroot_2</module>
                </before_chroot>
                <after_chroot config:type=”list”>
                    <module>after_chroot_1</module>
                    <module>after_chroot_2</module>
                </after_chroot>
                <before_umount config:type=”list”>
                    <module>before_umount_1</module>
                    <module>before_umount_2</module>
                </before_umount>
            </inst_finish>
            <system_roles>
              <insert_system_roles config:type="list">
                <insert_system_role>
                  <system_roles config:type="list">
                    <system_role>
                      <id>additional_role</id>
                    </system_role>
                  </system_roles>
                </insert_system_role>
              </insert_system_roles>
            </system_roles>
        </update>
    </productDefines>

Setting a text domain

Text domain is important for YaST to handle translations properly. The appropriate set of .mo-files must be present to have the texts related to the control file translated.

    <textdomain>OES</textdomain>

Defining proposals and workflow for standalone installation

The proposals are defined the same way as for the base product. The workflow for the standalone installation must have the mode and stage set

    <mode>installation</mode>
    <stage>normal</stage>

Proposal modification

The label of the proposal can be modified. The mode, stage, and proposal name has to be specified, other options (enable_skip, architecture) are optional. The modes, stages, and architectures do not

    <proposal>
        <label>OES Installation Settings</label>
        <mode>installation,demo,autoinstallation</mode>
        <stage>initial</stage>
        <name>initial</name>
        <enable_skip>no</enable_skip>
        [.....]
    </proposal>

Appending an item at the end of proposal

Adding an item to a proposal is possible at the end only. If the proposal has tabs, the items are added to a newly created tab.

    <append_modules config:type="list">
        <append_module>module_1</append_module>
        <append_module>module_2</append_module>
    </append_modules>

Removing an item from a proposal

    <remove_modules config:type="list">
        <remove_module>module_3</remove_module>
        <remove_module>module_4</remove_module>
    </remove_modules>

Replacing an item of a proposal

The replacement is available in 1:N mode – one client is to be replaced by one or more new clients. If you need M:N use remove and replace together.

    <replace_modules config:type="list">
        <replace_module>
        <replace>old_module</replace>
        <new_modules config:type="list">
            <new_module>module_5</new_module>
            <new_module>module_6</new_module>
        </new_modules>
        </replace_module>
    </replace_modules>

Workflow updates

The workflow to update is identified the same way as other workflows. The archs, modes, and installation don't need tobe alligned to the same groups as in the base product workflows.

    <workflow>
        <defaults>
        <archs>all</archs>
        <enable_back>no</enable_back>
        <enable_next>no</enable_next>
        </defaults>
        <mode>installation</mode>
        <stage>initial</stage>
        [...]
    </workflow>

Append steps to the end of installation sequence

    <append_modules config:type="list">
        <module>
        <heading>yes</heading>
        <label>OES configuration</label>
        </module>
        <module>
        <label>Perform Installation</label>
        <name>a1_netsetup</name>
        </module>
        <module>
        <label>Perform Installation</label>
        <name>a2_netprobe</name>
        </module>
        [...]
    </append_modules>

Insert steps to installation sequence

    <insert_modules config:type="list">
        <insert_module>
        <before>perform</before>
        <modules config:type="list">
            <module>
            <label>Perform Installation</label>
            <name>i1_netprobe</name>
            </module>
            [...]
        </modules>
        </insert_module>
    </insert_modules>

Remove steps from installation sequence

    <remove_modules config:type="list">
        <remove_module>finish</remove_module>
        [...]
    </remove_modules>

Replace steps in installation sequence

    <replace_modules config:type="list">
        <replace_module>
        <replace>language</replace>
        <modules config:type="list">
            <module>
            <label>Perform Installation</label>
            <name>r1_language</name>
            </module>
            [...]
        </modules>
        </replace_module>
    </replace_modules>

Add items in inst_finish.ycp

In CODE 10, the last step of an installation commonly known as inst_finish has been modularized, so it's possible to control the clients started at the end of the 1st stage. In principle, this phase runs in a chroot environment – all system access is done via chrooted process.

There are 3 cases that an add-on product can modify the workflow...

Before chroot

    <inst_finish_stages config:type="list">
    <before_chroot>
        <label>Copy Theme</label>
        <steps config:type="list">
        <step>copy_theme</step>
        [...]
        </steps>
    </before_chroot>
    </inst_finish_stages>

Running in chroot

    <inst_finish_stages config:type="list">
    <chroot>
        <label>Update Configuration</label>
        <steps config:type="list">
        <step>pkg</step>
        [...]
        </steps>
    </chroot>
    </inst_finish_stages>

Before unmounting the system

    <inst_finish_stages config:type="list">
    <before_umount>
        <label>Disconnect Network Disks</label>
        <steps config:type="list">
        <step>iscsi_disconnect</step>
        [...]
        </steps>
    </before_umount>
    </inst_finish_stages>

All new steps are added at the end of the current list in the particular inst_finish workflow. It is not possible to remove any other inst_finish clients or replace them.

Replace whole second-stage workflow

To replace a workflow, just create workflows as in base product control file. The important is that the stage of the workflow is set to

    <stage>continue</stage>

and the mode is set for the specified mode.

Algorithm for Adapting Workflow

The algorithm is rather straightforward. Every time, remove is applied first, then replace and the last step is add. This is done per product, so first the changes by product A are applied, then by product B etc.

Product Features

One of the most important data stored in the control.xml file are the values to influence the behavior of YaST code, like proposals etc. The idea is the same as for workflow/proposal adaptation: by redefining a value, the resulting values are changed. Within YaST, the options are accessible via ProductFeatures module. No new option groups can be defined. Options which are defined by the base product, but not by the add-on product, are kept unchanged (base product's value is used).

    <globals>
        <additional_kernel_parameters></additional_kernel_parameters>
    </globals>
    [...]
    <software>
        <selection_type config:type="symbol">auto</selection_type>
    </software>

AutoYaST profile generation

At the end of the installation, a profile for AutoYaST can be generated. The profile will be generated using modules from the base product and modules specified in the add-on product control file.

    <clone_modules config:type="list">
        <clone_module>printer</clone_module>
        [...]
    </clone_modules>

Example of OES 1.0

The network code is instructed to force a static IP address.

The control file contains steps for both standalone installation and installation together with the base product. In the standalone installation workflow, selecting and installing packages is missing, these steps need to be prepended to the workflow.

    <?xml version="1.0"?>
    <productDefines  xmlns="http://www.suse.com/1.0/yast2ns"
            xmlns:config="http://www.suse.com/1.0/configns">
    <textdomain>OES</textdomain>
    <network>
        <force_static_ip config:type="boolean">true</force_static_ip>
        <network_manager_is_default config:type="boolean">false</network_manager_is_default>
    </network>
    <proposals config:type="list">
        <proposal>
            <name>oes</name>
            <stage>continue,normal</stage>
            <mode>installation</mode>
            <proposal_modules config:type="list">
                <proposal_module>oes-ldap</proposal_module>
                <proposal_module>imanager</proposal_module>
                <proposal_module>lifeconsole</proposal_module>
                <proposal_module>linux-user-mgmt</proposal_module>
                <proposal_module>eguide</proposal_module>
                <proposal_module>novell-samba</proposal_module>
                <proposal_module>ifolder2</proposal_module>
                <proposal_module>ifolder</proposal_module>
                <proposal_module>ifolderwebaccess</proposal_module>
                <proposal_module>iprint</proposal_module>
                <proposal_module>nss</proposal_module>
                <proposal_module>netstorage</proposal_module>
                <proposal_module>novell-quickfinder</proposal_module>
                <proposal_module>novell-vo</proposal_module>
                <proposal_module>ncs</proposal_module>
                <proposal_module>ncpserver</proposal_module>
                <proposal_module>sms</proposal_module>
            </proposal_modules>
        </proposal>
    </proposals>
    <workflows config:type="list">
        <workflow>
            <label>Preparation</label>
            <defaults>
                <archs>all</archs>
            </defaults>
            <mode>installation</mode>
            <stage>normal</stage>
            <modules config:type="list">
                <module>
                    <label>License Agreement</label>
                    <name>inst_license</name>
                    <enable_back>no</enable_back>
                    <enable_next>yes</enable_next>
                </module>
                <module>
                    <label>OES Configuration</label>
                    <name>inst_check_cert</name>
                    <enable_back>no</enable_back>
                    <enable_next>yes</enable_next>
                </module>
                <module>
                    <label>OES Configuration</label>
                    <name>inst_proposal</name>
                    <arguments>false,false,`product</arguments>
                    <enable_back>no</enable_back>
                    <enable_next>yes</enable_next>
                </module>
                <module>
                    <label>OES Configuration</label>
                    <name>inst_oes</name>
                    <enable_back>yes</enable_back>
                    <enable_next>yes</enable_next>
                </module>
                <module>
                    <label>OES Configuration</label>
                    <name>inst_oes_congratulate</name>
                    <enable_back>no</enable_back>
                    <enable_next>yes</enable_next>
                </module>
            </modules>
        </workflow>
    </workflows>
    <update>
        <workflows config:type="list">
            <workflow>
                <defaults>
                    <archs>all</archs>
                    <enable_back>no</enable_back>
                    <enable_next>no</enable_next>
                </defaults>
                <stage>continue</stage>
                    <mode>installation</mode>
                    <append_modules config:type="list">
                        <module>
                            <label>OES Configuration</label>
                            <name>inst_oes_congratulate</name>
                        </module>
                    </append_modules>
                    <insert_modules config:type="list">
                        <insert_module>
                            <before>release_notes</before>
                            <modules config:type="list">
                                <module>
                                    <label>OES Configuration</label>
                                    <name>inst_check_cert</name>
                                </module>
                                <module>
                                    <label>OES Configuration</label>
                                    <name>inst_edirectory</name>
                                </module>
                                <module>
                                    <label>OES Configuration</label>
                                    <name>inst_proposal</name>
                                    <arguments>false,true,`product</arguments>
                                </module>
                                <module>
                                    <label>OES Configuration</label>
                                    <name>inst_oes</name>
                                </module>
                            </modules>
                        </insert_module>
                    </insert_modules>
                </workflow>
            </workflows>
        </update>
    </productDefines>