Empaquetado de Configuración por Producto

En el entorno de Fedora.next, contamos con una selección de productos Fedora, además de la disponibilidad de la versión clásica de Fedora. Tradicionalmente, hemos mantenido una configuración predeterminada única para todas las instalaciones de Fedora, pero los distintos casos de uso tienen necesidades diferentes. El objetivo de este documento es establecer las directrices para crear configuraciones predeterminadas específicas para cada producto.

Queremos garantizar que todos los paquetes tengan valores predeterminados razonables para cualquier Producto en el que estén instalados, y al mismo tiempo evitar situaciones donde los usuarios tengan algunos paquetes instalados con los valores predeterminados de un Producto y algunos paquetes con los de otro.

Requisitos

  • Todos los paquetes DEBEN tener una configuración predeterminada global. Esta configuración se utilizará siempre que no se requiera una configuración predeterminada específica del producto. (Por ejemplo, si se utiliza una instalación que no es del producto o si solo Fedora Cloud tiene una configuración personalizada y se instaló Fedora Workstation).

  • Cualquier paquete que requiera una configuración predeterminada por producto DEBE proporcionar todos los archivos de configuración alternativos en el mismo paquete.

  • Any package that requires a configuration that differs between Products MUST obtain permission from that Product’s Working Group before packaging it.

Configuración Predeterminada Global

  • The global default configuration MUST be provided by the package that requires it.

  • The global default configuration MUST be named based on the package’s normal naming scheme, with the main part of the name being suffixed by -default. For example, if the package normally uses foo.conf, then the global default configuration MUST be named foo-default.conf.

Per-Product Default Configuration

  • For each Product requiring a unique default configuration, the packager MUST provide a copy of the default configuration file, modified as appropriate for the specific product.

  • The product-specific configuration file MUST be named based on the package’s normal naming scheme, with the main part of the name being suffixed by a dash followed by the name of the product. For example, if the package normally uses foo.conf, then the Server version MUST be named foo-server.conf.

  • If the configuration will be symlinked in place, the product-specific configuration file MUST be located in an appropriate part of the /etc hierarchy. The divergent config file MUST be specified as %config(noreplace) in %files as per the usual /etc packaging guidelines.

  • If the configuration will be copied in place, the product-specific configuration file MUST be located in an appropriate part of the /usr/share hierarchy. The divergent config file MUST be specified as a normal file in the %files section.

Applying Configuration

In order to apply the configuration, the packager MUST implement a mechanism in the %posttrans section of the specfile that behaves as follows:

  • It MUST first check whether the final config file already exists. If so, the script MUST make no changes.

    %posttrans
    if [ ! -e %{_sysconfdir}/foo/foo.conf ]; then
        ...
    fi
  • Then it MUST use the value of the Fedora VARIANT_ID to symlink or copy one of the divergent config files (or the default) to the final config file location. It will get this value by importing the contents of /etc/os-release as shell values. Known values of this field at the time of this writing are "atomichost", "cloud", "server" and "workstation". For more detail, see the os-release(5) man page.

    . /etc/os-release || :
    case "$VARIANT_ID" in
        server)
            ln -sf foo-server.conf %{_sysconfdir}/foo/foo.conf || :
            ;;
        *)
            ln -sf foo-default.conf %{_sysconfdir}/foo/foo.conf || :
            ;;
        esac
  • Lastly, the final config file location MUST be listed in the %files section with %ghost:

    %ghost %config(noreplace) %{_sysconfdir}/foo/foo.conf
  • For tracking purposes, the package providing the various configuration files MUST also contain a virtual Provides: for each variant configuration that may be applied:

    Provides: variant_config(Atomic.host)
    Provides: variant_config(Cloud)
    Provides: variant_config(Server)
    Provides: variant_config(Workstation)

Ejemplo (firewalld)

We will assume for the sake of demonstration that firewalld will need a custom configuration for Fedora Server and Fedora Workstation, but that Fedora Cloud will not require any changes from the global default.

...
Provides: variant_config(Server)
Provides: variant_config(Workstation)
...

%posttrans
# If we don't yet have a symlink or existing file for firewalld.conf,
# create it. Note: this will intentionally reset the policykit policy
# at the same time, so they are in sync.
if [ ! -e %{_sysconfdir}/firewalld/firewalld.conf ]; then
    # Import /etc/os-release to get the variant definition
    . /etc/os-release || :

    case "$VARIANT_ID" in
        server)
            ln -sf firewalld-server.conf %{_sysconfdir}/firewalld/firewalld.conf || :
            ln -sf org.fedoraproject.FirewallD1.server.policy \
                %{_datadir}/polkit-1/actions/org.fedoraproject.FirewallD1.policy || :
            ;;
        workstation)
            ln -sf firewalld-workstation.conf %{_sysconfdir}/firewalld/firewalld.conf || :
            ln -sf org.fedoraproject.FirewallD1.desktop.policy \
                %{_datadir}/polkit-1/actions/org.fedoraproject.FirewallD1.policy || :
            ;;
        *)
            ln -sf firewalld-default.conf %{_sysconfdir}/firewalld/firewalld.conf || :
            # La normativa de cortafuegos predeterminada será la misma que la del servidor.
            ln -sf org.fedoraproject.FirewallD1.server.policy \
                %{_datadir}/polkit-1/actions/org.fedoraproject.FirewallD1.policy || :
            ;;
        esac
fi

…

%files -f %{name}.lang
…
%attr(0750,root,root) %dir %{_sysconfdir}/firewalld
%ghost %config(noreplace) %{_sysconfdir}/firewalld/firewalld.conf
%config(noreplace) %{_sysconfdir}/firewalld/firewalld-default.conf
%config(noreplace) %{_sysconfdir}/firewalld/firewalld-server.conf
%config(noreplace) %{_sysconfdir}/firewalld/firewalld-workstation.conf
…
%ghost %{_datadir}/polkit-1/actions/org.fedoraproject.FirewallD1.policy
%{_datadir}/polkit-1/actions/org.fedoraproject.FirewallD1.desktop.policy
%{_datadir}/polkit-1/actions/org.fedoraproject.FirewallD1.server.policy