From 5c661b888e821bcadf5e93fc0b09f86eb9ba901a Mon Sep 17 00:00:00 2001 From: Mark Goddard Date: Tue, 16 Nov 2021 11:27:37 +0000 Subject: [PATCH] Ubuntu: add support for Apt configuration This change adds support for configuration of Apt package manager in /etc/apt/apt.conf.d/. This allows adding arbitrary global configuration options for Apt. Options can be added in different files, allowing for different filename-based priorities. CI tests and documentation are provided. Story: 2009655 Task: 43987 Change-Id: I9d7d18851359e97cd01b4c2287bf79110796b25a --- ansible/group_vars/all/apt | 8 +++++++ ansible/roles/apt/defaults/main.yml | 8 +++++++ ansible/roles/apt/tasks/config.yml | 14 +++++++++++ ansible/roles/apt/tasks/main.yml | 2 ++ ansible/roles/apt/tasks/repos.yml | 1 + doc/source/configuration/reference/hosts.rst | 24 +++++++++++++++++++ etc/kayobe/apt.yml | 8 +++++++ .../overrides.yml.j2 | 4 ++++ .../tests/test_overcloud_host_configure.py | 7 ++++++ .../notes/apt-config-bc72fd0bff919888.yaml | 6 +++++ 10 files changed, 82 insertions(+) create mode 100644 ansible/roles/apt/tasks/config.yml create mode 100644 releasenotes/notes/apt-config-bc72fd0bff919888.yaml diff --git a/ansible/group_vars/all/apt b/ansible/group_vars/all/apt index ded0cdf0a..46d26de18 100644 --- a/ansible/group_vars/all/apt +++ b/ansible/group_vars/all/apt @@ -11,6 +11,14 @@ apt_proxy_http: # Apt proxy URL for HTTPS. Default is {{ apt_proxy_http }}. apt_proxy_https: "{{ apt_proxy_http }}" +# List of Apt configuration options. Each item is a dict with the following +# keys: +# * content: free-form configuration file content +# * filename: name of a file in /etc/apt/apt.conf.d/ in which to write the +# configuration +# Default is an empty list. +apt_config: [] + # List of apt keys. Each item is a dict containing the following keys: # * url: URL of key # * filename: Name of a file in which to store the downloaded key. The diff --git a/ansible/roles/apt/defaults/main.yml b/ansible/roles/apt/defaults/main.yml index 43ce85b36..f818381d7 100644 --- a/ansible/roles/apt/defaults/main.yml +++ b/ansible/roles/apt/defaults/main.yml @@ -11,6 +11,14 @@ apt_proxy_http: # Apt proxy URL for HTTPS. Default is {{ apt_proxy_http }}. apt_proxy_https: "{{ apt_proxy_http }}" +# List of Apt configuration options. Each item is a dict with the following +# keys: +# * content: free-form configuration file content +# * filename: name of a file in /etc/apt/apt.conf.d/ in which to write the +# configuration +# Default is an empty list. +apt_config: [] + # Directory containing GPG keyrings for apt repos. apt_keys_path: "/usr/local/share/keyrings" diff --git a/ansible/roles/apt/tasks/config.yml b/ansible/roles/apt/tasks/config.yml new file mode 100644 index 000000000..046f6e532 --- /dev/null +++ b/ansible/roles/apt/tasks/config.yml @@ -0,0 +1,14 @@ +--- +- name: Ensure Apt is configured + copy: + content: "{{ item.content }}" + dest: "/etc/apt/apt.conf.d/{{ item.filename }}" + owner: root + group: root + mode: 0664 + loop: "{{ apt_config }}" + loop_control: + label: "{{ item.filename }}" + become: true + notify: + - Update apt cache diff --git a/ansible/roles/apt/tasks/main.yml b/ansible/roles/apt/tasks/main.yml index 4bbd0b665..b4cb8f636 100644 --- a/ansible/roles/apt/tasks/main.yml +++ b/ansible/roles/apt/tasks/main.yml @@ -1,6 +1,8 @@ --- - import_tasks: proxy.yml +- import_tasks: config.yml + - import_tasks: keys.yml - import_tasks: repos.yml diff --git a/ansible/roles/apt/tasks/repos.yml b/ansible/roles/apt/tasks/repos.yml index ef401bb5e..8f48f2b92 100644 --- a/ansible/roles/apt/tasks/repos.yml +++ b/ansible/roles/apt/tasks/repos.yml @@ -14,6 +14,7 @@ - name: Disable repositories in /etc/apt/sources.list replace: + # Make a backup, in case we end up with a broken configuration. backup: true path: /etc/apt/sources.list regexp: '^(deb.*)' diff --git a/doc/source/configuration/reference/hosts.rst b/doc/source/configuration/reference/hosts.rst index ed50bfd79..710d0e195 100644 --- a/doc/source/configuration/reference/hosts.rst +++ b/doc/source/configuration/reference/hosts.rst @@ -331,6 +331,30 @@ Apt can be configured to use a proxy via ``apt_proxy_http`` and ``apt_proxy_https`` in ``etc/kayobe/apt.yml``. These should be set to the full URL of the relevant proxy (e.g. ``http://squid.example.com:3128``). +Apt configuration +----------------- + +Arbitrary global configuration options for Apt may be defined via the +``apt_config`` variable in ``etc/kayobe/apt.yml`` since the Yoga release. The +format is a list, with each item mapping to a dict/map with the following +items: + +* ``content``: free-form configuration file content +* ``filename``: name of a file in ``/etc/apt/apt.conf.d/`` in which to write + the configuration + +The default of ``apt_config`` is an empty list. + +For example, the following configuration tells Apt to use 2 attempts when +downloading packages: + +.. code-block:: yaml + + apt_config: + - content: | + Acquire::Retries 1; + filename: 99retries + Apt repositories ---------------- diff --git a/etc/kayobe/apt.yml b/etc/kayobe/apt.yml index c4314a0aa..34bfdd2ef 100644 --- a/etc/kayobe/apt.yml +++ b/etc/kayobe/apt.yml @@ -11,6 +11,14 @@ # Apt proxy URL for HTTPS. Default is {{ apt_proxy_http }}. #apt_proxy_https: +# List of Apt configuration options. Each item is a dict with the following +# keys: +# * content: free-form configuration file content +# * filename: name of a file in /etc/apt/apt.conf.d/ in which to write the +# configuration +# Default is an empty list. +#apt_config: + # List of apt keys. Each item is a dict containing the following keys: # * url: URL of key # * filename: Name of a file in which to store the downloaded key. The diff --git a/playbooks/kayobe-overcloud-host-configure-base/overrides.yml.j2 b/playbooks/kayobe-overcloud-host-configure-base/overrides.yml.j2 index 6591d5e68..34bf2a29f 100644 --- a/playbooks/kayobe-overcloud-host-configure-base/overrides.yml.j2 +++ b/playbooks/kayobe-overcloud-host-configure-base/overrides.yml.j2 @@ -115,6 +115,10 @@ docker_storage_driver: devicemapper timezone: Pacific/Honolulu {% if ansible_os_family == "Debian" %} +apt_config: + - content: | + Acquire::Retries 1; + filename: 99retries apt_keys: - url: https://packages.treasuredata.com/GPG-KEY-td-agent filename: td-agent.asc diff --git a/playbooks/kayobe-overcloud-host-configure-base/tests/test_overcloud_host_configure.py b/playbooks/kayobe-overcloud-host-configure-base/tests/test_overcloud_host_configure.py index a15429be8..f9582e155 100644 --- a/playbooks/kayobe-overcloud-host-configure-base/tests/test_overcloud_host_configure.py +++ b/playbooks/kayobe-overcloud-host-configure-base/tests/test_overcloud_host_configure.py @@ -192,6 +192,13 @@ def test_ntp_clock_synchronized(host): assert "synchronized: yes" in status_output +@pytest.mark.skipif(not _is_apt(), reason="Apt only supported on Ubuntu") +def test_apt_config(host): + apt_config = host.file("/etc/apt/apt.conf.d/99retries") + assert apt_config.exists + assert apt_config.content_string == "Acquire::Retries 1;\n" + + @pytest.mark.skipif(not _is_apt(), reason="Apt only supported on Ubuntu") def test_apt_custom_package_repository_is_available(host): with host.sudo(): diff --git a/releasenotes/notes/apt-config-bc72fd0bff919888.yaml b/releasenotes/notes/apt-config-bc72fd0bff919888.yaml new file mode 100644 index 000000000..a0b0f516c --- /dev/null +++ b/releasenotes/notes/apt-config-bc72fd0bff919888.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Adds support for global configuration options for Apt in files in + ``/etc/apt/apt.conf.d/`` on Ubuntu systems. See `story 2009655 + `__ for details.