From ac45c292e44f3d4d2c5a05fd66eb19036fbabe69 Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Wed, 14 Feb 2024 20:58:03 +0100 Subject: [PATCH] sources/containers-storage: call exists() when fetch()ing Implement fetch_all() and fetch_one() as calls to exists() to make sure we check that the containers are available every time they are needed. --- sources/org.osbuild.containers-storage | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/sources/org.osbuild.containers-storage b/sources/org.osbuild.containers-storage index 9555bd02..358de635 100755 --- a/sources/org.osbuild.containers-storage +++ b/sources/org.osbuild.containers-storage @@ -14,6 +14,7 @@ by osbuild itself. Buildhost commands used: `skopeo`. """ +import concurrent.futures import hashlib import subprocess as sp import sys @@ -57,10 +58,19 @@ class ContainersStorageSource(sources.SourceService): return f"containers-storage:[{driver}@{graphroot}+{runroot}]{imagename}" def fetch_one(self, checksum, desc) -> None: - return + # Instead of fetching anything, just check that it exists. + # + # Note that there's an obvious TOCTOU issue here, but it's unavoidable without copying the storage or a + # container out of it, which is exactly what we want to avoid with this source. + # Unlike all other sources, this source relies on external storage not controlled by osbuild itself. + self.exists(checksum, desc) def fetch_all(self, items) -> None: - return + # prepare each item as a (checksum, desc) tuple (where desc=None) + transformed = map(lambda i: self.transform(i, None), items) + with concurrent.futures.ThreadPoolExecutor(max_workers=self.max_workers) as executor: + for _ in executor.map(self.fetch_one, *zip(*transformed)): + pass def exists(self, checksum, _) -> bool: image_id = checksum.split(":")[1]