# Package Management for RHEL 8

How to add packages and package repositories and what repositories are available is documented here.

## Package Installation

### Install Packages with Hiera Package Groups

The packages automatically installed onto a system by Puppet are managed in the Hiera list `base::package_groups`. It contains the names of the package groups to be installed. Items can be added at all levels of the Hiera hierarchy and are merged.

The package groups itself are Hieara lists named `base::pkg_group::$USE_CASE`.
Here list all the packages you want to install.

Currently there exist the following package groups in the main [`common.yaml`](https://git.psi.ch/linux-infra/puppet/-/blob/preprod/data/common.yaml):

- `base::pkg_group::system_tools` (installed by default)
- `base::pkg_group::daq_buffer`
- `base::pkg_group::desktop_settings`
- `base::pkg_group::dev`
- `base::pkg_group::login_server`
- `base::pkg_group::qt5`
- `base::pkg_group::root`

but further ones can be created in Hiera at lower hierachies and added to `base::package_groups`, for example

```
base::pkg_group::java:
    - 'java-1.8.0-openjdk'
    - 'java-11-openjdk'
    - 'java-17-openjdk'

base::package_groups:
    - 'java'
```

### Install a Group of Packages

To add a RedHat predefined group of packages (checkout out `dnf grouplist --hidden`) prepend the name of it with a `@`, e.g. for "Java Platform" it would be `@Java Platform`:

```
base::pkg_group::java:
    - '@Java Platform'
```

### Install Latest Package Version

To ensure that always the latest available package version is installed, append the `:latest` tag to the package name in the package group:

```
base::pkg_group::java:
    - 'java-1.8.0-openjdk'
    - 'java-11-openjdk'
    - 'java-17-openjdk:latest'
```

### Install Packages only on Given OS Version

**implemented only in rhel8_preprod branch**
 
 Certain packages are only used on a given OS Version, so a `os=` with the OS name and the major version selects a package only for given OS, where as a `os!` will filter away given package on hosts with given OS, so they are not installed there.

```
base::pkg_group::java:
    - 'java-1.8.0-openjdk:os=redhat7'
    - 'java-11-openjdk'
    - 'java-17-openjdk:os!redhat7'
```

Note that this tag can be combined with the `latest` and `absent` tag.

### Remove Packages

To remove an already installed package, append the `:absent` tag to the package name in the package group:

```
base::pkg_group::java:
    - 'java-1.8.0-openjdk:absent'
    - 'java-11-openjdk'
    - 'java-17-openjdk'
```

### Ignore Packages

To make packages unavailable for installation, even though provided by the package repositories, add them in Hiera to the list `base::package_exclude`:
```
base::package_exclude:
    - 'epics-base-7.0.6*'
```

### Legacy Package Installation

The legacy Hiera lists for package groups is `yum_client::pkg_group::$USE_CASE` and supports the `latest` and `absent` tag, but not the filtering by operating system version.

Then `yum_client::package_groups` is the Hiera list to contain the package groups to be installed.

Please migrate them to the equivalent `base::*` list. You can have both of them available at the same time, with possibly the same content.

## Management of Package Repositories

### Package Repository Lists
Also for configuring package repositories our configuration management works with lists containing the names of the repositories to be installed.
The default list (except for nodes with the `bootpc` and `appliances::lenovo::*` Puppet roles) is `rpm_repos::default` (legacy: `yum_client::repositories`).

If repositories are managed in Hiera, feel free to add them to `rpm_repos::default` like
```
rpm_repos::default:
    - 'gfa'
```

Note that repositories for different versions of RHEL can be added and only the fitting ones will be configured on the node.

If the package repositories are managed by a Puppet module, then it is good practice is to define a specific package repository list in [`common.yaml`](https://git.psi.ch/linux-infra/puppet/-/blob/preprod/data/common.yaml) and then to install it only when needed. An example is `profile::telegraf` which only installes the repositories listed in `rpm_repos::influx` when needed.

### Package Repository Definition

An individual package repository is configured in Hiera within the namespace `rpm_repos::repo::*`, like following example:

```
rpm_repos::repo::epel_rhel8:
    name: 'epel'
    descr: "Extra Packages for Enterprise Linux 8"
    baseurl: 'https://repo01.psi.ch/el8/tags/$pli_repo_tag/epel/'
    gpgkey: 'https://repo01.psi.ch/el8/keys/RPM-GPG-KEY-EPEL-8'
    disable: false
    gpgcheck: true
    osversion: 8
    exclude:
        - "slurm*"
```

The legacy namespace `yum_client::repo::*` is currently used for RHEL7 repositories to be backward compatible as some Hiera configuration with higher precedence overwrites certain stuff.

#### Package Repository Name

The reference name used in Hiera (the part after `rpm_repos::repo::` should be globally unique. An unfortunate practice is to use the same name for different package repositories. A current example is the `gfa` repository which has different URLs on different `sysdb` environments.

Note for `name` attribute, that only has to be unique on the machine where they are installed. So if there are two repositories defined to provide the same software for two different OS versions, then it is fine to have the same name there.

#### Package Repository URL

Overriding the URL of a package repository definition on a stricter scope is considered bad practice. The URL defines the actual "identiy" of the package repository definition. It is confusing if it gets different meanings at different places. It is like one passport which will identify different persons in different countries.

If different sources are needed, define and name them appropriately. They point to one given repository and the package repository lists are the place to select what should be applied on a given node.

Also feel free to define all your package repositories in [`common.yaml`](https://git.psi.ch/linux-infra/puppet/-/blob/preprod/data/common.yaml).

#### Select Package Repository by OS Version

Usually a package repository only serves packages for one major OS version. This can be stated by the `osversion` attribute. When a package repository list is installed, only the repositories fitting the version of the OS installed on the node are selected and configured.

If the `osversion` attribute is not set, then it is always installed.

#### Package Repository GPG Verification
GPG verification is optional, so `gpgkey` may not be defined and `gpgcheck` is `false` by default. But ideally the packages are signed and checked for tampering and corruption.

#### Exclude Packages
If certain packages provided by given repository should be ignored on the nodes, then add them to the `exclude` list.



### Using Specific Package Repository Snapshot
Most of the externally sourced package repositories on `repo00.psi.ch` (RHEL7) and `repo01.psi.ch` (RHEL 8) have snapshots which can be used to freeze the available package versions to a given date.

The tags are different per major OS version and are definied in the Hiera hash `rpm_repos::tag`, below you see the default:

```
yum_client::repo_tag: 'prod'

rpm_repos::tag:
    redhat7: "%{lookup('yum_client::repo_tag')}"
    redhat8: 'rhel-8'
```

So for RHEL 7 the default is `prod` and can be overriden on `yum_client::repo_tag` (backwards compatibility) or on the `redhat7` attribute of `rpm_repos::tag`.

To fix to a specific snapshot on RHEL 8, the `redhat8` attribute has to be set on `rpm_repos::tag`, the default is `rhel-8` which points to the latest snapshot.

The available tags your find at
- [https://repo01.psi.ch/el8/tags/](https://repo01.psi.ch/el8/tags/) for RHEL 8 (note the `prod` tag will phase out)
- [https://repo00.psi.ch/el7/tags/](https://repo00.psi.ch/el7/tags/) for RHEL 7

### Package Repositories made Available by the Linux Group

Availabe on all systems are:
- RedHat [BaseOS](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/package_manifest/baseos-repository), [AppStream](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/package_manifest/appstream-repository) and [CodeReady](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/package_manifest/codereadylinuxbuilder-repository) repositories
- [Extra Packages for Enterprise Linux (EPEL) repositories](https://docs.fedoraproject.org/en-US/epel/)
- Puppet 7 repository
- Auristor repository for YFS and AFS related packages
- Google Chrome repository
- pli-misc (not tagged for RHEL7, but on RHEL 8)

Predefined and used when needed are:
- Influx (`influxdb`, `telegraf`, ...)

To be added/defined in [`common.yaml`](https://git.psi.ch/linux-infra/puppet/-/blob/preprod/data/common.yaml)?
- CUDA
- GPFS
- Epics (available for RHEL7)
- Nomachine
- Code (Visual Studio Code from Microsoft)
- HashiCorp (`vault`, `terraform`, `vagrant`, ...)

### pli-misc Repository

A small list of packages managed by the Linux Team.

- make v4.3 from [CentOS](https://rpmfind.net/linux/RPM/centos-stream/9/baseos/x86_64/make-4.3-7.el9.x86_64.html) as v4.2.1 has been reported to to make trouble
- latest [Zoom client](https://zoom.us/download?os=linux)
- latest [Webex client](https://www.webex.com/downloads.html)
- `pli-assets` containing the PSI and the Customer Self Service logo, any hints about the source rpm are welcome
- [mod_gearman v4.0.1](https://mod-gearman.org/download/v4.0.1/rhel8/x86_64/)
- lightdm-gtk v2.0.8-3.pli, a patched lightdm-gtk-greeter ([SRPM](https://git.psi.ch/linux-infra/lightdm-gtk-rpm), [PR](https://github.com/Xubuntu/lightdm-gtk-greeter/pull/121)) which allows to limit the presented keyboard layouts

### Package Repositories made Available by other PSI Groups

- `tivoli`, IBM backup software for Arema, managed by Datacenter and DB Services, AIT
- `nxserver` for NoMachine NX 


