Ansible git move
[csit.git] / fdio.infra.ansible / roles / kernel / filter_plugins / main.py
1
2 """Extra Ansible filters"""
3
4 def deb_kernel(packages, kernel_version, current_version):
5     """
6     Return best matching kernel version.
7     Args:
8         packages (dict): apt-cache showpkg output.
9         kernel_version (str): Kernel version to install.
10         current_version (str): Current kernel version.
11     Returns:
12        str: kernel version.
13     """
14     kernels = set()
15
16     # List all available kernel version and associated repository
17     for line in packages['stdout'].splitlines():
18         line = line.strip()
19         if line.startswith('Package: ') and (
20                 line.endswith('-common') or  # Debian
21                 line.endswith('-generic')):  # Ubuntu
22             kernel = line.split()[1]
23
24             for string in ('linux-headers-', 'common', 'generic'):
25                 kernel = kernel.replace(string, '')
26             kernel = kernel.strip('-')
27
28             if kernel:
29                 kernels.add(kernel)
30
31     # Sort Kernel versions
32     versions = {}
33     for kernel in kernels:
34         try:
35             version, build = kernel.split('-', 1)
36         except ValueError:
37             version = kernel
38             build = ''
39         versions[kernel] = list(
40             int(ver) for ver in version.split('.')) + [build]
41     kernels = sorted(versions.keys(), key=versions.get, reverse=True)
42
43     # Return more recent kernel package that match version requirement
44     for kernel in kernels:
45         if kernel.startswith(kernel_version):
46             return kernel
47
48     raise RuntimeError(
49         'No kernel matching to "%s". Available kernel versions: %s' % (
50             kernel_version, ', '.join(reversed(kernels))))
51
52
53 def _deb_kernel_package(kernel, dist, arch, name):
54     """
55     Return kernel package name.
56     Args:
57         kernel (str): Kernel version.
58         dist (str): Distribution.
59         arch (str): Architecture.
60         name (str): Package name.
61     Returns:
62        str: kernel package.
63     """
64     # Define package suffix
65     if dist == 'Ubuntu':
66         suffix = 'generic'
67     elif name == 'linux-image':
68         suffix = arch.replace('x86_64', 'amd64')
69     else:
70         suffix = 'common'
71
72     return '-'.join((name, kernel, suffix))
73
74
75 def deb_kernel_pkg(packages, kernel_version, current_version, dist, arch, name):
76     """
77     Return kernel package to install.
78     Args:
79         packages (dict): apt-cache showpkg output.
80         kernel_version (str): Kernel version to install.
81         current_version (str): Current kernel version.
82         dist (str): Distribution.
83         arch (str): Architecture.
84         name (str): Package name.
85     Returns:
86        str: kernel package to install.
87     """
88     return _deb_kernel_package(
89         deb_kernel(packages, kernel_version, current_version), dist, arch, name)
90
91
92 def deb_installed_kernel(installed, packages, kernel_version, current_version):
93     """
94     Return old kernel packages to remove.
95     Args:
96         installed (dict): dpkg -l output.
97         packages (dict): apt-cache showpkg output.
98         kernel_version (str): Kernel version to install.
99         current_version (str): Current kernel version.
100     Returns:
101        list of str: Kernel packages to remove.
102     """
103     # Filter installed package to keep
104     to_keep = deb_kernel(packages, kernel_version, current_version)
105
106     # Return installed package to remove
107     to_remove = []
108     for line in installed['stdout'].splitlines():
109         if ' linux-' not in line:
110             continue
111
112         package = line.split()[1]
113         if ((package.startswith('linux-image-') or
114              package.startswith('linux-headers-')) and not (
115              package.startswith('linux-image-' + to_keep) or
116              package.startswith('linux-headers-' + to_keep))):
117             to_remove.append(package)
118
119     return to_remove
120
121
122 def kernel_match(kernel, kernel_spec):
123     """
124     Check if kernel version match.
125     Args:
126         kernel (str): Kernel
127         kernel_spec (str): Kernel to match.
128     Returns:
129         bool: True if Kernel match.
130     """
131     return kernel.startswith(kernel_spec)
132
133
134 class FilterModule(object):
135     """Return filter plugin"""
136
137     @staticmethod
138     def filters():
139         """Return filter"""
140         return {'deb_kernel': deb_kernel,
141                 'deb_kernel_pkg': deb_kernel_pkg,
142                 'deb_installed_kernel': deb_installed_kernel,
143                 'kernel_match': kernel_match}