CentOS 8: Support DNF

Adds support for configuration of DNF repo mirrors for CentOS and EPEL
repositories, as well as custom repositories.

Adds support for DNF automatic, which is a replacement for yum-cron.

Configuration is backwards compatible, falling back to the equivalent
yum variables when DNF variables have not been overridden.

Change-Id: I8bef5e9c8e1c77c25d6077ff690da8f2cde6a643
Story: 2006574
Task: 38922
This commit is contained in:
Mark Goddard 2020-03-03 15:07:31 +00:00
parent a5f1f2bc49
commit dc32b52f08
23 changed files with 570 additions and 13 deletions

16
ansible/dnf.yml Normal file
View File

@ -0,0 +1,16 @@
---
- name: Ensure DNF repos are configured
hosts: seed-hypervisor:seed:overcloud
tags:
- dnf
tasks:
- block:
- import_role:
name: dnf
- import_role:
name: dnf-automatic
tags:
- dnf-automatic
when:
- ansible_os_family == 'RedHat'
- ansible_distribution_major_version | int >= 8

View File

@ -0,0 +1,52 @@
---
# NOTE(mgoddard): Use Yum configuration for defaults for backwards
# compatibility.
# Yum configuration. Dict mapping Yum config option names to their values.
# dnf_config:
# proxy: http://proxy.example.com
dnf_config: "{{ yum_config }}"
# Whether or not to use a local Yum mirror. Default value is 'false'.
dnf_use_local_mirror: "{{ yum_use_local_mirror }}"
# Mirror FQDN for Yum repos. Default value is 'mirror.centos.org'.
dnf_centos_mirror_host: "{{ yum_centos_mirror_host }}"
# Mirror directory for Yum CentOS repos. Default value is 'centos'.
dnf_centos_mirror_directory: "{{ yum_centos_mirror_directory }}"
# Mirror FQDN for Yum EPEL repos. Default value is
# 'download.fedoraproject.org'.
dnf_epel_mirror_host: "{{ yum_epel_mirror_host }}"
# Mirror directory for Yum EPEL repos. Default value is 'pub/epel'.
dnf_epel_mirror_directory: "{{ yum_epel_mirror_directory }}"
# A dict of custom repositories.
# You can see params on
# http://docs.ansible.com/ansible/latest/modules/yum_repository_module.html.
# For example:
# dnf_custom_repos:
# reponame:
# baseurl: http://repo
# file: myrepo
# gpgkey: http://gpgkey
# gpgcheck: yes
dnf_custom_repos: "{{ yum_custom_repos }}"
# Whether to install the epel-release package. This affects RedHat-based
# systems only. Default value is 'true'.
dnf_install_epel: "{{ yum_install_epel }}"
###############################################################################
# DNF Automatic configuration.
# Whether DNF Automatic is enabled. This can be used to regularly apply
# security updates. Default value is 'false'.
dnf_automatic_enabled: "{{ yum_cron_enabled }}"
# DNF Automatic upgrade type. Default value is 'security'. Note that the
# equivalent yum-cron variable is named slightly differently -
# yum_automatic_update_cmd.
dnf_automatic_upgrade_type: "{{ yum_cron_update_cmd }}"

View File

@ -1,8 +1,36 @@
---
# Yum configuration. Dict mapping Yum config option names to their values.
# yum_config:
# proxy: http://proxy.example.com
yum_config: {}
# Whether or not to use a local Yum mirror.
yum_use_local_mirror: false
# Mirror FQDN for Yum repos.
yum_centos_mirror_host: 'mirror.centos.org'
# Mirror directory for Yum CentOS repos.
yum_centos_mirror_directory: 'centos'
# Mirror FQDN for Yum EPEL repos.
yum_epel_mirror_host: 'download.fedoraproject.org'
# Mirror directory for Yum EPEL repos.
yum_epel_mirror_directory: 'pub/epel'
# A dict of custom repositories.
# You can see params on
# http://docs.ansible.com/ansible/latest/modules/yum_repository_module.html.
# For example:
# yum_custom_repos:
# reponame:
# baseurl: http://repo
# file: myrepo
# gpgkey: http://gpgkey
# gpgcheck: yes
yum_custom_repos: {}
# Whether to install the epel-release package. This affects RedHat-based
# systems only.
yum_install_epel: true

View File

@ -0,0 +1,6 @@
---
# Whether to enable Yum automatic updates.
yum_cron_enabled: false
# Command to use for Yum automatic updates.
yum_cron_update_cmd: 'security'

View File

@ -0,0 +1,6 @@
---
# Whether DNF Automatic is enabled.
dnf_automatic_enabled: false
# DNF Automatic upgrade type.
dnf_automatic_upgrade_type: "security"

View File

@ -0,0 +1,27 @@
---
- block:
- name: Install dnf-automatic
dnf:
name: dnf-automatic
state: present
- name: Apply configuration for DNF automatic
ini_file:
path: /etc/dnf/automatic.conf
section: commands
option: "{{ item.option }}"
value: "{{ item.value }}"
loop:
- option: apply_updates
value: yes
- option: upgrade_type
value: "{{ dnf_automatic_upgrade_type }}"
- name: Enable dnf-automatic.timer
service:
name: dnf-automatic.timer
state: "{{ 'started' if dnf_automatic_enabled | bool else 'stopped' }}"
enabled: "{{ dnf_automatic_enabled | bool }}"
when: dnf_automatic_enabled | bool
become: true

View File

@ -0,0 +1,35 @@
---
# DNF configuration. Dict mapping DNF config option names to their values.
# dnf_config:
# proxy: http://proxy.example.com
dnf_config: {}
# Whether or not to use a local DNF mirror.
dnf_use_local_mirror: false
# Mirror FQDN for DNF repos.
dnf_centos_mirror_host: 'mirror.centos.org'
# Mirror directory for DNF CentOS repos.
dnf_centos_mirror_directory: 'centos'
# Mirror FQDN for DNF EPEL repos.
dnf_epel_mirror_host: 'download.fedoraproject.org'
# Mirror directory for DNF EPEL repos.
dnf_epel_mirror_directory: 'pub/epel'
# A dict of custom repositories.
# You can see params on
# http://docs.ansible.com/ansible/latest/modules/yum_repository_module.html.
# For example:
# dnf_custom_repos:
# reponame:
# baseurl: http://repo
# file: myrepo
# gpgkey: http://gpgkey
# gpgcheck: yes
dnf_custom_repos: {}
# Whether to install the epel-release package.
dnf_install_epel: true

View File

@ -0,0 +1,27 @@
---
- name: Install custom repositories
yum_repository:
name: "{{ item.key }}"
description: "{% if 'description' in item.value %}{{ item.value.description }}{% else %}{{ item.key }} repository{% endif %}"
baseurl: "{{ item.value.baseurl }}"
file: "{{ item.value.file | default(omit)}}"
gpgkey: "{{ item.value.gpgkey | default(omit)}}"
gpgcheck: "{{ item.value.gpgcheck | default(omit)}}"
cost: "{{ item.value.cost | default(omit)}}"
enabled: "{{ item.value.enabled | default(omit)}}"
gpgcakey: "{{ item.value.gpgcakey | default(omit)}}"
metadata_expire: "{{ item.value.metadata_expire | default(omit)}}"
mirrorlist: "{{ item.value.mirrorlist | default(omit)}}"
mirrorlist_expire: "{{ item.value.mirrorlist_expire | default(omit)}}"
priority: "{{ item.value.priority | default(omit)}}"
proxy: "{{ item.value.proxy | default(omit)}}"
proxy_password: "{{ item.value.proxy_password | default(omit)}}"
proxy_username: "{{ item.value.proxy_username | default(omit)}}"
repo_gpgcheck: "{{ item.value.repo_gpgcheck | default(omit)}}"
sslverify: "{{ item.value.sslverify | default(omit)}}"
with_dict: "{{ dnf_custom_repos }}"
register: register_dnf_command
retries: 3
delay: 10
until: register_dnf_command is success
become: true

View File

@ -0,0 +1,46 @@
---
- name: Copy CentOS repo templates
template:
src: "{{ item }}.j2"
dest: /etc/yum.repos.d/{{ item }}
owner: root
group: root
mode: 0664
become: True
loop:
- CentOS-AppStream.repo
- CentOS-Base.repo
- CentOS-Extras.repo
- name: Update cache
dnf:
name: []
update_cache: yes
become: True
# NOTE(mgoddard): Install epel-release to ensure it does not get installed
# later and override our repo file.
- name: Install epel-release
dnf:
name: epel-release
state: installed
become: True
when: dnf_install_epel | bool
- name: Copy EPEL repo templates
template:
src: "{{ item }}.j2"
dest: /etc/yum.repos.d/{{ item }}
owner: root
group: root
mode: 0664
become: True
loop:
- epel.repo
- epel-modular.repo
- name: Update cache
dnf:
name: []
update_cache: yes
become: True

View File

@ -0,0 +1,14 @@
---
- name: Ensure dnf.conf configuration exists
ini_file:
path: /etc/dnf/dnf.conf
section: "main"
option: "{{ item.key }}"
value: "{{ item.value }}"
loop: "{{ query('dict', dnf_config) }}"
become: true
- include_tasks: local-mirror.yml
when: dnf_use_local_mirror | bool
- include_tasks: custom-repo.yml

View File

@ -0,0 +1,19 @@
# CentOS-AppStream.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
[AppStream]
name=CentOS-$releasever - AppStream
baseurl=http://{{ dnf_centos_mirror_host }}/{{ dnf_centos_mirror_directory }}/$releasever/AppStream/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
fastestmirror=0

View File

@ -0,0 +1,19 @@
# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
[BaseOS]
name=CentOS-$releasever - Base
baseurl=http://{{ dnf_centos_mirror_host }}/{{ dnf_centos_mirror_directory }}/$releasever/BaseOS/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
fastestmirror=0

View File

@ -0,0 +1,20 @@
# CentOS-Extras.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
baseurl=http://{{ dnf_centos_mirror_host }}/{{ dnf_centos_mirror_directory }}/$releasever/extras/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
fastestmirror=0

View File

@ -0,0 +1,23 @@
[epel-modular]
name=Extra Packages for Enterprise Linux Modular $releasever - $basearch
baseurl=http://{{ dnf_epel_mirror_host }}/{{ dnf_epel_mirror_directory }}/$releasever/Modular/$basearch
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
fastestmirror=0
[epel-modular-debuginfo]
name=Extra Packages for Enterprise Linux Modular $releasever - $basearch - Debug
baseurl=http://{{ dnf_epel_mirror_host }}/{{ dnf_epel_mirror_directory }}/$releasever/Modular/$basearch/debug
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
gpgcheck=1
fastestmirror=0
[epel-modular-source]
name=Extra Packages for Enterprise Linux Modular $releasever - $basearch - Source
baseurl=http://{{ dnf_epel_mirror_host }}/{{ dnf_epel_mirror_directory }}/$releasever/Modular/SRPMS
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
gpgcheck=1
fastestmirror=0

View File

@ -0,0 +1,23 @@
[epel]
name=Extra Packages for Enterprise Linux $releasever - $basearch
baseurl=http://{{ dnf_epel_mirror_host }}/{{ dnf_epel_mirror_directory }}/$releasever/Everything/$basearch
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
fastestmirror=0
[epel-debuginfo]
name=Extra Packages for Enterprise Linux $releasever - $basearch - Debug
baseurl=http://{{ dnf_epel_mirror_host }}/{{ dnf_epel_mirror_directory }}/$releasever/Everything/$basearch/debug
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
gpgcheck=1
fastestmirror=0
[epel-source]
name=Extra Packages for Enterprise Linux $releasever - $basearch - Source
baseurl=http://{{ dnf_epel_mirror_host }}/{{ dnf_epel_mirror_directory }}/$releasever/Everything/SRPMS
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
gpgcheck=1
fastestmirror=0

View File

@ -3,9 +3,14 @@
hosts: seed-hypervisor:seed:overcloud
tags:
- yum
roles:
- role: yum
- role: yum-cron
tags:
- yum-cron
tasks:
- block:
- import_role:
name: yum
- import_role:
name: yum-cron
tags:
- yum-cron
when:
- ansible_os_family == 'RedHat'
- ansible_distribution_major_version | int == 7

View File

@ -202,8 +202,8 @@ added to the Kayobe configuration.
ssh_key:
- "{{ lookup('file', kayobe_config_path ~ '/ssh-keys/id_rsa_bob.pub') }}"
Package Repositories
====================
Package Repositories (CentOS 7)
===============================
*tags:*
| ``yum``
@ -256,7 +256,8 @@ Custom Yum Repositories
It is also possible to configure a list of custom Yum repositories via the
``yum_custom_repos`` variable. The format is a dict/map, with repository names
mapping to a dict/map of arguments to pass to the Ansible ``yum`` module.
mapping to a dict/map of arguments to pass to the Ansible ``yum_repository``
module.
For example, the following configuration defines a single Yum repository called
``widgets``.
@ -277,6 +278,101 @@ Disabling EPEL
It is possible to disable the EPEL Yum repository by setting
``yum_install_epel`` to ``false``.
Package Repositories (CentOS 8)
===============================
*tags:*
| ``dnf``
Kayobe supports configuration of package repositories via DNF, via variables in
``${KAYOBE_CONFIG_PATH}/dnf.yml``. For backwards compatibility, all variables
in this section starting with ``dnf_`` default to the equivalently named Yum
variable starting with ``yum_``.
Configuration of dnf.conf
-------------------------
Global configuration of DNF is stored in ``/etc/dnf/dnf.conf``, and options can
be set via the ``dnf_config`` variable. Options are added to the ``[main]``
section of the file. For example, to configure DNF to use a proxy server:
.. code-block:: yaml
:caption: ``dnf.yml``
dnf_config:
proxy: https://proxy.example.com
CentOS and EPEL Mirrors
-----------------------
CentOS and EPEL mirrors can be enabled by setting ``dnf_use_local_mirror`` to
``true``. CentOS repository mirrors are configured via the following
variables:
* ``dnf_centos_mirror_host`` (default ``mirror.centos.org``) is the mirror
hostname.
* ``dnf_centos_mirror_directory`` (default ``centos``) is a directory on the
mirror in which repositories may be accessed.
EPEL repository mirrors are configured via the following variables:
* ``dnf_epel_mirror_host`` (default ``download.fedoraproject.org``) is the
mirror hostname.
* ``dnf_epel_mirror_directory`` (default ``pub/epel``) is a directory on the
mirror in which repositories may be accessed.
For example, to configure CentOS and EPEL mirrors at mirror.example.com:
.. code-block:: yaml
:caption: ``dnf.yml``
dnf_use_local_mirror: true
dnf_centos_mirror_host: mirror.example.com
dnf_epel_mirror_host: mirror.example.com
Custom DNF Repositories
-----------------------
It is also possible to configure a list of custom DNF repositories via the
``dnf_custom_repos`` variable. The format is a dict/map, with repository names
mapping to a dict/map of arguments to pass to the Ansible ``yum_repository``
module.
For example, the following configuration defines a single DNF repository called
``widgets``.
.. code-block:: yaml
:caption: ``dnf.yml``
dnf_custom_repos:
widgets:
baseurl: http://example.com/repo
file: widgets
gpgkey: http://example.com/gpgkey
gpgcheck: yes
Disabling EPEL
--------------
It is possible to disable the EPEL DNF repository by setting
``dnf_install_epel`` to ``false``.
DNF Automatic
-------------
DNF Automatic provides a mechanism for applying regular updates of packages.
DNF Automatic is disabled by default, and may be enabled by setting
``dnf_automatic_enabled`` to ``true``.
.. code-block:: yaml
:caption: ``dnf.yml``
dnf_automatic_enabled: true
By default, only security updates are applied. Updates for all packages may be
installed by setting ``dnf_automatic_upgrade_type`` to ``default``. This may
cause the system to be less predictable as packages are updated without
oversight or testing.
SELinux
=======
*tags:*

67
etc/kayobe/dnf.yml Normal file
View File

@ -0,0 +1,67 @@
---
# DNF configuration.
###############################################################################
# DNF repository configuration.
# For backwards compatibility, all variables in this section default to the
# equivalently named variables starting with 'yum_' instead of 'dnf_'.
# The yum variables will be removed in a future release.
# Yum configuration. Dict mapping Yum config option names to their values.
# dnf_config:
# proxy: http://proxy.example.com
#dnf_config:
# Whether or not to use a local Yum mirror. Default value is 'false'.
#dnf_use_local_mirror:
# Mirror FQDN for Yum repos. Default value is 'mirror.centos.org'.
#dnf_centos_mirror_host:
# Mirror directory for Yum CentOS repos. Default value is 'centos'.
#dnf_centos_mirror_directory:
# Mirror FQDN for Yum EPEL repos. Default value is
# 'download.fedoraproject.org'.
#dnf_epel_mirror_host:
# Mirror directory for Yum EPEL repos. Default value is 'pub/epel'.
#dnf_epel_mirror_directory:
# A dict of custom repositories.
# You can see params on
# http://docs.ansible.com/ansible/latest/modules/yum_repository_module.html.
# For example:
# dnf_custom_repos:
# reponame:
# baseurl: http://repo
# file: myrepo
# gpgkey: http://gpgkey
# gpgcheck: yes
#dnf_custom_repos:
# Whether to install the epel-release package. This affects RedHat-based
# systems only. Default value is 'true'.
#dnf_install_epel:
###############################################################################
# DNF Automatic configuration.
# For backwards compatibility, all variables in this section default to the
# equivalently named variables starting with 'yum_cron' instead of
# 'dnf_automatic'. # The yum-cron variables will be removed in a future
# release.
# Whether DNF Automatic is enabled. This can be used to regularly apply
# security updates. Default value is 'false'.
#dnf_automatic_enabled:
# DNF Automatic upgrade type. Default value is 'security'. Note that the
# equivalent yum-cron variable is named slightly differently -
# 'yum_cron_update_cmd'.
#dnf_automatic_upgrade_type:
###############################################################################
# Dummy variable to allow Ansible to accept this file.
workaround_ansible_issue_8743: yes

View File

@ -1,4 +1,6 @@
---
# DEPRECATED: Variables in this file are deprecated and will be removed in a
# future release. Please use dnf.yml instead.
# Whether to enable Yum automatic updates.
#yum_cron_enabled: false

View File

@ -1,4 +1,7 @@
---
# DEPRECATED: Variables in this file are deprecated and will be removed in a
# future release. Please use dnf.yml instead.
# Yum configuration. Dict mapping Yum config option names to their values.
# yum_config:
# proxy: http://proxy.example.com

View File

@ -377,8 +377,8 @@ class SeedHypervisorHostConfigure(KollaAnsibleMixin, KayobeAnsibleMixin,
if parsed_args.wipe_disks:
playbooks += _build_playbook_list("wipe-disks")
playbooks += _build_playbook_list(
"users", "yum", "dev-tools", "network", "sysctl", "ntp", "mdadm",
"lvm", "seed-hypervisor-libvirt-host")
"users", "yum", "dnf", "dev-tools", "network", "sysctl", "ntp",
"mdadm", "lvm", "seed-hypervisor-libvirt-host")
self.run_kayobe_playbooks(parsed_args, playbooks,
limit="seed-hypervisor")
@ -544,7 +544,7 @@ class SeedHostConfigure(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin,
if parsed_args.wipe_disks:
playbooks += _build_playbook_list("wipe-disks")
playbooks += _build_playbook_list(
"users", "yum", "dev-tools", "disable-selinux", "network",
"users", "yum", "dnf", "dev-tools", "disable-selinux", "network",
"sysctl", "ip-routing", "snat", "disable-glean", "ntp", "mdadm",
"lvm", "docker-devicemapper")
self.run_kayobe_playbooks(parsed_args, playbooks, limit="seed")
@ -944,7 +944,7 @@ class OvercloudHostConfigure(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin,
if parsed_args.wipe_disks:
playbooks += _build_playbook_list("wipe-disks")
playbooks += _build_playbook_list(
"users", "yum", "dev-tools", "disable-selinux", "network",
"users", "yum", "dnf", "dev-tools", "disable-selinux", "network",
"sysctl", "disable-glean", "disable-cloud-init", "ntp", "mdadm",
"lvm", "docker-devicemapper")
self.run_kayobe_playbooks(parsed_args, playbooks, limit="overcloud")

View File

@ -322,6 +322,7 @@ class TestCase(unittest.TestCase):
"ansible", "kayobe-target-venv.yml"),
utils.get_data_files_path("ansible", "users.yml"),
utils.get_data_files_path("ansible", "yum.yml"),
utils.get_data_files_path("ansible", "dnf.yml"),
utils.get_data_files_path("ansible", "dev-tools.yml"),
utils.get_data_files_path("ansible", "network.yml"),
utils.get_data_files_path("ansible", "sysctl.yml"),
@ -499,6 +500,7 @@ class TestCase(unittest.TestCase):
"ansible", "kayobe-target-venv.yml"),
utils.get_data_files_path("ansible", "users.yml"),
utils.get_data_files_path("ansible", "yum.yml"),
utils.get_data_files_path("ansible", "dnf.yml"),
utils.get_data_files_path("ansible", "dev-tools.yml"),
utils.get_data_files_path(
"ansible", "disable-selinux.yml"),
@ -1126,6 +1128,7 @@ class TestCase(unittest.TestCase):
"ansible", "kayobe-target-venv.yml"),
utils.get_data_files_path("ansible", "users.yml"),
utils.get_data_files_path("ansible", "yum.yml"),
utils.get_data_files_path("ansible", "dnf.yml"),
utils.get_data_files_path("ansible", "dev-tools.yml"),
utils.get_data_files_path(
"ansible", "disable-selinux.yml"),

View File

@ -0,0 +1,20 @@
---
features:
- |
Adds support for configuration of DNF repositories on CentOS 8. Variables
have been added in a new configuration file, ``dnf.yml``. Backwards
compatibility with the Yum configuration variables is provided.
- |
Adds support for applying regular package updates on CentOS 8 via DNF
Automatic. Variables have been added in a new configuration file,
``dnf.yml``. Backwards compatibility with the Yum-cron configuration
variables is provided.
deprecations:
- |
The Yum configuration variables in ``yum.yml`` are deprecated and will be
removed in a future release. Adapt any configuration overrides to use the
new DNF variables in ``dnf.yml`` instead.
- |
The yum-cron configuration variables in ``yum-cron.yml`` are deprecated and
will be removed in a future release. Adapt any configuration overrides to
use the new DNF automatic variables in ``dnf.yml``.