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

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

17 from __future__ import annotations

18

19 from typing import TYPE_CHECKING

20

21 from gitlabracadabra.containers.const import DOCKER_MANIFEST_SCHEMA2_LIST, OCI_IMAGE_INDEX

22

23 if 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

28 class 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