@@ -15,17 +15,14 @@ def _rhel_kernel_info(packages, kernel_version, current_version):
1515 """
1616 kernels = list ()
1717
18- # If current version match with required version, use this version
1918 if current_version .startswith (kernel_version ):
2019 kernel_version = current_version .rsplit ("." , 1 )[0 ]
2120
22- # List all available kernel version and associated repository
2321 for line in packages ["stdout" ].splitlines ():
2422 if line .startswith ("kernel." ) and not line .startswith ("kernel.src" ):
2523 package = line .strip ().split ()
2624 kernels .append (dict (version = package [1 ], repo = package [2 ]))
2725
28- # Return more recent kernel version that match version requirement
2926 for kernel in reversed (kernels ):
3027 if kernel ["version" ].startswith (kernel_version ):
3128 return kernel
@@ -66,139 +63,106 @@ def rhel_repo(packages, kernel_version, current_version):
6663 return _rhel_kernel_info (packages , kernel_version , current_version )["repo" ]
6764
6865
69- def deb_kernel (packages , kernel_version , current_version ):
66+ def deb_kernel (packages , kernel_version , current_version , variant = None ):
7067 """
7168 Return best matching kernel version.
7269
7370 Args:
7471 packages (dict): apt-cache showpkg output.
7572 kernel_version (str): Kernel version to install.
7673 current_version (str): Current kernel version.
74+ variant (str): Kernel variant to use ("common", ...) If not specified use
75+ current variant.
7776
7877 Returns:
7978 str: kernel version.
8079 """
81- kernels = set ()
82-
83- # If current version match with required version, use this version
84- if current_version .startswith (kernel_version ):
85- kernel_version = current_version
80+ if current_version .startswith (kernel_version ) and not variant :
81+ return current_version
8682
87- # List all available kernel version and associated repository
88- for line in packages ["stdout" ].splitlines ():
89- line = line .strip ()
90- if line .startswith ("Package: " ) and (
91- line .endswith ("-common" ) or line .endswith ("-generic" ) # Debian
92- ): # Ubuntu
93- kernel = line .split ()[1 ]
83+ import re
9484
95- for string in ("linux-headers-" , "common" , "generic" ):
96- kernel = kernel .replace (string , "" )
97- kernel = kernel .strip ("-" )
85+ kernels = set ()
86+ kernels_add = kernels .add
87+ current_version , current_variant = re .match (
88+ r"^([0-9-.]+)(-[a-z0-9]+)?$" , current_version
89+ ).groups ()
90+ variant = "-" + (
91+ variant
92+ if not (variant is None or variant .startswith ("__omit_place_holder__" ))
93+ else (current_variant or "" )
94+ ).lstrip ("-" )
95+ match = re .compile (r"^Package: linux-headers-([a-z0-9-.]+%s)\s*$" % variant ).match
9896
99- if kernel :
100- kernels .add (kernel )
97+ for line in packages ["stdout" ].splitlines ():
98+ line_match = match (line )
99+ if line_match :
100+ kernels_add (line_match .group (1 ))
101101
102- # Sort Kernel versions
103102 versions = {}
104103 for kernel in kernels :
105- try :
106- version , build = kernel .split ("-" , 1 )
107- except ValueError :
108- version = kernel
109- build = ""
104+ version_info = kernel .split ("-" )
105+ version = version_info [0 ]
106+ build = version_info [1 ]
110107 versions [kernel ] = list (int (ver ) for ver in version .split ("." )) + [build ]
111108 kernels = sorted (versions .keys (), key = versions .get , reverse = True )
112109
113- # Return more recent kernel package that match version requirement
114110 for kernel in kernels :
115111 if kernel .startswith (kernel_version ):
116112 return kernel
117113
118114 raise RuntimeError (
119- 'No kernel matching to "%s". Available kernel versions: %s'
120- % (kernel_version , ", " .join (reversed (kernels )))
121- )
122-
123-
124- def _deb_kernel_package (kernel , dist , arch , name ):
125- """
126- Return kernel package name.
127-
128- Args:
129- kernel (str): Kernel version.
130- dist (str): Distribution.
131- arch (str): Architecture.
132- name (str): Package name.
133-
134- Returns:
135- str: kernel package.
136- """
137- # Define package suffix
138- if dist == "Ubuntu" :
139- suffix = "generic"
140- elif name == "linux-image" :
141- suffix = arch .replace ("x86_64" , "amd64" )
142- else :
143- suffix = "common"
144-
145- return "-" .join ((name , kernel , suffix ))
146-
147-
148- def deb_kernel_pkg (packages , kernel_version , current_version , dist , arch , name ):
149- """
150- Return kernel package to install.
151-
152- Args:
153- packages (dict): apt-cache showpkg output.
154- kernel_version (str): Kernel version to install.
155- current_version (str): Current kernel version.
156- dist (str): Distribution.
157- arch (str): Architecture.
158- name (str): Package name.
159-
160- Returns:
161- str: kernel package to install.
162- """
163- return _deb_kernel_package (
164- deb_kernel (packages , kernel_version , current_version ), dist , arch , name
115+ 'No kernel matching to "%s". Current version: %s. Available kernel versions: %s'
116+ % (kernel_version , current_version , ", " .join (reversed (kernels )))
165117 )
166118
167119
168- def deb_installed_kernel (installed , packages , kernel_version , current_version ):
120+ def deb_installed_kernel (installed , kernel_version , arch ):
169121 """
170122 Return old kernel packages to remove.
171123
172124 Args:
173125 installed (dict): dpkg -l output.
174- packages (dict): apt-cache showpkg output.
175126 kernel_version (str): Kernel version to install.
176- current_version (str): Current kernel version .
127+ arch (str): Architecture .
177128
178129 Returns:
179130 list of str: Kernel packages to remove.
180131 """
181- # Filter installed package to keep
182- to_keep = deb_kernel ( packages , kernel_version , current_version )
132+ packages = ( "linux-image-" , "linux-headers-" )
133+ to_keep = tuple ( deb_kernel_package ( name , kernel_version , arch ) for name in packages )
183134
184- # Return installed package to remove
185135 to_remove = []
186136 for line in installed ["stdout" ].splitlines ():
187137 if " linux-" not in line :
188138 continue
189-
190- package = line .split ()[1 ]
191- if (
192- package .startswith ("linux-image-" ) or package .startswith ("linux-headers-" )
193- ) and not (
194- package .startswith ("linux-image-" + to_keep )
195- or package .startswith ("linux-headers-" + to_keep )
139+ package = line .split ()[1 ].strip ()
140+ if any (package .startswith (name ) for name in packages ) and not any (
141+ package .startswith (name ) for name in to_keep
196142 ):
197143 to_remove .append (package )
198-
199144 return to_remove
200145
201146
147+ def deb_kernel_package (name , kernel_version , arch ):
148+ """
149+ Check if kernel version match.
150+
151+ Args:
152+ name (str): package name.
153+ kernel_version (str): Kernel version to install.
154+ arch (str): Architecture.
155+
156+ Returns:
157+ str: Package name.
158+ """
159+ package = "%s-%s" % (name , kernel_version )
160+ if name == "linux-image" :
161+ # Debian "image" packages does not end by the variant like headers
162+ package = package .replace ("-common" , "-" + arch .replace ("x86_64" , "amd64" ))
163+ return package
164+
165+
202166def kernel_match (kernel , kernel_spec ):
203167 """
204168 Check if kernel version match.
@@ -223,7 +187,7 @@ def filters():
223187 "rhel_kernel" : rhel_kernel ,
224188 "rhel_repo" : rhel_repo ,
225189 "deb_kernel" : deb_kernel ,
226- "deb_kernel_pkg" : deb_kernel_pkg ,
227190 "deb_installed_kernel" : deb_installed_kernel ,
191+ "deb_kernel_package" : deb_kernel_package ,
228192 "kernel_match" : kernel_match ,
229193 }
0 commit comments