Try   HackMD

SPS

.sps - "smart package specification" - defines how individual packages look and behave.

There are three kinds of sps files:

  • Basic - most often contains just binaries or dumb data.
  • Service - defines a service launched with the system (e.g. bitcoind) and the corresponding package.
    These are often parametrised over bitcoin network (mainnet, regtest)
  • Configuration extensions - define packages that control configuration.
    These are used for settings that need to be enforced by the depending packages.
    The main idea is to avoid conflicting configuration and other issues.

The kind of SPS package is inferred from content and can not be distinguished otherwise.
Basically, if the file contains service-related options it's a service package, if it contains architecture key it's a basic package, everything else is a configuration extension.

Basic package example

name = "linuxutil"
architecture = "amd64"
summary = "Collection of Linux Utility Scripts"
conflicts = []
depends = ["bash (>= 4.0)"]
long_doc = """
The 'linuxutil' package provides a collection of useful utility scripts for managing and monitoring Linux systems.

Included Utilities:
- `disk-usage.sh`: Displays disk usage information for mounted partitions.
- `system-info.sh`: Provides system information, including CPU, memory, and kernel details.
- `log-monitor.sh`: Monitors system log files for critical events and errors.
- `backup-scripts.sh`: Assists in creating and managing system backups.

Usage:
$ disk-usage.sh
$ system-info.sh
$ log-monitor.sh
$ backup-scripts.sh

These scripts can help administrators and users perform various system maintenance and monitoring tasks conveniently.

Please refer to the man pages for each utility for detailed usage instructions.

Note: This is a fictional package for demonstration purposes.
"""
add_dirs = []
add_files = ["disk-usage.sh /usr/local/bin", "system-info.sh /usr/local/bin", "log-monitor.sh /usr/local/bin", "backup-scripts.sh /usr/local/bin"]
add_links = []
add_manpages = ["disk-usage.1", "system-info.1", "log-monitor.1", "backup-scripts.1"]
min_patch = ""
provides = []
recommends = []
suggests = []
patch_foreign = {}

Service package example

name = "linuxutil-service"
summary = "Systemd Service for Linux Utility Scripts"
conflicts = []
depends = ["linuxutil"]
long_doc = """
The 'linuxutil-service' package provides a systemd service configuration for the 'linuxutil' package, which is a collection of useful utility scripts for managing and monitoring Linux systems.

This package defines a systemd service called 'linuxutil-service' that ensures the 'linuxutil' scripts are properly managed and executed as a system service.

Note: This is a fictional package for demonstration purposes.
"""
add_dirs = []
add_files = []
add_links = []
add_manpages = []
min_patch = ""
provides = []
recommends = []
suggests = []
patch_foreign = {}

# Service Fields
after = "multi-user.target"
bin_package = ""
bare_conf_param = false
bin_package = ""
binds_to = ""
binary = ""
condition_path_exists = ""
conf_d = {}
conf_param = []
exec_stop = ""
extra_groups = {}
extra_service_config = """
ExecStart=/usr/bin/linuxutil-script
Restart=always
"""
part_of = ""
refuse_manual_start = false
refuse_manual_stop = false
requires = []
runtime_dir = {}
service_type = "simple"
user = {}
wanted_by = "multi-user.target"
wants = "linuxutil"

Configuration extensions example

name = "linuxutil-config"
summary = "Configuration Details for Linux Utility Scripts"
conflicts = []
depends = ["linuxutil"]
long_doc = """
The 'linuxutil-config' package provides configuration details for the 'linuxutil' package, which is a collection of useful utility scripts for managing and monitoring Linux systems.

This configuration package does not contain any binaries or scripts but adds configuration settings to the 'linuxutil' package. It includes:

- Customized settings for 'disk-usage.sh'.
- System monitoring preferences for 'system-info.sh'.
- Log monitoring configurations for 'log-monitor.sh'.
- Backup preferences for 'backup-scripts.sh'.

These configurations enhance the functionality of the 'linuxutil' package, allowing users to tailor the utility scripts to their specific needs.

Note: This is a fictional package for demonstration purposes.
"""
add_dirs = []
add_files = []
add_links = []
add_manpages = []
min_patch = ""
provides = []
recommends = []
suggests = []
patch_foreign = {}

# ConfExt Fields
depends_on_extended = false
external = false
extends = "linuxutil"
extended_by = []
replaces = false

SPS specification

The structure

# Debian fields
# Shared fields
# One of:  Basic fields | Service fields | ConfExt  fields

Package: Debian inherited packaging fields

  • conflicts

    • Type: Set of TemplateString
    • Example:
      ​​​​conflicts = ["nbxplorer (<< 2.1.47)", "python3-lnpbp-testkit (<< 0.1.4)"]
      
    • Variant example
      ​​​​conflicts = ["bitcoin-chain-mode-{variant}"]
      

The "conflicts" field in Debian packaging specifies packages that cannot be installed at the same time as the current package. When a package is marked as a conflict, it means that it has known conflicts with other packages and should not be installed together with them to prevent issues or system instability.

  • depends

    • Type: Set of TemplateString
    • Example
      ​​​​depends = ["nodejs (>= 8.0.0)"]
      
    • Variant Example
      ​​​​depends = ["bitcoin-{variant}"]
      

The "depends" field in Debian packaging lists the dependencies of the current package. Dependencies are other packages that must be installed for the current package to work correctly. These dependencies ensure that all required libraries, tools, or services are available before the package can be installed.

  • long_doc

    • Type: List of TemplateString
    • Example:
      ​​​​long_doc = """This package provides a very simple, yet useful UI for accessing
      ​​​​selfhost-enabled applications."""
      

The "long_doc" field is a List of TemplateStrings that allows you to provide detailed, long-form documentation for the package. It is used to describe the package, its functionality, and any relevant information that users or maintainers need to know. This documentation can include paragraphs of text to provide comprehensive information about the package.

This documentation explains the purpose of the long_doc field and provides an example with its value.

  • name (required)

    • Type: VPackageName
    • Example:
      ​​​​name = bitcoin
      
    • Variant Example:
      ​​​​name = "bitcoin-timechain-@variant"
      
  • provides

    • Type: Set of TemplateString
    • Example
      ​​​​provides = ["selfhost-domain (= 1.1)"]
      
    • Variant example
      ​​​​provides = ["bitcoin-chain-mode-{variant} (= 1.0)", "bitcoin-fullchain-{variant}"]
      

The "provides" field in Debian packaging allows a package to specify that it provides a certain functionality or capability, even if it's not the original package that provides it. This is useful for packages that offer compatibility with other packages or libraries, allowing users to install them interchangeably.

  • recommends

    • Type: Set of TemplateString
    • Example
      ​​​​recommends = ["selfhost (>= 0.1.5)", "selfhost (<< 0.2.0)"]
      
    • Variant example
      ​​​​recommends = ["electrum-trustless-{variant} | electrum-trustless-regtest", "python3-pyqt5"]
      

The "recommends" field in Debian packaging suggests additional packages that are not strictly required for the current package but are highly recommended to enhance its functionality or provide additional features. These packages are typically suggested to improve the user experience.

  • suggests

    • Type: Set of TemplateString
    • Example
      ​​​​suggests = ["bitcoin-cli"]
      
    • Variant example
      ​​​​suggests = ["tor", "bitcoin-fullchain-{variant}"]
      

The "suggests" field in Debian packaging lists packages that are suggested to the user but are entirely optional. Unlike "recommends," packages listed in "suggests" are not considered important for the functionality of the current package but may be useful in certain situations or for specific use cases. Users can choose to install or ignore suggested packages based on their needs.

Package: Shared fields: Basic/Service/ConfExt

  • add_dirs

    • Type: List of TemplateString
    • Example:
      ​​​​add_dirs = ["/etc/tor/torrc.d","/etc/tor/hidden-services.d"]
      

The "add_dirs" field is a list of TemplateStrings representing additional directories that you wish to install along with the package. Each TemplateString can specify a directory path, allowing you to define where these directories should be created or copied during the package installation process. This feature is useful when you need to include extra directories as part of your package distribution.

  • add_files

    • Type: List of TemplateString
    • Example:
      ​​​​add_files = ["lnd /usr/bin", "lib/bash.sh /usr/share/lnd/lib", "get_external_addr.sh /usr/share/lnd"]
      

The "add_files" field is a list of TemplateStrings that defines additional files you wish to install along with the package. Each TemplateString can specify a file path, allowing you to include extra files in the package distribution. These files will be copied or installed to the appropriate locations during package installation, ensuring they are available for use.

    • Type: List of TemplateString
    • Example:
      ​​​​add_links = ["/usr/lib/NBXplorer/NBXplorer /usr/bin/nbxplorer"]
      

The "add_links" field is a list of TemplateStrings used to specify additional symbolic links that should be created when the package is installed. Each TemplateString defines a symbolic link, indicating the source file or directory and the destination where the symbolic link should point. This allows you to set up symbolic links as part of the package installation, making it easier to manage dependencies or provide shortcuts to important resources.

  • add_manpages

    • Type: List of TemplateString
    • Example:
      ​​​​add_manpages = ["target/man/selfhost-dashboard.1"]
      

The "add_manpages" field is a list of TemplateStrings specifying additional man pages that should be included with the package. Each TemplateString can define the source path of the man page and where it should be installed. Man pages are important for documenting command-line tools and utilities.

  • patch_foreign

    • Type: Map of String to String

The "patch_foreign" field represents a mapping of file paths in the system to their corresponding patch file paths. It is used to specify which patches should be applied to certain files during the installation or configuration of the package. Each entry in the map consists of a file path as the key and the path to the associated patch file as the value. For example:

[patch_foreign]
"/usr/share/tor/tor-service-defaults-torrc" = "/usr/share/tor-hs-patch-config/defaults.patch"
"/etc/apparmor.d/local/system_tor" = "/usr/share/tor-hs-patch-config/apparmor.patch"

In this example, the package will apply the defaults.patch to /usr/share/tor/tor-service-defaults-torrc and the apparmor.patch to /etc/apparmor.d/local/system_tor during installation or configuration. This feature is commonly used to apply custom patches or configuration changes to specific files as part of the package installation process.

  • summary (required)

    • Type: TemplateString
    • Example
      ​​​​summary = "Publishes bitcoin whitepaper as /bitcoin.pdf"
      
    • Variant example
      ​​​​summary = "Marker package disabling integration of LND into BTCPayServer ({variant})"
      

The "summary" field is a required field in Debian packaging that provides a concise one-line description of the package. It summarizes the purpose or functionality of the package in a brief and informative manner. The value of this field should be a TemplateString, allowing for dynamic content insertion if needed.

  • config

See bellow

  • min_patch

    • Type: String
    • Example
      ​​​​min_patch = "1"
      

The "min_patch" field specifies the minimum required patch level for the package. It defines the minimum version or level of patching needed for the package to function correctly. This field can help ensure that the package is compatible with the required patch level of related software or dependencies.

Package: Basic only

  • architecture

    • Type: String
    • Example
      ​​​​​​architecture = "amd64"
      

The "architecture" field specifies the target architecture(s) for which the package is intended in Debian packaging. You can use one of the following values to define the supported architectures:

  • "any": The package is architecture-independent and can be installed on any architecture.
  • "all": The package is architecture-independent and can be installed on any architecture. This is often used in combination with "Architecture: all" in the package control file.
  • "amd64": The package is built for the AMD64 architecture, commonly used for 64-bit x86 systems.
  • "i386": The package is built for the IA-32 architecture, which is used for 32-bit x86 systems.
  • "arm64": The package is built for the ARM64 architecture, commonly used for 64-bit ARM systems.
  • "armhf": The package is built for the ARM Hard Float (ARMHF) architecture, typically used for ARMv7 and later systems with hardware floating-point support.
  • "ppc64el": The package is built for the PowerPC 64-bit Little-Endian (PPC64LE) architecture.
  • "s390x": The package is built for the IBM System z architecture (s390

Package: Service only

  • after

    • Type: TemplateString
    • Example
      ​​​​after = "postgresql.service"
      
    • Variant example
      ​​​​after = "lnd-system-{variant}.service"
      

The "after" field specifies a target service or unit that the current package should be configured to start after. It defines a dependency relationship where the package should wait for the specified service or unit to start before it is started. This field is particularly useful for ensuring proper service dependencies and startup order.

  • bare_conf_param

    • Type: bool
    • Conflicts with: conf_param
    • Example
      ​​​​bare_conf_param="true"
      

The "bare_conf_param" field is a boolean flag that, when set to true, indicates that the package should use a "bare" configuration parameter without additional settings. It conflicts with the conf_param field, meaning that you should use either bare_conf_param or `conf_param,`` but not both. This flag is used to simplify the configuration when no additional settings are required.

  • bin_package

    • Type: String
    • Example
      ​​​​bin_package = "python3-remir"
      

The "bin_package" field specifies the name of a binary package that is associated with the current package. This field is used to establish a relationship between packages, indicating that the current package relies on or is related to the specified binary package. The binary package name is typically used to reference related packages that provide specific functionality or dependencies.

  • binds_to

    • Type: TemplateString
    • Example
      ​​​​binds_to = "lnd-system.service"
      
    • Variant example
      ​​​​binds_to = "lnd-system-{variant}.service"
      

The "binds_to" field specifies a target service or unit that the current package should be bound to. It establishes a relationship where the package should be started and stopped together with the specified service or unit. This field is used to ensure that the package is closely tied to the specified service or unit's lifecycle.

  • binary

    • Type: String
    • Example
      ​​​​binary = "/usr/bin/remir"
      

The "binary" field specifies the path to the binary executable associated with the package. It indicates the location of the main executable file that the package provides or relies on. This field is essential for identifying the primary executable within the package.

  • condition_path_exists

    • Type: TemplateString
    • Example
      ​​​​condition_path_exists="!/etc/selfhost/deactivate-selfhost-dashboard"
      

The "condition_path_exists" field specifies a condition that needs to be met for the package to be installed or configured. It uses a TemplateString to define a path condition that checks for the existence or non-existence of a specific file or directory. Depending on the condition, the package installation or configuration may proceed or be skipped.

  • conf_d

    • Type: ConfDir
    • Example
      ​​​​conf_d = { name = "conf.d", param = "--conf-dir" }
      

The "conf_d" field specifies configuration directory information using the ConfDir type. It typically includes a name and param that define the name of the configuration directory and any associated command-line parameters. This field is used to specify the configuration directory for the package, typically located under the /etc directory.

  • conf_param

    • Type: ConfParam
    • Example
      ​​​​conf_param = "--conf"
      ​​​​conf_param = "--conf="
      

The "conf_param" field specifies the command-line parameters used by the underlying CLI when starting the service associated with the package. These parameters are typically related to the configuration of the service and may include flags or options that affect how the service runs. The ConfParam type allows you to define these parameters to ensure proper configuration.

  • exec_stop

    • Type: String
    • Example
      ​​​​exec_stop = "/bin/true"
      

The "exec_stop" field specifies the command or script that should be executed when stopping the service associated with the package. It defines the action to be taken when the service is stopped, such as running a specific command or script. This field is used to control the behavior of the service during the stop process.

  • extra_groups

    • Type: Map of TemplateString to ExtraGroup
    • Example
      ​​​​[extra_groups."lnd-system"]
      ​​​​create = false
      
    • Variant example
      ​​​​[extra_groups."lnd-system-{variant}"]
      ​​​​create = false
      

The "extra_groups" field specifies additional groups that should be created or configured as part of the package installation process. It uses a map where each key is a TemplateString representing the group name, and each value is an ExtraGroup type that defines the group's configuration, including whether it should be created or not.

  • extra_service_config

    • Type: TemplateString
    • Example
      ​​​​extra_service_config = """
      ​​​​Restart=always
      ​​​​"""
      
    • Variant example
      ​​​​extra_service_config = """
      ​​​​Environment="BITCOIN_NETWORK={variant}"
      ​​​​RemainAfterExit=true
      ​​​​"""
      

The "extra_service_config" field allows you to specify additional configuration options for the systemd service associated with the package. It uses a TemplateString to define custom systemd service configuration settings. These settings can include directives that control how the service behaves, environment variables, and more.

  • part_of

    • Type: TemplateString
    • Example
      ​​​​part_of = "lnd-system.service"
      
    • Variant example
      ​​​​part_of = "lnd-system-{variant}.service"
      

The "part_of" field specifies that the current package is considered a part of another systemd service, indicating a dependency relationship. It uses a TemplateString to define the name of the service to which the package is considered a part. This field ensures that the package is treated as a component of the specified service.

  • refuse_manual_start

    • Type: bool
    • Example
      ​​​​refuse_manual_start = true
      

The "refuse_manual_start" field is a boolean flag that, when set to true, indicates that the package should not be started manually by users or administrators. It prevents manual initiation of the associated service using commands like systemctl start or similar. This flag is used to enforce automatic startup behavior or to prevent unintentional manual starts.

  • refuse_manual_stop

    • Type: bool
    • Example
      ​​​​refuse_manual_stop = true
      

The "refuse_manual_stop" field is a boolean flag that, when set to true, indicates that the package should not be stopped manually by users or administrators. It prevents manual termination of the associated service using commands like systemctl stop or similar. This flag is used to enforce automatic stop behavior or to prevent unintentional manual stops.

  • requires (TODO)

    • Type: TemplateString
    • Example
    • Variant example
  • runtime_dir

    • Type: RuntimeDir
    • Example
      ​​​​runtime_dir = { mode = "750" }
      

The "runtime_dir" field specifies the configuration for creating a runtime directory associated with the package. It uses the RuntimeDir type to define the configuration, including the directory's mode. Runtime directories are typically used to store temporary or runtime data for a service or application.

  • service_type

    • Type: String
    • Example
      ​​​​service_type = "notify"
      

The "service_type" field specifies the type of systemd service that is associated with the package. It defines the behavior and characteristics of the systemd service. The allowed values for the "service_type" field include:

  • "simple": Indicates a basic systemd service that does not provide notifications or special features.

  • "forking": Indicates a systemd service that forks itself into the background during startup.

  • "oneshot": Indicates a systemd service that is designed to be executed once and then exit.

  • "dbus": Indicates a systemd service that communicates with D-Bus for activation.

  • "notify": Indicates a systemd service that sends a notification to systemd when it is ready to accept connections.

  • user

    • Type: UserSpec
    • Example
      ​​​​user = { group = true, create = { home = false } }
      
    • Variant example
      ​​​​user = { name = "lnd-system-{variant}", group = true }
      

The "user" field specifies user-related configuration for the package. It uses the UserSpec type to define the user and its associated attributes. This can include whether to create a user or group, the user's name, and additional user-related settings.

  • wanted_by

    • Type: TemplateString
    • Example
      ​​​​wanted_by = "lnd-system.service"
      
    • Variant example
      ​​​​wanted_by = "lnd-system-{variant}.service"
      

The "wanted_by" field specifies the systemd target or service that the current package should be wanted by. It establishes a dependency relationship where the package is configured to be wanted by the specified target or service. This field ensures that the package is included in the dependencies of the target or service.

  • wants

    • Type: TemplateString
    • Example
      ​​​​wants = "postgresql.service"
      
    • Variant example
      ​​​​wants = "postgresql-{variant}.service"
      

The "wants" field specifies the systemd target or service that the current package wants as a dependency. It establishes a relationship where the package indicates that it wants the specified target or service to be active. This field ensures that the package relies on the presence and activation of the specified target or service.

Package: ConfExt only

  • depends_on_extended

    • Type: bool
    • Example
      ​​​​depends_on_extended = true
      

The "depends_on_extended" field is a boolean flag that, when set to true, indicates that the package depends on extended packages or configurations. It signifies that the package relies on or requires additional configurations provided by extended packages or components. When set to true, it enforces dependencies on extended configurations.

  • external

    • Type: bool
    • Example
      ​​​​external = true
      

The "external" field is a boolean flag that, when set to true, indicates that the package is considered external or provided by an external source. It signifies that the package is not part of the local packaging system but is instead sourced from an external repository or location. Setting this flag to true distinguishes the package as an external dependency.

  • extends

    • Type: TemplateString
    • Example
      ​​​​extends = "tor"
      
    • Variant example
      ​​​​extends = "bitcoin-@variant"
      

The "extends" field specifies the name of a package or configuration that the current package extends or inherits from. It allows the current package to inherit properties and settings from the specified package or configuration. This field establishes an inheritance relationship, enabling the current package to build upon the settings of the extended package.

  • extended_by

    • Type: List of TemplateString
    • Example
      ​​​​extended_by = ["tor-hs-patch-config", "selfhost-clearnet"]
      
    • Variant example

The "extended_by" field specifies a list of packages or configurations that extend or inherit properties and settings from the current package. It indicates which other packages or configurations build upon the current package's settings. This field establishes a relationship where the current package serves as a base for other packages or configurations.

  • replaces

    • Type: Boolean or List of TemplateString
    • Example
      ​​​​replaces = false
      
    • Variant example
      ​​​​replaces = ["bitcoin-chain-mode-{variant}"]
      

The "replaces" field specifies whether the current package replaces other packages or configurations. It can be set to false to indicate that the package does not replace any other packages. Alternatively, it can be a list of TemplateStrings representing the names of packages that the current package replaces.

Types

String

Bool

TemplateString

Defining a TemplateString:

In your TOML configuration file, a TemplateString can be defined as a string value enclosed in double (") or triple (""") quotes. Triple quotes are employed for multi-line strings. Placeholders for variables are included using curly braces {}.

Example:

template = "This is a {} template."

In this example, "This is a {} template." constitutes a TemplateString with {} acting as a placeholder for a variable.

Providing Variable Values:

Within the same TOML file or a related configuration, you have the option to define values for variables. These values will replace the placeholders within the TemplateString and are specified as regular string values.

Example:

variable = "customized"

In this case, "customized" serves as the value that will substitute the {} placeholder within the template.

Using TemplateString in Configuration:

To utilize the TemplateString in your configuration, reference it by its assigned name (e.g., "template") and incorporate variable values where required using the {variable_name} format.

Example:

message = "This is a {variable} template."

In this example, the message field makes use of the TemplateString defined earlier, and the variable value, "customized," replaces {variable} within the resulting message.

Confdir

The ConfDir struct represents configuration directory settings and can be used within a TOML file to specify configuration directory attributes. Below is the documentation for the ConfDir struct:


# ConfDir Struct in TOML Configuration

# The `ConfDir` struct is used to define configuration directory attributes.
# It specifies the parameters and name of the configuration directory.

# Example short usage:
conf_d = { param = "--conf-dir", name = "my_config" }


# Alternate usage
[conf_d]

# param (required): Specifies the parameter used to set the configuration directory.
# This parameter is used to indicate the path or location of the configuration directory.
param = "--conf-dir"

# name (required): Specifies the name of the configuration directory.
# The name is typically a user-defined identifier for the configuration directory.
name = "my_config"

In the above TOML documentation:

The ConfDir struct is explained as a way to define configuration directory attributes.
It includes two required fields:

  • param: Specifies the parameter used to set the configuration directory. This parameter indicates the path or location of the configuration directory.
  • name: Specifies the name of the configuration directory, which is typically a user-defined identifier.
    An example usage is provided to illustrate how to use the ConfDir struct within a TOML configuration file

ConfParam

The ConfParam enum provides a way to define different types of configuration parametersin a TOML configuration file. It is designed to help you format configuration parameters correctly.


# Usage Examples:

# To specify a configuration parameter with a value separated by a space, you can simply provide the parameter followed by the value.
# Example:
# conf_param = "--config /etc/my_config.conf"
conf_param = "--config /etc/my_config.conf"

# To specify a configuration parameter with a value without spaces, use an equals sign (=) to separate the parameter and its value.
# Example:
# conf_param = "--port=8080"
conf_param = "--port=8080"

# For a bare configuration parameter without a value, you can directly provide the parameter itself.
# Example:
# conf_param = "--verbose"
conf_param = "--verbose"

UserSpec

# User Configuration Example

# Short usage 
user_spec = { group = true, create = { home = false } }

# This example demonstrates how to configure user-related settings using the `UserSpec` struct directly.

[user_spec]

# Configure the user as follows:
# - Create a user group.
# - Do not create a home directory for the user.

[user_spec.create]
home = false
group = true

ExtraGroup

# Extra Group Configuration

# The `ExtraGroup` struct is used to configure additional user groups in a TOML configuration file.

[extra_group]
create = true
# Short Usage Example:

# To configure an extra group, you can use the short syntax by directly specifying the `create` field with a boolean value.
# Set `create` to `true` to create the extra group, or `false` to skip its creation.

# Example:
extra_group = { create = true }

VPackageName

TODO

FileVar

TODO

Config

# Main file or directory configuration section
[config."<filename|dirname>"]

# Internal variables specific to the file
[config."<filename|dirname>".ivars]
"<variable_name>" = "<variable_value>"

# Hidden variables that won't be exposed to dpkg-configure
[config."<filename|dirname>".hvars]
"<variable_name>" = "<variable_value>"

# Extend the file's configuration by adding extra variables
[config."<filename|dirname>".evars]
"<variable_name>" = "<variable_value>"

In summary:

  • [config.<filename|dirname>] is the main file or directory configuration section.
  • [config.<filename|dirname>.ivars.<variable_name>] is used for defining internal variables specific to the file.
  • [config.<filename|dirname>.hvars.<variable_name>] is used for defining hidden variables that won't be exposed to dpkg-configure.
  • [config.<filename|dirname>.evars.<variable_name>] is used to extend the file's configuration by adding extra variables.
[config.<filename|dirname>]

This structure represents a file configuration section in a TOML configuration file, where <filename|dirname> should be replaced with the actual name of the file you're configuring.

Example for allowed values for [config.<filename|dirname>]

# Example TOML configuration file with configuration parameters

# Define the format for the configuration data
[config.example]
format = "toml"

# Specify directories to be created under /etc
cat_dir = ["conf.d", "data"]

# List of files to be appended to the configuration file
cat_files = ["file1", "file2"]

# Set file permissions to public (644)
public = true

# Define the content to be written to the file
content = """
Hello World!
"""

# Insert header and additional content at the beginning of the file
insert_header = "#Hello Example"
insert_header = """
# This file has a very long header description
# 
# End of long header
"""

# Define file variables and their values
[config.example.fvars]
type = "path"
file_type = "regular"
structure = ["SSO", "rtlCookiePath"]

# Add an additional comment or description
comment = "Some additional comment"

# Specify post-processing commands
[config.example.postprocess]
command = ["echo", "hello world"]

# Specify details about file generation after post-processing
[config.example.postprocess.generates]
dir = ""
file = ""
format
  • Type: One of the following - plain, toml, yaml, json, spaceseperated.
  • Example:
    ​​​​[config.example]
    ​​​​format = "toml"
    
    In this example, the "format" field is set to "toml," indicating that the configuration data for config.example will be represented in TOML format.

The "format" field allows you to specify the format in which your configuration data should be represented. You can choose one of the following formats:

  • plain: Represents the configuration data in plain, unformatted text.
  • toml: Represents the configuration data in TOML (Tom's Obvious, Minimal Language) format.
  • yaml: Represents the configuration data in YAML (YAML Ain't Markup Language) format.
  • json: Represents the configuration data in JSON (JavaScript Object Notation) format.
  • spaceseperated: Represents the configuration data in a space-separated format.
cat_dir
  • Type: List of TemplateString
  • Usage Example:
    ​​​​[config.example]
    ​​​​format = "toml"
    ​​​​cat_dir = ["conf.d", "data"]
    
    In this example, the "cat_dir" field defines two directories, "conf.d" and "data," which will be created under the /etc directory.
  • Post-install Action: The "cat_dir" field typically implies a post-install action where files in the specified directories (relative to /etc/example/) are concatenated and appended to a target file.

The "cat_dir" field specifies a directory or directories, represented as a list of TemplateString values, that will be created under the /etc directory. These directories will be placed in the /etc directory, and they can be used to organize configuration files or data.

cat_files
  • Type: List of TemplateString
  • Example:
    ​​​​[config.example]
    ​​​​format = "toml"
    ​​​​cat_files = ["file1", "file2"]
    
    In this example, the "cat_files" field specifies a list of files, "file1" and "file2," that will be appended to the configuration file during post-installation.

The cat_files field allows you to specify a list of files that will be appended to the configuration file during post-installation.

public
  • Type: bool
  • Example:
    ​​​​[config.example]
    ​​​​public = true
    
    In this example, setting public to true indicates that the associated file should have its permissions set to 644. If the public field is not specified or set to false, the default permissions of 640 will be used.

The public field allows you to control the file permissions for the associated file. When set to true, it ensures that the file is made publicly readable (644), while false uses the default permissions of 640.

content
  • Type: TemplateString
  • Example:
    ​​​​[config.example]
    ​​​​content = """
    ​​​​Hello World!
    ​​​​"""
    
    In this example, the "content" field allows you to specify the content that will be written to the associated file. The content should be enclosed within triple-quotes (""") to allow for multi-line content.

The content field is used to define the content that will be written to the file associated with it. You can use triple-quotes to enclose multi-line content for the file.

insert_header
  • Type: TemplateString
  • Example:
    ​​​​[config.example]
    ​​​​insert_header = "#Hello Example"
    ​​​​insert_header = """
    ​​​​# This file has a very long header description
    ​​​​# 
    ​​​​# End of long header
    ​​​​"""
    
    In this example, the "insert_header" field allows you to specify a header or additional content that will be inserted at the beginning of the associated file. You can provide both single-line and multi-line headers using triple-quotes (""").

The insert_header field is used to add a header or additional content at the beginning of the associated file. It supports both single-line and multi-line headers.

fvars
  • Type: Map of String to Filevar
  • Example:
    ​​​​[config.example]
    ​​​​type = "path"
    ​​​​file_type = "regular"
    ​​​​structure = ["SSO", "rtlCookiePath"]
    
    In this example, the "fvars" field is used to define a map of String to Filevar. It allows you to specify a set of file variables (Filevar) with associated values. Each key in the map represents the name of a file variable, and the corresponding value is an instance of the Filevar type.

The fvars field is used to specify file variables and their values for the associated configuration. It provides a way to configure file-related settings using a map format.

comment
  • Type: String
  • Example:
    ​​​​[config.example]
    ​​​​comment = "Some additional comment"
    
    In this example, the "comment" field allows you to add an additional comment or description to the associated configuration. The comment should be provided as a string value.

The comment field is used to include additional comments or descriptions within the configuration. It helps provide context or explanations for specific configuration settings.

postprocess
  • Type: List of TemplateString
  • Usage Example:
    ​​​​[config.example.postprocess]
    ​​​​command = ["echo", "hello world"]
    
    In this example, the "postprocess" field is a list of TemplateString values. Each TemplateString represents a command or script to be executed as part of the post-processing phase after the associated configuration is applied.
postprocess.generates
  • Type: Object
  • Usage Example:
    ​​​​[config.example.postprocess.generates]
    ​​​​dir = ""
    ​​​​file = ""
    
    The "generates" section allows you to specify additional details related to file generation as part of the post-processing. It includes the following fields:
    • dir: Specifies the directory where generated files should be placed. Provide a TemplateString to dynamically determine the directory path.
    • file: Specifies the name of the generated file. Provide a TemplateString to dynamically determine the file name.

The generates section complements the postprocess field by providing information about where and how generated files should be placed after post-processing.

[config.<filename|dirname>.ivars.<variable_name>]

Within the file configuration section, you can define internal variables (ivars) using the <variable_name>. These internal variables are meant to be used within the configuration for the specified file. This variable will be shown with dpkg-configure.

# Main file or directory configuration section
[config."<filename|dirname>"]

# Internal variables specific to the file
[config."<filename|dirname>".ivars]
"<variable_name>" = "<variable_value>"

[config."<filename|dirname>".ivars."<variable_name>"]
# Short description of the variable
summary = "Description of the variable"

# Detailed documentation of the variable
long_doc = """
Detailed documentation explaining the variable's purpose and usage.
"""

# Default value for the variable
default = "Default value for the variable"

# Script to calculate and overwrite the default value
try_overwrite_default = """
Script to dynamically calculate and overwrite the default value.
"""

# DebConf priority for presenting the configuration question
priority = { dynamic = { script = "Script to calculate priority based on conditions" } }

# Store the value as part of the package's configuration
store = true

# Ignore the variable if no value is provided
ignore_empty = true

# Additional field placeholders (structure and conditions)
structure = ["Additional field placeholders"]
conditions = ["Additional field placeholders"]
summary
  • Type: TemplateString
  • Example:
    ​​​​summary = "Directory containing the timechain data"
    
    In this example, the "summary" field is used to describe the variable or configuration item as a directory that holds timechain data.

The "summary" field provides a concise and short description of the variable or configuration item it is associated with. It serves as a way to summarize the purpose or content of the variable in a clear and brief manner.

The summary field is typically used to provide a quick and informative summary of the variable's purpose or content. It helps users understand the variable's role without needing to read detailed documentation.

long_doc
  • Type: TemplateString
  • Example:
    ​​​​long_doc = """
    ​​​​The full path to the directory which will contain timechain data (blocks and chainstate).
    ​​​​Important: you need around 10GB of free space!
    ​​​​"""
    
    In this example, the "long_doc" field offers a detailed explanation of the variable, including its purpose, the type of data it holds, and an important note about the required amount of free space.

The long_doc field is used when more extensive documentation is needed to convey detailed information about the variable, helping users understand its significance and usage in-depth.

default
  • Type: TemplateString
  • Example:
    ​​​​default = "/var/lib/bitcoin-mainnet"
    
    In this example, the "default" field sets the default value for the variable to "/var/lib/bitcoin-mainnet."

The default field allows you to define a fallback value that will be used when the user does not specify a value for the associated variable or configuration item, ensuring that there is always a value available for the variable.

try_overwrite_default
  • Type: TemplateString
  • Example:
    ​​​​try_overwrite_default = """
    ​​​​mem_avail=`grep MemTotal /proc/meminfo | awk '{{print $2}}'` &&
    ​​​​if [ $mem_avail -lt 1024000 ]; then
    ​​​​   echo -n 450;
    ​​​​elif [ $mem_avail -lt 2048000 ]; then
    ​​​​   echo -n 512;
    ​​​​elif [ $mem_avail -lt 4096000 ]; then
    ​​​​   echo -n 1024;
    ​​​​elif [ $mem_avail -lt 8192000 ]; then
    ​​​​   echo -n 2048;
    ​​​​else echo -n 4096; fi
    ​​​​"""
    
    In this example, the "try_overwrite_default" field contains a script that calculates a memory-based value and attempts to overwrite the default value of the associated variable based on the available system memory.

The try_overwrite_default field allows you to specify a script that dynamically calculates a new value for the variable and replaces the default value if the script produces a valid result.

priority
  • Type: DebConfPriority
  • Example:
    ​​​​priority = { dynamic = { script = "test `df /var | tail -1 | awk '{ print $4; }'` -lt 10000000 && PRIORITY=high || PRIORITY=medium"} }
    
    In this example, the "priority" is calculated by a script. If the script condition is met (available disk space in /var is less than 10,000,000), the priority is set to "high"; otherwise, it is set to "medium."

The priority field allows you to dynamically set the DebConf priority based on specific conditions or calculations, ensuring that the configuration question is presented with the appropriate level of importance and urgency during package management.

store
  • Type: bool
  • Example:
    ​​​​store = true
    
    In this example, the "store" field is set to true, indicating that the variable's value should be stored as part of the package's configuration.

The store field allows you to specify whether the value of the configuration variable should be retained and stored as part of the package's configuration data. Setting it to true ensures that the value is saved, while false prevents it from being stored.

ignore_empty
  • Type: bool
  • Example:
    ​​​​ignore_empty = true
    
    In this example, the "ignore_empty" field is set to true, indicating that the variable should be ignored if no value is provided during package configuration.

The ignore_empty field provides a way to control the behavior of the package when handling configuration variables. Setting it to true allows you to skip empty or unspecified variables, while false enforces the requirement of a value, even if it is empty.

structure
  • Type: List of String
  • Example:
    ​​​​summary = "Directory containing the timechain data"
    

Not sure

conditions
  • Type: List of IntervalVarCondition
  • Example:

???

[config.<filename|dirname>.hvars.<variable_name>]

Similarly, within the file configuration section, you can define hidden variables (hvars) using <variable_name>. These variables are hidden from dpkg-configure and are not meant to be exposed externally.

# Main file or directory configuration section
[config."<filename|dirname>"]

# Hidden variables specific to the file
[config."<filename|dirname>".hvars]
"<variable_name>" = "<variable_value>"

# Ignore the variable if no value is provided
[config."<filename|dirname>".hvars."<variable_name>"]
ignore_empty = true

# Store the value as part of the package's configuration
store = true

# Additional field placeholders (val and structure)
val = "HiddenVarVal placeholder"
structure = ["Additional field placeholders"]

ignore_empty
  • Type: bool
  • Example:
    ​​​​ignore_empty = true
    
    In this example, the "ignore_empty" field is set to true, indicating that the variable should be ignored if no value is provided during package configuration.

The ignore_empty field provides a way to control the behavior of the package when handling configuration variables. Setting it to true allows you to skip empty or unspecified variables, while false enforces the requirement of a value, even if it is empty.

store
  • Type: bool
  • Example:
    ​​​​store = true
    
    In this example, the "store" field is set to true, indicating that the variable's value should be stored as part of the package's configuration.

The store field allows you to specify whether the value of the configuration variable should be retained and stored as part of the package's configuration data. Setting it to true ensures that the value is saved, while false prevents it from being stored.

val
  • Type: HiddenVarVal
  • Example:
    ​​​​store = false
    

??? Not sure how this is provided

structure
  • Type: List of String
  • Example:
    ​​​​structure = ["Authentication", "macaroonPath"]    ```
    
    

???

[config.<filename|dirname>.evars.<variable_name>]

Lastly, you can extend the configuration of the file by defining external variables (evars) using<variable_name>. These variables allow you to append additional configuration settings to the files you don't own, extending its functionality.

# Main file or directory configuration section
[config."<filename|dirname>"]

# External variables specific to the file
[config."<filename|dirname>".evars]
"<variable_name>" = "<variable_value>"

# Name of the external variable
[config."<filename|dirname>".evars."<variable_name>"]
name = "External Variable Name"

# Store the value as part of the package's configuration
store = true

# Ignore the variable if no value is provided
ignore_empty = true

# Additional field (structure) for external variables
structure = ["Additional field placeholders"]

name
  • Type: String
store
  • Type: bool
  • Example:
    ​​​​store = true
    
    In this example, the "store" field is set to true, indicating that the variable's value should be stored as part of the package's configuration.

The store field allows you to specify whether the value of the configuration variable should be retained and stored as part of the package's configuration data. Setting it to true ensures that the value is saved, while false prevents it from being stored.

ignore_empty
  • Type: bool
  • Example:
    ​​​​ignore_empty = true
    
    In this example, the "ignore_empty" field is set to true, indicating that the variable should be ignored if no value is provided during package configuration.

The ignore_empty field provides a way to control the behavior of the package when handling configuration variables. Setting it to true allows you to skip empty or unspecified variables, while false enforces the requirement of a value, even if it is empty.

structure
  • Type: List of string

???

[config."null"]

  • Explanation: The [config."null"] configuration section is a special and unique hack used to define postprocess or preinstall actions that are not associated with a specific file or configuration variable. It allows you to execute custom scripts or commands during the package installation or configuration process. This section can be used to perform tasks that are not directly related to the configuration of files or variables but are still necessary as part of the package's installation or setup.
  • Usage: You can define postprocess or preinstall actions within the [config."null"] section by specifying the desired commands or scripts. These actions will be executed at the appropriate stage of the package installation or configuration process.
  • Example:
    ​​​​[config."null"]
    ​​​​postprocess = [
    ​​​​    "echo 'Performing custom post-installation action'",
    ​​​​    "chmod +x /path/to/script.sh",
    ​​​​    "/path/to/script.sh --option value",
    ​​​​]
    
    In this example, the [config."null"] section defines a postprocess action that includes multiple commands to be executed as part of a custom post-installation action.

The [config."null"] configuration section is a flexible and powerful feature that allows you to extend package configuration beyond file-related settings and configuration variables, enabling custom actions and scripts as needed.

[map_variant.<variable_name>]

The [map_variant.<variable_name>] configuration section is used to define variable values that are specific to different variants of a package or configuration. Variants are identified by their names (e.g., mainnet, regtest) and are typically represented using the @variant placeholder. This section allows you to map values to specific variants, ensuring that the correct value is used depending on the active variant during package configuration.

  • Usage: Within the [map_variant.<variable_name>] section, you can specify the values for different variants using variant names as keys and their respective values as values. This allows you to configure variables differently based on the active variant.
  • Example:
    ​​​​[map_variant.mainnet_enabled]
    ​​​​mainnet = "1"
    ​​​​regtest = "0"
    
    In this example, the [map_variant.mainnet_enabled] section defines two mappings for the mainnet and regtest variants. When the package is configured with the mainnet variant, the variable mainnet_enabled will have a value of "1". Conversely, when the regtest variant is active, the value will be "0".
  • Additional Details: This configuration section is particularly useful when dealing with variant-specific settings or behaviors. It allows you to customize package configuration based on the specific variant being used, ensuring that variables have the appropriate values for each variant.

The [map_variant.<variable_name>] configuration section provides a way to tailor variable values to different package variants, enhancing flexibility and customization in your package configurations.

[alternatives.<filename>]

Explanation: The [alternatives.<filename>] configuration section is used to define alternatives for files in a package. Alternatives allow multiple packages to provide the same functionality (e.g., command-line tools) while enabling users to select the preferred implementation. This section specifies details for the alternatives, including the name, destination, and priority.

  • Usage: Within the [alternatives.<filename>] section, you can define the following attributes:
    • name: Specifies the name of the alternative. This is the name that users will use to select the alternative.
    • dest: Defines the destination path where the alternative will be installed. This is typically a symbolic link to the actual file.
    • priority: Assigns a priority value to the alternative. Alternatives with higher priority values are considered more preferred.
  • Example:
    ​​​​[alternatives."/usr/share/lncli/xlncli"]
    ​​​​name = "lncli"
    ​​​​dest = "/usr/bin/lncli"
    ​​​​priority = 100
    
    In this example, an alternative named "lncli" is defined for the file located at "/usr/share/lncli/xlncli". The alternative will be installed at "/usr/bin/lncli" with a priority of 100.
  • Additional Details: Alternatives are commonly used to manage interchangeable components or commands within a package. Users can choose their preferred alternative using system-level commands like update-alternatives on Debian-based systems. The priority value helps determine which alternative is the default when multiple options are available.

The [alternatives.<filename>] configuration section provides a way to manage alternative implementations of files or commands, enhancing flexibility and user choice in package installations.

[[plug]]

The [[plug]] configuration section is used to define external scripts or commands that can be executed as part of package installation or removal. These scripts are referred to as "plugs" and provide a way to perform custom actions during package management processes.

  • Usage: Within each [[plug]] section, you can define the following attributes:
    • run_as_user (optional): Specifies the user under which the plug should be executed. If not provided, the plug will run with the default user permissions.
    • register_cmd: Defines the command or script to execute when registering the plug during package installation. This command is typically used to set up or configure the plug.
    • unregister_cmd: Specifies the command or script to execute when unregistering or removing the plug during package removal. This command is used to clean up or deactivate the plug.
  • Example:
    ​​​​[[plug]]
    ​​​​run_as_user = "root"
    ​​​​register_cmd = ["/usr/share/lnd-auto-unlock/set.sh", "{variant}"]
    ​​​​unregister_cmd = ["rm", "-f", "/var/lib/lnd-system-{variant}/.auto_unlock"]
    
    In this example, a plug is defined with the following details:
    • It is executed as the "root" user.
    • The register_cmd command runs the script "/usr/share/lnd-auto-unlock/set.sh" with the "{variant}" parameter during package installation.
    • The unregister_cmd command removes the "/var/lib/lnd-system-{variant}/.auto_unlock" file during package removal.
  • Additional Details: The [[plug]] configuration sections are commonly used to integrate external scripts or commands into package management workflows. These scripts can perform various tasks such as configuration, initialization, or cleanup specific to the package's functionality.

The [[plug]] section offers flexibility for package maintainers to extend and customize package management actions by executing external scripts or commands at specific points in the installation or removal process.

[databases.<databasename>]

The [databases.<databasename>] configuration section is used to define a specific database connection configuration for a database system with the given <databasename>. This configuration allows you to specify the connection details, such as the host, port, user, password, and database name, needed to establish a connection to the database.

  • Type: TemplateString

  • Usage: To define a database connection configuration for a specific database system, you should create a [databases.<databasename>] section, where <databasename> is a placeholder for the actual name of the database system (e.g., [databases.mysql], [databases.postgresql]). Within this section, you can define the following fields:

    • template: A string field that represents the connection string template. This template can contain placeholders for various connection parameters that will be replaced with actual values when connecting to the database.
  • Example:

    ​​​​[databases.postgresql]
    ​​​​template = """
    ​​​​postgresql://_DB_USER_:_DB_PASSWORD_@_DB_HOST_:_DB_PORT_/_DB_NAME_
    ​​​​"""
    

    In this example, a configuration for a PostgreSQL database connection is defined using the [databases.postgresql] section. The template field specifies the connection string template, which includes placeholders such as _DB_USER_, _DB_PASSWORD_, _DB_HOST_, _DB_PORT_, and _DB_NAME_.

  • Additional Details: The [databases.<databasename>] configuration sections allow you to organize and manage database connection configurations for different database systems within your TOML configuration file. Each section corresponds to a specific database system, and the provided template defines how the connection string should be formatted.

    By using these configuration sections, you can ensure that your application can easily switch between different databases or database providers by referencing the appropriate [databases.<databasename>] section, which provides the necessary connection details. This approach simplifies database configuration management and enhances the portability of your application across different database systems.

[migrations.<version_number>]

The [migrations] configuration section is used to define migration scripts that need to be executed when specific conditions or versions of a package or application are met during the upgrade or installation process. These migration scripts typically handle tasks like data migration, configuration updates, or cleanup operations.

  • Usage: To define a migration script, you should create a [migrations."<< version"] section, where version is a placeholder for the specific package version to which the migration script applies. You can define multiple [migrations] sections with different versions to handle various migration scenarios. Within each [migrations."<< version"] section, you can define the following fields:

    • config (Optional): A string field containing the migration script that needs to be executed. This script can include shell commands or instructions to perform specific migration tasks. You can use shell scripting syntax to define the migration logic.
    • preinst (Optional): A string field that defines a migration script to be executed before the package is installed or upgraded. This script can handle any pre-installation tasks or checks required for the migration.
    • postinst (Optional): A string field that defines a migration script to be executed after the package is installed or upgraded. This script can perform post-installation tasks, configuration updates, or data migration.
    • prerm (Optional): A string field that defines a migration script to be executed before the package is removed or downgraded. This script can handle any pre-removal cleanup or data backup tasks.
    • postrm (Optional): A string field that defines a migration script to be executed after the package is removed or downgraded. This script can perform post-removal cleanup or data archiving tasks.
    • preinst_finish (Optional): A string field that defines a migration script to be executed after the package installation process is completed but before the package is configured. This script can handle any additional setup or checks needed.
    • postinst_finish (Optional): A string field that defines a migration script to be executed after the package installation process is completed and the package is configured. This script can perform final configuration or cleanup tasks.
  • Example:

    ​​​​[migrations."<< 0.10.1-2"]
    ​​​​postinst_finish = """
    ​​​​rm -rf /var/lib/ridetheln-system/sso
    ​​​​"""
    

    In this example, a migration script is defined for the version "0.10.1-2." The postinst_finish field specifies a script that removes a specific directory (/var/lib/ridetheln-system/sso) as part of the post-installation finish process.

    ​​​​[migrations."<< 0.9.9-1"]
    ​​​​config = """
    ​​​​db_get electrs-{variant}/verbose || RET="2"
    ​​​​if [ "$RET" -eq 0 ];
    ​​​​then
    ​​​​\tlog_filters=error
    ​​​​elif [ "$RET" -eq 1 ];
    ​​​​then
    ​​​​\tlog_filters=warn
    ​​​​elif [ "$RET" -eq 2 ];
    ​​​​then
    ​​​​\tlog_filters=info
    ​​​​else
    ​​​​\tlog_filters=debug
    ​​​​fi
    ​​​​\techo "Migrating verbose level $RET to log_filters=$log_filters" >&2
    ​​​​\tdb_set electrs-{variant}/log_filters "$log_filters"
    ​​​​\tdb_fset electrs-{variant}/log_filters seen false || true
    ​​​​"""
    

    In this example, a migration script is defined for the version "0.9.9-1." The config field specifies a script that checks a database value (electrs-{variant}/verbose) and updates another database value (electrs-{variant}/log_filters) based on the retrieved value. This script handles the migration of verbose levels to log filters during the upgrade process.

  • Additional Details: The [migrations] configuration section allows you to automate migration tasks when packages or applications are upgraded or installed. By defining migration scripts for specific versions or conditions, you can ensure that your system transitions smoothly and performs any necessary data migration or configuration updates during package management operations.

To check with Martin if the document is correct, some notable questions:

  • structure field
  • val field
  • condition field
  • conf.d
  • VPackageName naming
  • conf.param is that correct?
  • check TemplateString
  • TODO check if [[plug]] is correct
  • TODO check if alternatives section is correct
  • TODO where are @variant values come from
  • check migrations

For me to fill out:

  • add example for ivars with allowed values
  • add examples for evars
  • add examples of hvars
  • FileVar
  • TODO document requires field
  • TODO add links to debconf
  • TODO add links to system.d
  • TODO add backlink reference to types
  • TODO add links to debcrafter
  • TODO check if the architecture field are correct