-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathocm_util.py
120 lines (100 loc) · 3.61 KB
/
ocm_util.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import collections.abc
import logging
import cnudie.iter
import cnudie.retrieve_async
import dso.model
import ioutil
import oci.client
import oci.model
import ocm
import tarutil
import util
logger = logging.getLogger(__name__)
def iter_local_blob_content(
access: ocm.LocalBlobAccess,
oci_client: oci.client.Client,
image_reference: str=None,
) -> collections.abc.Generator[bytes, None, None]:
if access.globalAccess:
image_reference = access.globalAccess.ref
digest = access.globalAccess.digest
size = access.globalAccess.size
else:
if not image_reference:
raise ValueError('`image_reference` must not be empty to resolve local blob')
digest = access.localReference.lower()
size = access.size
blob = oci_client.blob(
image_reference=image_reference,
digest=digest,
stream=True,
)
if not size:
manifest = oci_client.manifest(
image_reference=image_reference,
accept=oci.model.MimeTypes.prefer_multiarch,
)
if isinstance(manifest, oci.model.OciImageManifestList):
raise ValueError('component-descriptor manifest must not be a manifest list')
for layer in manifest.layers:
if layer.digest == digest:
size = layer.size
break
else:
raise ValueError('`size` must not be empty to stream local blob')
return tarutil.concat_blobs_as_tarstream(
blobs=[
ioutil.BlobDescriptor(
content=blob.iter_content(chunk_size=4096),
size=size,
name=access.referenceName,
)
],
)
async def find_artefact_node(
component_descriptor_lookup: cnudie.retrieve_async.ComponentDescriptorLookupById,
artefact: dso.model.ComponentArtefactId,
absent_ok: bool=False,
) -> cnudie.iter.ResourceNode | cnudie.iter.SourceNode | None:
if not dso.model.is_ocm_artefact(artefact.artefact_kind):
return None
component = (await util.retrieve_component_descriptor(
ocm.ComponentIdentity(
name=artefact.component_name,
version=artefact.component_version,
),
component_descriptor_lookup=component_descriptor_lookup,
)).component
if artefact.artefact_kind is dso.model.ArtefactKind.RESOURCE:
artefacts = component.resources
elif artefact.artefact_kind is dso.model.ArtefactKind.SOURCE:
artefacts = component.sources
else:
raise RuntimeError('this line should never be reached')
for a in artefacts:
if a.name != artefact.artefact.artefact_name:
continue
if a.version != artefact.artefact.artefact_version:
continue
if a.type != artefact.artefact.artefact_type:
continue
if (
dso.model.normalise_artefact_extra_id(a.extraIdentity)
!= artefact.artefact.normalised_artefact_extra_id
):
continue
# found artefact in component's artefacts
if artefact.artefact_kind is dso.model.ArtefactKind.RESOURCE:
return cnudie.iter.ResourceNode(
path=(cnudie.iter.NodePathEntry(component),),
resource=a,
)
elif artefact.artefact_kind is dso.model.ArtefactKind.SOURCE:
return cnudie.iter.SourceNode(
path=(cnudie.iter.NodePathEntry(component),),
source=a,
)
else:
raise RuntimeError('this line should never be reached')
if not absent_ok:
raise ValueError(f'could not find OCM node for {artefact=}')