Skip to content

Commit e8201bd

Browse files
authored
Merge branch 'main' into 3054-move-github-workflows-py-to-python-gardenlinux-lib
2 parents b22f349 + 02879bd commit e8201bd

10 files changed

Lines changed: 694 additions & 261 deletions

File tree

‎poetry.lock‎

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/gardenlinux/oci/__init__.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
"""
66

77
from .container import Container
8+
from .image_manifest import ImageManifest
89
from .index import Index
910
from .layer import Layer
1011
from .manifest import Manifest
1112

12-
__all__ = ["Container", "Index", "Layer", "Manifest"]
13+
__all__ = ["Container", "ImageManifest", "Index", "Layer", "Manifest"]

‎src/gardenlinux/oci/__main__.py‎

Lines changed: 84 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,28 @@ def cli():
3131
help="Container Name",
3232
)
3333
@click.option(
34-
"--version",
35-
required=True,
36-
type=click.Path(),
37-
help="Version of image",
34+
"--cname", required=True, type=click.Path(), help="Canonical Name of Image"
3835
)
3936
@click.option(
40-
"--commit",
37+
"--arch",
4138
required=False,
4239
type=click.Path(),
4340
default=None,
44-
help="Commit of image",
41+
help="Target Image CPU Architecture",
4542
)
4643
@click.option(
47-
"--arch",
48-
required=True,
44+
"--version",
45+
required=False,
4946
type=click.Path(),
50-
help="Target Image CPU Architecture",
47+
default=None,
48+
help="Version of image",
5149
)
5250
@click.option(
53-
"--cname", required=True, type=click.Path(), help="Canonical Name of Image"
51+
"--commit",
52+
required=False,
53+
type=click.Path(),
54+
default=None,
55+
help="Commit of image",
5456
)
5557
@click.option("--dir", "directory", required=True, help="path to the build artifacts")
5658
@click.option(
@@ -76,10 +78,10 @@ def cli():
7678
)
7779
def push_manifest(
7880
container,
81+
cname,
82+
arch,
7983
version,
8084
commit,
81-
arch,
82-
cname,
8385
directory,
8486
cosign_file,
8587
manifest_file,
@@ -107,6 +109,76 @@ def push_manifest(
107109
print(manifest.digest, file=open(cosign_file, "w"))
108110

109111

112+
@cli.command()
113+
@click.option(
114+
"--container",
115+
required=True,
116+
type=click.Path(),
117+
help="Container Name",
118+
)
119+
@click.option(
120+
"--cname",
121+
required=False,
122+
type=click.Path(),
123+
default=None,
124+
help="Canonical Name of Image",
125+
)
126+
@click.option(
127+
"--arch",
128+
required=False,
129+
type=click.Path(),
130+
default=None,
131+
help="Target Image CPU Architecture",
132+
)
133+
@click.option(
134+
"--version",
135+
required=False,
136+
type=click.Path(),
137+
default=None,
138+
help="Version of image",
139+
)
140+
@click.option(
141+
"--commit",
142+
required=False,
143+
type=click.Path(),
144+
default=None,
145+
help="Commit of image",
146+
)
147+
@click.option(
148+
"--insecure",
149+
default=False,
150+
help="Use HTTP to communicate with the registry",
151+
)
152+
@click.option(
153+
"--tag",
154+
required=True,
155+
multiple=True,
156+
help="Tag to push the manifest with",
157+
)
158+
def push_manifest_tags(
159+
container,
160+
cname,
161+
arch,
162+
version,
163+
commit,
164+
insecure,
165+
tag,
166+
):
167+
"""
168+
Push artifacts and the manifest from a directory to a registry.
169+
170+
:since: 0.10.0
171+
"""
172+
173+
container = Container(
174+
f"{container}:{version}",
175+
insecure=insecure,
176+
)
177+
178+
manifest = container.read_or_generate_manifest(cname, arch, version, commit)
179+
container.push_manifest_for_tags(manifest, tag)
180+
181+
110182
@cli.command()
111183
@click.option(
112184
"--container",

‎src/gardenlinux/oci/container.py‎

Lines changed: 81 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
from .index import Index
3030
from .layer import Layer
31+
from .image_manifest import ImageManifest
3132
from .manifest import Manifest
3233
from .schemas import index as IndexSchema
3334

@@ -83,11 +84,21 @@ def __init__(
8384
self._container_version = container_data[1]
8485

8586
container_url_data = urlsplit(self._container_url)
87+
self._token = None
88+
89+
if token is None:
90+
token = getenv("GL_CLI_REGISTRY_TOKEN")
91+
92+
if token is not None:
93+
auth_backend = "token"
94+
self._token = b64encode(token.encode("utf-8")).decode("utf-8")
95+
else:
96+
auth_backend = "basic"
8697

8798
Registry.__init__(
8899
self,
89100
hostname=container_url_data.netloc,
90-
auth_backend="token",
101+
auth_backend=auth_backend,
91102
insecure=insecure,
92103
)
93104

@@ -97,11 +108,7 @@ def __init__(
97108
self._container_name = container_url_data.path[1:]
98109
self._logger = logger
99110

100-
if token is None:
101-
token = getenv("GL_CLI_REGISTRY_TOKEN")
102-
103-
if token is not None:
104-
self._token = b64encode(token.encode("utf-8")).decode("utf-8")
111+
if self._token is not None:
105112
self.auth.set_token_auth(self._token)
106113
else:
107114
# Authentication credentials from environment
@@ -117,17 +124,7 @@ def __init__(
117124
except Exception as login_error:
118125
self._logger.error(f"Login error: {str(login_error)}")
119126

120-
def generate_index(self):
121-
"""
122-
Generates an OCI image index
123-
124-
:return: (object) OCI image index
125-
:since: 0.7.0
126-
"""
127-
128-
return Index()
129-
130-
def generate_manifest(
127+
def generate_image_manifest(
131128
self,
132129
cname: str,
133130
architecture: Optional[str] = None,
@@ -145,7 +142,7 @@ def generate_manifest(
145142
:param feature_set: The expanded list of the included features of this manifest
146143
147144
:return: (object) OCI image manifest
148-
:since: 0.7.0
145+
:since: 0.10.0
149146
"""
150147

151148
cname_object = CName(cname, architecture, version)
@@ -162,15 +159,13 @@ def generate_manifest(
162159
if commit is None:
163160
commit = ""
164161

165-
manifest = Manifest()
162+
manifest = ImageManifest()
166163

167-
manifest["annotations"] = {}
168-
manifest["annotations"]["version"] = version
169-
manifest["annotations"]["cname"] = cname
170-
manifest["annotations"]["architecture"] = architecture
171-
manifest["annotations"]["feature_set"] = feature_set
172-
manifest["annotations"]["flavor"] = f"{cname_object.flavor}-{architecture}"
173-
manifest["annotations"]["commit"] = commit
164+
manifest.version = version
165+
manifest.cname = cname
166+
manifest.arch = architecture
167+
manifest.feature_set = feature_set
168+
manifest.commit = commit
174169

175170
description = (
176171
f"Image: {cname} "
@@ -189,6 +184,43 @@ def generate_manifest(
189184

190185
return manifest
191186

187+
def generate_index(self):
188+
"""
189+
Generates an OCI image index
190+
191+
:return: (object) OCI image index
192+
:since: 0.7.0
193+
"""
194+
195+
return Index()
196+
197+
def generate_manifest(
198+
self,
199+
version: Optional[str] = None,
200+
commit: Optional[str] = None,
201+
):
202+
"""
203+
Generates an OCI manifest
204+
205+
:param cname: Canonical name of the manifest
206+
:param architecture: Target architecture of the manifest
207+
:param version: Artifacts version of the manifest
208+
:param commit: The commit hash of the manifest
209+
:param feature_set: The expanded list of the included features of this manifest
210+
211+
:return: (object) OCI manifest
212+
:since: 0.9.2
213+
"""
214+
215+
manifest = Manifest()
216+
217+
manifest.version = version
218+
manifest.commit = commit
219+
220+
manifest.config_from_dict({}, {})
221+
222+
return manifest
223+
192224
def _get_index_without_response_parsing(self):
193225
"""
194226
Return the response of an OCI image index request.
@@ -520,14 +552,14 @@ def read_or_generate_index(self):
520552

521553
def read_or_generate_manifest(
522554
self,
523-
cname: str,
555+
cname: Optional[str] = None,
524556
architecture: Optional[str] = None,
525557
version: Optional[str] = None,
526558
commit: Optional[str] = None,
527559
feature_set: Optional[str] = None,
528560
) -> Manifest:
529561
"""
530-
Reads from registry or generates the OCI image manifest.
562+
Reads from registry or generates the OCI manifest.
531563
532564
:param cname: Canonical name of the manifest
533565
:param architecture: Target architecture of the manifest
@@ -539,19 +571,31 @@ def read_or_generate_manifest(
539571
:since: 0.7.0
540572
"""
541573

542-
if architecture is None:
543-
architecture = CName(cname, architecture, version).arch
574+
if cname is None:
575+
manifest_type = Manifest
544576

545-
response = self._get_manifest_without_response_parsing(
546-
f"{self._container_version}-{cname}-{architecture}"
547-
)
577+
response = self._get_manifest_without_response_parsing(
578+
self._container_version
579+
)
580+
else:
581+
manifest_type = ImageManifest
582+
583+
if architecture is None:
584+
architecture = CName(cname, architecture, version).arch
585+
586+
response = self._get_manifest_without_response_parsing(
587+
f"{self._container_version}-{cname}-{architecture}"
588+
)
548589

549590
if response.ok:
550-
manifest = Manifest(**response.json())
591+
manifest = manifest_type(**response.json())
551592
elif response.status_code == 404:
552-
manifest = self.generate_manifest(
553-
cname, architecture, version, commit, feature_set
554-
)
593+
if cname is None:
594+
manifest = self.generate_manifest(version, commit)
595+
else:
596+
manifest = self.generate_image_manifest(
597+
cname, architecture, version, commit, feature_set
598+
)
555599
else:
556600
response.raise_for_status()
557601

0 commit comments

Comments
 (0)