Skip to content

Commit 82fef72

Browse files
committed
Add support to read and write metadata for a GL canonical name
Signed-off-by: Tobias Wolf <[email protected]>
1 parent 97d6e1c commit 82fef72

File tree

1 file changed

+140
-2
lines changed

1 file changed

+140
-2
lines changed

src/gardenlinux/features/cname.py

Lines changed: 140 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
Canonical name (cname)
55
"""
66

7-
from typing import Optional
7+
from configparser import ConfigParser, UNNAMED_SECTION
8+
from pathlib import Path
9+
from typing import List, Optional
10+
from os import PathLike
811
import re
912

1013
from ..constants import ARCHS
@@ -82,6 +85,7 @@ def arch(self) -> Optional[str]:
8285
Returns the architecture for the cname parsed.
8386
8487
:return: (str) CName architecture
88+
:since: 0.7.0
8589
"""
8690

8791
return self._arch
@@ -92,6 +96,7 @@ def cname(self) -> str:
9296
Returns the cname parsed.
9397
9498
:return: (str) CName
99+
:since: 0.7.0
95100
"""
96101

97102
cname = self._flavor
@@ -110,6 +115,7 @@ def commit_id(self) -> Optional[str]:
110115
Returns the commit ID if part of the cname parsed.
111116
112117
:return: (str) Commit ID
118+
:since: 0.7.0
113119
"""
114120

115121
return self._commit_id
@@ -120,6 +126,7 @@ def flavor(self) -> str:
120126
Returns the flavor for the cname parsed.
121127
122128
:return: (str) Flavor
129+
:since: 0.7.0
123130
"""
124131

125132
return self._flavor
@@ -130,8 +137,12 @@ def feature_set(self) -> str:
130137
Returns the feature set for the cname parsed.
131138
132139
:return: (str) Feature set of the cname
140+
:since: 0.7.0
133141
"""
134142

143+
if self._feature_set_cached is not None:
144+
return self._feature_set_cached
145+
135146
return Parser().filter_as_string(self.flavor)
136147

137148
@property
@@ -140,16 +151,35 @@ def platform(self) -> str:
140151
Returns the platform for the cname parsed.
141152
142153
:return: (str) Flavor
154+
:since: 0.7.0
143155
"""
144156

145-
return re.split("[_-]", self._flavor, maxsplit=1)[0]
157+
if self._platforms_cached is not None:
158+
return ",".join(self._platforms_cached)
159+
160+
return ",".join(Parser().filter_as_dict(self.flavor)["platform"])
161+
162+
@property
163+
def platforms(self) -> List[str]:
164+
"""
165+
Returns the platforms for the cname parsed.
166+
167+
:return: (str) Flavor
168+
:since: 0.9.1
169+
"""
170+
171+
if self._platforms_cached is not None:
172+
return self._platforms_cached
173+
174+
return Parser().filter_as_dict(self.flavor)["platform"]
146175

147176
@property
148177
def version(self) -> Optional[str]:
149178
"""
150179
Returns the version if part of the cname parsed.
151180
152181
:return: (str) Version
182+
:since: 0.7.0
153183
"""
154184

155185
return self._version
@@ -160,9 +190,117 @@ def version_and_commit_id(self) -> Optional[str]:
160190
Returns the version and commit ID if part of the cname parsed.
161191
162192
:return: (str) Version and commit ID
193+
:since: 0.7.0
163194
"""
164195

165196
if self._commit_id is None:
166197
return None
167198

168199
return f"{self._version}-{self._commit_id}"
200+
201+
def load_from_metadata_file(self, metadata_file: PathLike | str) -> None:
202+
"""
203+
Loads and parses a metadata file.
204+
205+
:param metadata_file: Metadata file containing information about the CName instance.
206+
207+
:since: 0.9.1
208+
"""
209+
210+
if not isinstance(metadata_file, PathLike):
211+
metadata_file = Path(metadata_file)
212+
213+
if not metadata_file.exists():
214+
raise RuntimeError(f"Metadata file given is invalid: {metadata_file}")
215+
216+
metadata_config = ConfigParser(allow_unnamed_section=True)
217+
metadata_config.read(metadata_file)
218+
219+
for metadata_field in (
220+
"GARDENLINUX_CNAME",
221+
"GARDENLINUX_FEATURES",
222+
"GARDENLINUX_FEATURES_PLATFORMS",
223+
"GARDENLINUX_VERSION",
224+
):
225+
if not metadata_config.has_option(UNNAMED_SECTION, metadata_field):
226+
raise RuntimeError(
227+
f"Metadata file given is invalid: {metadata_file} misses {metadata_field}"
228+
)
229+
230+
loaded_cname_instance = CName(
231+
metadata_config.get(UNNAMED_SECTION, "GARDENLINUX_CNAME")
232+
)
233+
234+
commit_id = metadata_config.get(UNNAMED_SECTION, "GARDENLINUX_COMMIT_ID")
235+
version = metadata_config.get(UNNAMED_SECTION, "GARDENLINUX_VERSION")
236+
237+
if (
238+
loaded_cname_instance.flavor != self.flavor
239+
or loaded_cname_instance.commit_id != commit_id
240+
or (self._commit_id is not None and self._commit_id != commit_id)
241+
or loaded_cname_instance.version != version
242+
or (self._version is not None and self._version != version)
243+
):
244+
raise RuntimeError(
245+
f"Metadata file given is invalid: {metadata_file} failed consistency check - {self.cname} != {loaded_cname_instance.cname}"
246+
)
247+
248+
self._arch = loaded_cname_instance.arch
249+
self._flavor = loaded_cname_instance.flavor
250+
self._commit_id = commit_id
251+
self._version = version
252+
253+
self._feature_set_cached = metadata_config.get(
254+
UNNAMED_SECTION, "GARDENLINUX_FEATURES"
255+
)
256+
257+
self._platforms_cached = metadata_config.get(
258+
UNNAMED_SECTION, "GARDENLINUX_FEATURES_PLATFORMS"
259+
).split(",")
260+
261+
def save_to_metadata_file(
262+
self, metadata_file: PathLike | str, overwrite: Optional[bool] = False
263+
) -> None:
264+
"""
265+
Saves the metadata file.
266+
267+
:param metadata_file: Metadata file containing information about the CName instance.
268+
269+
:since: 0.9.1
270+
"""
271+
272+
if not isinstance(metadata_file, PathLike):
273+
metadata_file = Path(metadata_file)
274+
275+
if not overwrite and metadata_file.exists():
276+
raise RuntimeError(
277+
f"Refused to overwrite existing metadata file: {metadata_file}"
278+
)
279+
280+
features = Parser().filter_as_dict(self.flavor)
281+
282+
elements = ",".join(features["element"])
283+
flags = ",".join(features["flag"])
284+
platforms = ",".join(features["platform"])
285+
286+
metadata = f"""
287+
ID=gardenlinux
288+
NAME="Garden Linux"
289+
PRETTY_NAME="Garden Linux {self.version}"
290+
IMAGE_VERSION={self.version}
291+
VARIANT_ID="{self.flavor}-{self.arch}"
292+
HOME_URL="https://gardenlinux.io"
293+
SUPPORT_URL="https://github.com/gardenlinux/gardenlinux"
294+
BUG_REPORT_URL="https://github.com/gardenlinux/gardenlinux/issues"
295+
GARDENLINUX_CNAME="{self.cname}"
296+
GARDENLINUX_FEATURES="{self.feature_set}"
297+
GARDENLINUX_FEATURES_PLATFORMS="{platforms}"
298+
GARDENLINUX_FEATURES_ELEMENTS="{elements}"
299+
GARDENLINUX_FEATURES_FLAGS="{flags}"
300+
GARDENLINUX_VERSION="{self.version}"
301+
GARDENLINUX_COMMIT_ID="{self.commit_id}"
302+
GARDENLINUX_COMMIT_ID_LONG=$BUILDER_COMMIT
303+
""".strip()
304+
305+
with metadata_file.open("w") as fp:
306+
fp.write(metadata)

0 commit comments

Comments
 (0)