|
6 | 6 | import argparse |
7 | 7 | import fnmatch |
8 | 8 | import io |
| 9 | +import os |
9 | 10 | import shlex |
10 | 11 | import shutil |
11 | 12 | import sqlite3 |
|
19 | 20 | from urllib.error import HTTPError |
20 | 21 |
|
21 | 22 | from drgn_tools.util import download_file |
| 23 | +from drgn_tools.util import head_file |
22 | 24 | from testing.util import BASE_DIR |
23 | 25 |
|
24 | 26 |
|
@@ -92,6 +94,18 @@ def download_file_cached( |
92 | 94 | return cached_file |
93 | 95 |
|
94 | 96 |
|
| 97 | +def check_file_cached( |
| 98 | + url: str, cache: Optional[Path], cache_key: Optional[str] |
| 99 | +) -> bool: |
| 100 | + if not cache: |
| 101 | + cache = YUM_CACHE_DIR |
| 102 | + if cache_key: |
| 103 | + cache = cache / cache_key |
| 104 | + cached_file = cache / url.split("/")[-1] |
| 105 | + rv = cached_file.is_file() or head_file(url) |
| 106 | + return rv |
| 107 | + |
| 108 | + |
95 | 109 | class TestKernel: |
96 | 110 | ol_ver: int |
97 | 111 | uek_ver: Union[int, str] |
@@ -192,20 +206,58 @@ def _getlatest(self) -> None: |
192 | 206 | def key(t): |
193 | 207 | return tuple(map(int, t[0].split(".") + t[1].split(".")[:-1])) |
194 | 208 |
|
195 | | - rows.sort(key=key) |
196 | | - ver, rel, href = rows[-1] |
197 | | - |
198 | | - # Now set the final values as output |
199 | | - self._rpm_urls = [] |
200 | | - rpm_url = yumbase + href |
201 | | - for final_pkg in self.pkgs: |
202 | | - self._rpm_urls.append(rpm_url.replace(self.pkgbase, final_pkg)) |
203 | | - self._release = f"{ver}-{rel}.{self.arch}" |
204 | | - self._dbinfo_url = DEBUGINFO_URL.format( |
205 | | - ol_ver=self.ol_ver, |
206 | | - release=self._release, |
207 | | - pkgbase=self.pkgbase, |
| 209 | + allow_missing = bool( |
| 210 | + int(os.environ.get("DRGN_TOOLS_ALLOW_MISSING_LATEST", 0)) |
208 | 211 | ) |
| 212 | + rows.sort(key=key, reverse=True) |
| 213 | + versions_tried = [] |
| 214 | + for ver, rel, href in rows[:2]: |
| 215 | + # Check whether all RPMs are either cached or available via HTTP |
| 216 | + rpm_urls: List[str] = [] |
| 217 | + rpm_url = yumbase + href |
| 218 | + missing_urls = [] |
| 219 | + release = f"{ver}-{rel}.{self.arch}" |
| 220 | + for final_pkg in self.pkgs: |
| 221 | + url = rpm_url.replace(self.pkgbase, final_pkg) |
| 222 | + if not check_file_cached( |
| 223 | + url, self.cache_dir, self._cache_key("rpm") |
| 224 | + ): |
| 225 | + missing_urls.append(url) |
| 226 | + rpm_urls.append(url) |
| 227 | + dbinfo_url = DEBUGINFO_URL.format( |
| 228 | + ol_ver=self.ol_ver, |
| 229 | + release=release, |
| 230 | + pkgbase=self.pkgbase, |
| 231 | + ) |
| 232 | + if not check_file_cached( |
| 233 | + dbinfo_url, self.cache_dir, self._cache_key("rpm") |
| 234 | + ): |
| 235 | + missing_urls.append(dbinfo_url) |
| 236 | + |
| 237 | + # If some RPMs are available, we have two options: |
| 238 | + # 1. Try the next older RPM (if the environment variable is set) |
| 239 | + # 2. Ignore the error and let the HTTP 404 handling below report the |
| 240 | + # issue. |
| 241 | + if missing_urls and allow_missing: |
| 242 | + print( |
| 243 | + f"warning: {release} had missing RPMs:\n" |
| 244 | + + "\n".join(missing_urls) |
| 245 | + + "\nTrying an older release..." |
| 246 | + ) |
| 247 | + versions_tried.append(release) |
| 248 | + continue |
| 249 | + |
| 250 | + self._rpm_urls = rpm_urls |
| 251 | + self._dbinfo_url = dbinfo_url |
| 252 | + self._release = release |
| 253 | + return |
| 254 | + else: |
| 255 | + # This is the case where we checked both candidates, but neither had |
| 256 | + # all files available. Report an error. |
| 257 | + sys.exit( |
| 258 | + "error: no release had all files available. Tried: " |
| 259 | + + ", ".join(versions_tried) |
| 260 | + ) |
209 | 261 |
|
210 | 262 | def _get_rpms(self) -> None: |
211 | 263 | if not self._release: |
|
0 commit comments