Ansible: Kernel installation 37/26337/7
authorPeter Mikus <pmikus@cisco.com>
Fri, 3 Apr 2020 08:14:50 +0000 (08:14 +0000)
committerPeter Mikus <pmikus@cisco.com>
Thu, 9 Apr 2020 11:00:33 +0000 (11:00 +0000)
Signed-off-by: Peter Mikus <pmikus@cisco.com>
Change-Id: Iee65272169339ed0e5561cf3dee11567335b12be

resources/tools/testbed-setup/ansible/roles/kernel/defaults/main.yaml [new file with mode: 0644]
resources/tools/testbed-setup/ansible/roles/kernel/filter_plugins/main.py [new file with mode: 0644]
resources/tools/testbed-setup/ansible/roles/kernel/tasks/main.yaml [new file with mode: 0644]
resources/tools/testbed-setup/ansible/roles/kernel/tasks/ubuntu_bionic.yaml [new file with mode: 0644]
resources/tools/testbed-setup/ansible/roles/mellanox/defaults/main.yaml
resources/tools/testbed-setup/ansible/roles/mellanox/tasks/main.yaml
resources/tools/testbed-setup/ansible/roles/performance_tuning/files/irqbalance
resources/tools/testbed-setup/ansible/roles/performance_tuning/filter_plugins/main.py [new file with mode: 0644]
resources/tools/testbed-setup/ansible/roles/performance_tuning/tasks/main.yaml
resources/tools/testbed-setup/ansible/sut.yaml
resources/tools/testbed-setup/ansible/tg.yaml

diff --git a/resources/tools/testbed-setup/ansible/roles/kernel/defaults/main.yaml b/resources/tools/testbed-setup/ansible/roles/kernel/defaults/main.yaml
new file mode 100644 (file)
index 0000000..d84a163
--- /dev/null
@@ -0,0 +1,28 @@
+---
+# file: roles/kernel/defaults/main.yaml
+
+# Kernel version to install (Default to any version).
+kernel_version: "{{ kernel_version_by_distro[ansible_distribution | lower] | join(' ') }}"
+
+kernel_version_by_distro:
+  ubuntu:
+    - "4.15.0-72"
+
+kernel_packages: "{{ kernel_packages_by_distro[ansible_distribution | lower] | flatten(levels=1) }}"
+
+kernel_packages_by_distro:
+  ubuntu:
+    - "linux-image"
+    - "linux-headers"
+    - "linux-modules"
+    - "linux-modules-extra"
+    - "linux-tools"
+
+# Packages to remove in relation to kernel upgrade.
+absent_packages: "{{ absent_packages_by_distro[ansible_distribution | lower] | flatten(levels=1) }}"
+
+absent_packages_by_distro:
+  ubuntu:
+    - "amd64-microcode"
+    - "intel-microcode"
+    - "iucode-tool"
diff --git a/resources/tools/testbed-setup/ansible/roles/kernel/filter_plugins/main.py b/resources/tools/testbed-setup/ansible/roles/kernel/filter_plugins/main.py
new file mode 100644 (file)
index 0000000..7d909b9
--- /dev/null
@@ -0,0 +1,143 @@
+
+"""Extra Ansible filters"""
+
+def deb_kernel(packages, kernel_version, current_version):
+    """
+    Return best matching kernel version.
+    Args:
+        packages (dict): apt-cache showpkg output.
+        kernel_version (str): Kernel version to install.
+        current_version (str): Current kernel version.
+    Returns:
+       str: kernel version.
+    """
+    kernels = set()
+
+    # List all available kernel version and associated repository
+    for line in packages['stdout'].splitlines():
+        line = line.strip()
+        if line.startswith('Package: ') and (
+                line.endswith('-common') or  # Debian
+                line.endswith('-generic')):  # Ubuntu
+            kernel = line.split()[1]
+
+            for string in ('linux-headers-', 'common', 'generic'):
+                kernel = kernel.replace(string, '')
+            kernel = kernel.strip('-')
+
+            if kernel:
+                kernels.add(kernel)
+
+    # Sort Kernel versions
+    versions = {}
+    for kernel in kernels:
+        try:
+            version, build = kernel.split('-', 1)
+        except ValueError:
+            version = kernel
+            build = ''
+        versions[kernel] = list(
+            int(ver) for ver in version.split('.')) + [build]
+    kernels = sorted(versions.keys(), key=versions.get, reverse=True)
+
+    # Return more recent kernel package that match version requirement
+    for kernel in kernels:
+        if kernel.startswith(kernel_version):
+            return kernel
+
+    raise RuntimeError(
+        'No kernel matching to "%s". Available kernel versions: %s' % (
+            kernel_version, ', '.join(reversed(kernels))))
+
+
+def _deb_kernel_package(kernel, dist, arch, name):
+    """
+    Return kernel package name.
+    Args:
+        kernel (str): Kernel version.
+        dist (str): Distribution.
+        arch (str): Architecture.
+        name (str): Package name.
+    Returns:
+       str: kernel package.
+    """
+    # Define package suffix
+    if dist == 'Ubuntu':
+        suffix = 'generic'
+    elif name == 'linux-image':
+        suffix = arch.replace('x86_64', 'amd64')
+    else:
+        suffix = 'common'
+
+    return '-'.join((name, kernel, suffix))
+
+
+def deb_kernel_pkg(packages, kernel_version, current_version, dist, arch, name):
+    """
+    Return kernel package to install.
+    Args:
+        packages (dict): apt-cache showpkg output.
+        kernel_version (str): Kernel version to install.
+        current_version (str): Current kernel version.
+        dist (str): Distribution.
+        arch (str): Architecture.
+        name (str): Package name.
+    Returns:
+       str: kernel package to install.
+    """
+    return _deb_kernel_package(
+        deb_kernel(packages, kernel_version, current_version), dist, arch, name)
+
+
+def deb_installed_kernel(installed, packages, kernel_version, current_version):
+    """
+    Return old kernel packages to remove.
+    Args:
+        installed (dict): dpkg -l output.
+        packages (dict): apt-cache showpkg output.
+        kernel_version (str): Kernel version to install.
+        current_version (str): Current kernel version.
+    Returns:
+       list of str: Kernel packages to remove.
+    """
+    # Filter installed package to keep
+    to_keep = deb_kernel(packages, kernel_version, current_version)
+
+    # Return installed package to remove
+    to_remove = []
+    for line in installed['stdout'].splitlines():
+        if ' linux-' not in line:
+            continue
+
+        package = line.split()[1]
+        if ((package.startswith('linux-image-') or
+             package.startswith('linux-headers-')) and not (
+             package.startswith('linux-image-' + to_keep) or
+             package.startswith('linux-headers-' + to_keep))):
+            to_remove.append(package)
+
+    return to_remove
+
+
+def kernel_match(kernel, kernel_spec):
+    """
+    Check if kernel version match.
+    Args:
+        kernel (str): Kernel
+        kernel_spec (str): Kernel to match.
+    Returns:
+        bool: True if Kernel match.
+    """
+    return kernel.startswith(kernel_spec)
+
+
+class FilterModule(object):
+    """Return filter plugin"""
+
+    @staticmethod
+    def filters():
+        """Return filter"""
+        return {'deb_kernel': deb_kernel,
+                'deb_kernel_pkg': deb_kernel_pkg,
+                'deb_installed_kernel': deb_installed_kernel,
+                'kernel_match': kernel_match}
diff --git a/resources/tools/testbed-setup/ansible/roles/kernel/tasks/main.yaml b/resources/tools/testbed-setup/ansible/roles/kernel/tasks/main.yaml
new file mode 100644 (file)
index 0000000..bf8ea9f
--- /dev/null
@@ -0,0 +1,6 @@
+---
+# file: roles/kernel/tasks/main.yaml
+
+- name: Kernel - Install distribution - release
+  include_tasks: '{{ ansible_distribution|lower }}_{{ ansible_distribution_release }}.yaml'
+  tags: install-kernel
diff --git a/resources/tools/testbed-setup/ansible/roles/kernel/tasks/ubuntu_bionic.yaml b/resources/tools/testbed-setup/ansible/roles/kernel/tasks/ubuntu_bionic.yaml
new file mode 100644 (file)
index 0000000..c9c561d
--- /dev/null
@@ -0,0 +1,44 @@
+---
+# file: roles/kernel/tasks/ubuntu_bionic.yaml
+
+- name: Kernel - Get Available Kernel Versions
+  command: "apt-cache showpkg linux-headers-*"
+  changed_when: false
+  register: apt_kernel_list
+  tags: install-kernel
+
+- name: Kernel - Get installed packages with APT
+  command: "dpkg -l"
+  changed_when: false
+  register: apt_packages_list
+  tags: install-kernel
+
+- name: Kernel - Set target APT kernel version
+  set_fact:
+    _kernel: "{{ apt_kernel_list | deb_kernel(
+                 kernel_version, ansible_kernel) }}"
+  tags: install-kernel
+
+- name: Kernel - Ensure Packages Versions
+  apt:
+    name: "{{ apt_kernel_list | deb_kernel_pkg(
+              kernel_version, ansible_kernel, ansible_distribution,
+              ansible_architecture, item) }}"
+  loop: "{{ kernel_packages }}"
+  tags: install-kernel
+
+- name: Kernel - Ensure Any Other Kernel Packages Are Removed
+  apt:
+    name: "{{ apt_packages_list | deb_installed_kernel(
+              apt_kernel_list, kernel_version, ansible_kernel) }}"
+    state: absent
+    purge: true
+  tags: install-kernel
+
+- name: Kernel - Ensure Any Microcode Is Absent
+  apt:
+    name: "{{ absent_packages }}"
+    state: absent
+    purge: true
+  tags: install-kernel
+
index 2b6d3a3..a77bc67 100644 (file)
@@ -9,6 +9,8 @@ packages_base:
 packages_by_distro:
   ubuntu:
     - "build-essential"
+    - "libnl-3-dev"
+    - "libnl-route-3-dev"
 
 packages_by_arch:
   aarch64:
index 030cf59..e914427 100644 (file)
@@ -1,6 +1,14 @@
 ---
 # file: roles/mellanox/tasks/main.yaml
 
+- name: Mellanox Install - Install Distribution - Release - Machine Prerequisites
+  package:
+    name: "{{ packages | flatten(levels=1) }}"
+    state: latest
+    update_cache: true
+  tags:
+    - install-dependencies
+
 - name: Mellanox Install - Check Presence of Mellanox Hardware
   shell: "lspci | grep Mellanox | awk '{print $1}'"
   register: mellanox_pcis
index 98ba483..861be02 100644 (file)
@@ -17,8 +17,7 @@
 #    corresponding bits set to one in this mask will not have any
 #    irq's assigned to them on rebalance
 #
-IRQBALANCE_BANNED_CPUS=ffffffff,ffffffff,ffffffff,fffffffe
-
+IRQBALANCE_BANNED_CPUS="{{ ansible_processor_cores | irqbalance_banned_cpu_mask(ansible_processor_count, ansible_processor_threads_per_core) }}"
 #
 # IRQBALANCE_ARGS
 #    append any args here to the irqbalance daemon as documented in the man page
diff --git a/resources/tools/testbed-setup/ansible/roles/performance_tuning/filter_plugins/main.py b/resources/tools/testbed-setup/ansible/roles/performance_tuning/filter_plugins/main.py
new file mode 100644 (file)
index 0000000..d76f6fe
--- /dev/null
@@ -0,0 +1,29 @@
+"""Extra Ansible filters"""
+
+def irqbalance_banned_cpu_mask(
+        processor_cores, processor_count, processor_threads_per_core):
+    """
+    Return irqbalance CPU mask.
+    Args:
+        processor_cores (int): Physical processor unit.
+        processor_counts (int): Processors per physical unit.
+        processor_threads_per_core (int): Threads per physical unit.
+    Returns:
+       str: irqbalance_banned_cpus.
+    """
+    mask = int("1" * 128, 2)
+
+    for i in range(processor_count * processor_threads_per_core):
+        mask &= ~(1 << i * processor_cores)
+
+    import re
+    return ",".join(re.findall('.{1,8}', str(hex(mask))[2:]))
+
+
+class FilterModule(object):
+    """Return filter plugin"""
+
+    @staticmethod
+    def filters():
+        """Return filter"""
+        return {'irqbalance_banned_cpu_mask': irqbalance_banned_cpu_mask}
index 49a2088..67da43b 100644 (file)
     - copy-cpufrequtils
 
 - name: Performance Tuning - Copy Irqbalance File
-  copy:
+  template:
     src: "files/irqbalance"
     dest: "/etc/default/irqbalance"
     owner: "root"
index c44dfe8..650f100 100644 (file)
@@ -24,6 +24,8 @@
       tags: kernel_vm
     - role: performance_tuning
       tags: performance_tuning
+    - role: kernel
+      tags: kernel
     - role: cleanup
       tags: cleanup
     - role: calibration
index 44e5515..172e8a9 100644 (file)
@@ -24,6 +24,8 @@
       tags: mellanox
     - role: performance_tuning
       tags: performance_tuning
+    - role: kernel
+      tags: kernel
     - role: cleanup
       tags: cleanup
     - role: calibration