# Specification of the user interaction configuration file

Version: | 1.0
Authors: | Martin Kolman <mkolman@redhat.com>

This specification aims to establish a configuration file format that can be used to communicate information about which installation screens have been seen by the user during the installation. Optionally the configuration file might also contain information about which configuration options have been changed by the user and if the user has explicitly requested post installation setup tools to be disabled.

While this configuration file is primarily meant to be read (and potentially changed) by post installation tools (such as for example Initial Setup and Gnome Initial setup), Anaconda will take an existing configuration file into account at startup. This is meant to accommodate tools that are run before Anaconda is started, such as a system-wide language selection tool that runs before Anaconda is started and which sets language for both Anaconda and a Live installation environment.

## Configuration file location

The user interaction configuration file is stored in: `/etc/sysconfig/anaconda`

## General configuration file syntax

The configuration file is based on the INI file de-facto standard, eq.: key=value assignments and square bracket framed section headers.

Comments start with a hash (#) sign and need to be on a separate line. Inline comments (eq. behind section or key/value definitions) are not supported.

For Python programs this file format can be parsed and written by the ConfigParser[0] module available from the Python standard library. For programs written in C the GKeyFile[1] parser might be a good choice. Comparable INI file parsing and writing modules are available for most other programming languages.

Example:

    # comment example - before the section headers

    [section_1]
    # comment example - inside section 1
    key_a_in_section1=some_value
    key_b_in_section1=some_value

    [section_2]
    # comment example - inside section 2
    key_a_in_section2=some_value

Boolean values are marked with 1 for true and 0 for false.

Example:

    true_key=1
    false_key=0

## Toplevel namespace

The toplevel configuration file namespace can only contain section headers.

There are two section types:

- One special section called General that can contain top-level settings not directly corresponding to any screen.
- Other sections that correspond to Anaconda spoke screens.
  - Hubs are not represented as sections as there is nothing that can be directly set on a hub in Anaconda.
  - All currently visible spokes in Anaconda will be enumerated as a section headers by Anaconda in the configuration file. Note that this can include spokes provided by addons[2], if any Anaconda addons that provide additional spokes are present during the installation run.

## The General section

The General section is optional and is not required to be present in the config file. At the moment it can contain only the `post_install_tools_disabled` key.

The `post_install_tools_disabled` key corresponds to using the `firstboot --disable` command in the installation kickstart file. This requests that the post-installation setup tools be skipped. If this key is present and set to 1, any post-installation tools that parse the user interaction file should first make sure the tool won’t be started again on next boot, and then terminate immediately.

## Naming of sections corresponding to Anaconda screens

All section headers not named General are named according to the Anaconda spoke class name. For example `DatetimeSpoke` or `KeyboardSpoke`.

To get a list of all such spokes run the `list_spokes` script from the `scripts` directory in the Anaconda source code tree:

    git clone https://github.com/rhinstaller/anaconda
    cd anaconda/scripts
    ./list_screens

Note that this script only lists Anaconda spokes, not spokes provided by addons[2] or Initial Setup.

It is also possible to check for the Entered spoke: entries in the `/tmp/anaconda.log` file during an installation to correlate spokes on the screen to spoke class names.

## Screen section namespace

Each section corresponding to a screen must contain the `visited` key with a value of either 1 if the user has visited the corresponding screen or 0 if not.

Optionally each section can contain one or more keys with the `changed_` prefix which track if the user has changed an option on the screen. If the option is changed by the user, the corresponding key is set to 1. If the given option has not been changed by the user then the corresponding key can either be omitted or set to 0.

Example:

    [DatetimeSpoke]
    visited=1
    changed_timezone=1
    changed_ntp=0
    changed_timedate=1

In this example the user has visited the date & time spoke and has changed the timezone & time/date, but not the NTP settings. Note that the `changed_ntp` key could also be omitted as the user has not changed the NTP options.

Another example:

    [KeyboardSpoke]
    visited=0

Here the user has not visited the keyboard spoke and thus could not have changed any options, so all `changed_*` keys (if any) have been omitted.

Note that if a spoke section is missing, it should be assumed that the corresponding screen has not been visited. On the other hand, if a screen has been visited, the section must be present, with the `visited` key being equal to 1.

## Full configuration file example

    # this is the user interaction config file

    [General]
    post_install_tools_disabled=0

    [DatetimeSpoke]
    # the date and time spoke has been visited
    visited=1
    changed_timezone=1
    changed_ntp=0
    changed_timedate=1

    [KeyboardSpoke]
    # the keyboard spoke has not been visited
    visited=0

The first section is the special section for top-level settings called General. It contains only one option, `post_install_tools_disabled`, which is in this case equal to 0 This means that post installation setup tools should proceed as usual. In this case (being equal to 0) the `post_install_tools_disabled` key and the whole General section might also be omitted.

Next there are two sections corresponding to two screens - `DatetimeSpoke` and `KeyboardSpoke`.

The user has visited the date & time screen and has changed various options, but not the NTP settings. On the other hand the keyboard screen has not been visited at all.

## Parsing and writing the of the configuration file by Anaconda

If the user interaction file exists during Anaconda startup, it will be parsed and taken into account when deciding which screens to show during the installation. This make it possible for secondary installation setup tools to run before Anaconda and query the user for information.

This can be for example a tool querying the user for language settings. Then once Anaconda starts it can skip the language selection screen as language has already been set by the tool.

Once the installation process is done, Anaconda will write out information about what screens the user has and has not visited and optionally which settings have been changed by the user.

If Anaconda successfully parsed an existing user interaction configuration file, any valid settings present in the file will propagate to the configuration file when it is written-out by Anaconda.

Note that comments present in the configuration file at the time Anaconda parses it might not be present in the output file, therefore tools should not depend on comments being present or on information contained in comments.

## Parsing and writing of the configuration file by tools other than Anaconda

Non-Anaconda system configuration tools should also parse the user interaction file at startup and write it out once done. All valid data already present in the configuration file should be kept and updated accordingly (the user has visited a not-yet-visited screen, changed another option, etc.).

Non-Anaconda tools should try to keep comments present in the input file, but this is not strictly required.

Also note that a variable number of tools might be working with the configuration file in sequence, so no single tool should expect that it is the first or last tool working with the configuration file.

## Links

[0] https://docs.python.org/3/library/configparser.html [1] https://developer.gnome.org/glib/stable/glib-Key-value-file-parser.html [2] https://rhinstaller.github.io/anaconda-addon-development-guide/