From e4345c217ee0ac8e4ec790e45c98f0f603052a2c Mon Sep 17 00:00:00 2001
From: Mohammed Naser <mnaser@vexxhost.com>
Date: Sat, 4 Apr 2020 15:35:37 -0400
Subject: [PATCH] ensure-package-repositories: Add role

This role allows users to supply a common variable and it will
contain all the logic to configure the correct repository based
on their operating system.

Co-Authored-By: Andreas Jaeger <aj@suse.com>
Change-Id: I4a3ab5f099c2e4671b78c751d8f0e8ccf2304afa
---
 doc/source/system-roles.rst                   |  1 +
 roles/ensure-package-repositories/README.rst  | 80 +++++++++++++++++++
 .../defaults/main.yaml                        |  3 +
 .../tasks/Debian.yaml                         | 25 ++++++
 .../tasks/RedHat.yaml                         | 36 +++++++++
 .../tasks/Suse.yaml                           | 35 ++++++++
 .../tasks/main.yaml                           |  7 ++
 7 files changed, 187 insertions(+)
 create mode 100644 roles/ensure-package-repositories/README.rst
 create mode 100644 roles/ensure-package-repositories/defaults/main.yaml
 create mode 100644 roles/ensure-package-repositories/tasks/Debian.yaml
 create mode 100644 roles/ensure-package-repositories/tasks/RedHat.yaml
 create mode 100644 roles/ensure-package-repositories/tasks/Suse.yaml
 create mode 100644 roles/ensure-package-repositories/tasks/main.yaml

diff --git a/doc/source/system-roles.rst b/doc/source/system-roles.rst
index 828b30dc9..2c6c0ceaf 100644
--- a/doc/source/system-roles.rst
+++ b/doc/source/system-roles.rst
@@ -1,6 +1,7 @@
 System Roles
 ============
 
+.. zuul:autorole:: ensure-package-repositories
 .. zuul:autorole:: ensure-phoronix-test-suite
 .. zuul:autorole:: phoronix-test-suite
 .. zuul:autorole:: phoronix-combine-results
diff --git a/roles/ensure-package-repositories/README.rst b/roles/ensure-package-repositories/README.rst
new file mode 100644
index 000000000..60439357f
--- /dev/null
+++ b/roles/ensure-package-repositories/README.rst
@@ -0,0 +1,80 @@
+Ensure that package manager repositories are installed.  This role works
+with the pattern of including variables for different operating systems.
+
+.. note:: This role currently only supports RPM and DEB based distributions.
+
+Example use for Debian and Ubuntu:
+
+.. code-block:: yaml
+
+   - name: Add all repositories
+     include_role:
+       name: ensure-package-repositories
+     vars:
+       repositories_keys:
+         - url: https://deb.nodesource.com/gpgkey/nodesource.gpg.key
+       repositories_list:
+         - repo: deb-src https://deb.nodesource.com/node_6.x {{ ansible_distribution_release }} main
+         - repo: deb https://deb.nodesource.com/node_6.x {{ ansible_distribution_release }} main
+
+Example use for Fedora and Red Hat:
+
+.. code-block:: yaml
+
+   _docker_keys:
+     - data: |
+         -----BEGIN PGP PUBLIC KEY BLOCK-----
+         ...
+         -----END PGP PUBLIC KEY BLOCK-----
+
+   _docker_repos:
+     - name: docker-ce-stable
+       description: Docker CE Stable - $basearch
+       baseurl: "{{ docker_mirror_base_url }}/$releasever/$basearch/stable"
+       gpgcheck: yes
+
+   - name: Add all repositories
+         include_role:
+           name: ensure-package-repositories
+         vars:
+           repositories_keys: "{{ _docker_keys }}"
+           repositories_list: "{{ _docker_repos }}"
+
+Example use for openSUSE and SUSE Linux:
+
+.. code-block:: yaml
+
+   _docker_keys:
+     - data: |
+         -----BEGIN PGP PUBLIC KEY BLOCK-----
+         ...
+         -----END PGP PUBLIC KEY BLOCK-----
+
+   _docker_repos:
+     - name: docker-ce-stable
+       description: Docker CE Stable - $basearch
+       uri: "{{ docker_mirror_base_url }}/$releasever/$basearch/stable.repo"
+
+   - name: Add all repositories
+         include_role:
+           name: ensure-package-repositories
+         vars:
+           repositories_keys: "{{ _docker_keys }}"
+           repositories_list: "{{ _docker_repos }}"
+
+**Role Variables**
+
+.. zuul:rolevar:: repositories_keys
+   :default: []
+
+   List of dictionaries containing keys to install for the package manager,
+   every dictionary may contain either the key ``url`` which will be
+   downloaded and installed, or ``data`` which contains the key to be
+   installed.
+
+.. zuul:rolevar:: repository_list
+   :default: []
+
+   List of dictionaries containing repository configuration, the format
+   of each dictionary is mapped to the same as the module parameters of
+   the package manager for Ansible (such as ``yum_repository``, etc.)
diff --git a/roles/ensure-package-repositories/defaults/main.yaml b/roles/ensure-package-repositories/defaults/main.yaml
new file mode 100644
index 000000000..2a98a497b
--- /dev/null
+++ b/roles/ensure-package-repositories/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+repositories_keys: []
+repositories_list: []
diff --git a/roles/ensure-package-repositories/tasks/Debian.yaml b/roles/ensure-package-repositories/tasks/Debian.yaml
new file mode 100644
index 000000000..f97486498
--- /dev/null
+++ b/roles/ensure-package-repositories/tasks/Debian.yaml
@@ -0,0 +1,25 @@
+- name: Add apt keys
+  become: true
+  apt_key:
+    url: "{{ zj_item['url'] | default(omit) }}"
+    data: "{{ zj_item['data'] | default(omit) }}"
+  loop: "{{ repositories_keys }}"
+  loop_control:
+    loop_var: zj_item
+
+- name: Add apt repositories
+  become: true
+  apt_repository:
+    repo: "{{ zj_item['repo'] | default(omit) }}"
+    state: present
+    update_cache: no
+  loop: "{{ repositories_list }}"
+  loop_control:
+    loop_var: zj_item
+  register: _add_apt_repos
+
+- name: Update APT cache
+  become: true
+  apt:
+    update_cache: yes
+  when: _add_apt_repos is changed
diff --git a/roles/ensure-package-repositories/tasks/RedHat.yaml b/roles/ensure-package-repositories/tasks/RedHat.yaml
new file mode 100644
index 000000000..659601ef3
--- /dev/null
+++ b/roles/ensure-package-repositories/tasks/RedHat.yaml
@@ -0,0 +1,36 @@
+- name: Create GPG key temp directory
+  tempfile:
+    prefix: "GPG_keys"
+    state: directory
+  register: gpg_key_tempdir
+
+- name: Upload GPG keys
+  copy:
+    content: "{{ zj_item['data'] }}"
+    dest: "{{ gpg_key_tempdir.path }}/key-{{ zj_idx }}.gpg"
+  loop: "{{ repositories_keys }}"
+  loop_control:
+    loop_var: zj_item
+    index_var: zj_idx
+  when: "'data' in zj_item"
+
+- name: Import GPG keys
+  become: true
+  rpm_key:
+    key: "{{ ('url' in zj_item) | ternary(zj_item['url'], ('data' in zj_item) | ternary(gpg_key_tempdir.path + '/key-' ~ zj_idx ~ '.gpg', zj_item['key'])) }}"
+    state: present
+  loop: "{{ repositories_keys }}"
+  loop_control:
+    loop_var: zj_item
+    index_var: zj_idx
+
+- name: Add repositories
+  yum_repository:
+    name: "{{ zj_item['name'] }}"
+    description: "{{ zj_item['description'] | default(omit) }}"
+    baseurl: "{{ zj_item['baseurl'] | default(omit) }}"
+    gpgcheck: "{{ zj_item['gpgcheck'] | default(omit) }}"
+    gpgkey: "{{ zj_item['gpgkey'] | default(omit) }}"
+  loop: "{{ repositories_list }}"
+  loop_control:
+    loop_var: zj_item
diff --git a/roles/ensure-package-repositories/tasks/Suse.yaml b/roles/ensure-package-repositories/tasks/Suse.yaml
new file mode 100644
index 000000000..8f8abd21f
--- /dev/null
+++ b/roles/ensure-package-repositories/tasks/Suse.yaml
@@ -0,0 +1,35 @@
+- name: Create GPG key temp directory
+  tempfile:
+    prefix: "GPG_keys"
+    state: directory
+  register: gpg_key_tempdir
+
+- name: Upload GPG keys
+  copy:
+    content: "{{ zj_item['data'] }}"
+    dest: "{{ gpg_key_tempdir.path }}/key-{{ zj_idx }}.gpg"
+  loop: "{{ repositories_keys }}"
+  loop_control:
+    loop_var: zj_item
+    index_var: zj_idx
+  when: "'data' in zj_item"
+
+- name: Import GPG keys
+  become: true
+  rpm_key:
+    key: "{{ ('url' in zj_item) | ternary(zj_item['url'], ('data' in zj_item) | ternary(gpg_key_tempdir.path + '/key-' ~ zj_idx ~ '.gpg', zj_item['key'])) }}"
+    state: present
+  loop: "{{ repositories_keys }}"
+  loop_control:
+    loop_var: zj_item
+    index_var: zj_idx
+
+- name: Add repositories
+  zypper_repository:
+    name: "{{ zj_item['name'] }}"
+    description: "{{ zj_item['description'] | default(omit) }}"
+    repo: "{{ zj_item['repo'] | default(omit) }}"
+    disable_gpg_check: "{{ zj_item['disable_gpg_check'] | default(omit) }}"
+  loop: "{{ repositories_list }}"
+  loop_control:
+    loop_var: zj_item
diff --git a/roles/ensure-package-repositories/tasks/main.yaml b/roles/ensure-package-repositories/tasks/main.yaml
new file mode 100644
index 000000000..93f093c72
--- /dev/null
+++ b/roles/ensure-package-repositories/tasks/main.yaml
@@ -0,0 +1,7 @@
+- name: Install repositories
+  include: "{{ zj_item }}"
+  with_first_found:
+    - "{{ ansible_distribution }}.yaml"
+    - "{{ ansible_os_family }}.yaml"
+  loop_control:
+    loop_var: zj_item