Coverage for src/gitlabracadabra/containers/with_blobs.py: 81%

24 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-14 23:10 +0200

1# 

2# Copyright (C) 2019-2025 Mathieu Parent <math.parent@gmail.com> 

3# 

4# This program is free software: you can redistribute it and/or modify 

5# it under the terms of the GNU Lesser General Public License as published by 

6# the Free Software Foundation, either version 3 of the License, or 

7# (at your option) any later version. 

8# 

9# This program is distributed in the hope that it will be useful, 

10# but WITHOUT ANY WARRANTY; without even the implied warranty of 

11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

12# GNU Lesser General Public License for more details. 

13# 

14# You should have received a copy of the GNU Lesser General Public License 

15# along with this program. If not, see <http://www.gnu.org/licenses/>. 

16 

17from __future__ import annotations 

18 

19from typing import TYPE_CHECKING 

20 

21from gitlabracadabra.containers.const import DOCKER_MANIFEST_SCHEMA2_LIST, OCI_IMAGE_INDEX 

22 

23if TYPE_CHECKING: 23 ↛ 24line 23 didn't jump to line 24 because the condition on line 23 was never true

24 from gitlabracadabra.containers.blob import Blob 

25 from gitlabracadabra.containers.manifest import Manifest 

26 

27 

28class WithBlobs: 

29 """Keep in which manifest blobs are. 

30 

31 Method blob_from_digest is in RegistryImporter 

32 """ 

33 

34 def __init__(self) -> None: 

35 """Initialize which keeps trace in which manifests blobs are.""" 

36 # Cache where blobs are present 

37 # Dict key is digest, value is a list of manifest names 

38 self._blobs: dict[str, list[str]] = {} 

39 self._sizes: dict[str, int] = {} 

40 

41 def register_manifest_blobs(self, manifest: Manifest) -> None: 

42 """Add all manifest blobs in the blob mapping. 

43 

44 Args: 

45 manifest: Manifest. 

46 """ 

47 if manifest.mime_type in {DOCKER_MANIFEST_SCHEMA2_LIST, OCI_IMAGE_INDEX}: 47 ↛ 50line 47 didn't jump to line 50 because the condition on line 47 was never true

48 # Note: Should we register all blobs from referenced manifests? 

49 # or only from requested platform? 

50 return 

51 for blob in manifest.blobs(): 

52 self.register_blob(blob) 

53 

54 def register_blob(self, blob: Blob) -> None: 

55 """Add a blob in the blob mapping. 

56 

57 Args: 

58 blob: Blob to register. 

59 """ 

60 self._register_digest(blob.digest, blob.manifest_name, blob.size) 

61 

62 def _register_digest(self, digest: str, manifest_name: str, size: int) -> None: 

63 """Add a blob in the blob mapping by digest and manifest name. 

64 

65 Args: 

66 digest: Digest of Blob to register. 

67 manifest_name: Manifest name of Blob to register. 

68 size: Blob size. 

69 """ 

70 if digest not in self._blobs: 

71 self._blobs[digest] = [] 

72 if manifest_name not in self._blobs[digest]: 

73 self._blobs[digest].append(manifest_name) 

74 if digest not in self._sizes: 

75 self._sizes[digest] = size