4
4
Canonical name (cname)
5
5
"""
6
6
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
8
11
import re
9
12
10
13
from ..constants import ARCHS
@@ -38,9 +41,11 @@ def __init__(self, cname, arch=None, commit_id=None, version=None):
38
41
"""
39
42
40
43
self ._arch = None
41
- self ._flavor = None
42
44
self ._commit_id = None
45
+ self ._feature_set_cached = None
46
+ self ._flavor = None
43
47
self ._version = None
48
+ self ._platforms_cached = None
44
49
45
50
re_match = re .match (
46
51
"([a-zA-Z0-9]+([\\ _\\ -][a-zA-Z0-9]+)*?)(-([a-z0-9]+)(-([a-z0-9.]+)-([a-z0-9]+))*)?$" ,
@@ -82,6 +87,7 @@ def arch(self) -> Optional[str]:
82
87
Returns the architecture for the cname parsed.
83
88
84
89
:return: (str) CName architecture
90
+ :since: 0.7.0
85
91
"""
86
92
87
93
return self ._arch
@@ -92,6 +98,7 @@ def cname(self) -> str:
92
98
Returns the cname parsed.
93
99
94
100
:return: (str) CName
101
+ :since: 0.7.0
95
102
"""
96
103
97
104
cname = self ._flavor
@@ -110,6 +117,7 @@ def commit_id(self) -> Optional[str]:
110
117
Returns the commit ID if part of the cname parsed.
111
118
112
119
:return: (str) Commit ID
120
+ :since: 0.7.0
113
121
"""
114
122
115
123
return self ._commit_id
@@ -120,6 +128,7 @@ def flavor(self) -> str:
120
128
Returns the flavor for the cname parsed.
121
129
122
130
:return: (str) Flavor
131
+ :since: 0.7.0
123
132
"""
124
133
125
134
return self ._flavor
@@ -130,8 +139,12 @@ def feature_set(self) -> str:
130
139
Returns the feature set for the cname parsed.
131
140
132
141
:return: (str) Feature set of the cname
142
+ :since: 0.7.0
133
143
"""
134
144
145
+ if self ._feature_set_cached is not None :
146
+ return self ._feature_set_cached
147
+
135
148
return Parser ().filter_as_string (self .flavor )
136
149
137
150
@property
@@ -140,16 +153,35 @@ def platform(self) -> str:
140
153
Returns the platform for the cname parsed.
141
154
142
155
:return: (str) Flavor
156
+ :since: 0.7.0
157
+ """
158
+
159
+ if self ._platforms_cached is not None :
160
+ return "," .join (self ._platforms_cached )
161
+
162
+ return "," .join (Parser ().filter_as_dict (self .flavor )["platform" ])
163
+
164
+ @property
165
+ def platforms (self ) -> List [str ]:
166
+ """
167
+ Returns the platforms for the cname parsed.
168
+
169
+ :return: (str) Flavor
170
+ :since: 0.9.1
143
171
"""
144
172
145
- return re .split ("[_-]" , self ._flavor , maxsplit = 1 )[0 ]
173
+ if self ._platforms_cached is not None :
174
+ return self ._platforms_cached
175
+
176
+ return Parser ().filter_as_dict (self .flavor )["platform" ]
146
177
147
178
@property
148
179
def version (self ) -> Optional [str ]:
149
180
"""
150
181
Returns the version if part of the cname parsed.
151
182
152
183
:return: (str) Version
184
+ :since: 0.7.0
153
185
"""
154
186
155
187
return self ._version
@@ -160,9 +192,117 @@ def version_and_commit_id(self) -> Optional[str]:
160
192
Returns the version and commit ID if part of the cname parsed.
161
193
162
194
:return: (str) Version and commit ID
195
+ :since: 0.7.0
163
196
"""
164
197
165
198
if self ._commit_id is None :
166
199
return None
167
200
168
201
return f"{ self ._version } -{ self ._commit_id } "
202
+
203
+ def load_from_metadata_file (self , metadata_file : PathLike | str ) -> None :
204
+ """
205
+ Loads and parses a metadata file.
206
+
207
+ :param metadata_file: Metadata file containing information about the CName instance.
208
+
209
+ :since: 0.9.1
210
+ """
211
+
212
+ if not isinstance (metadata_file , PathLike ):
213
+ metadata_file = Path (metadata_file )
214
+
215
+ if not metadata_file .exists ():
216
+ raise RuntimeError (f"Metadata file given is invalid: { metadata_file } " )
217
+
218
+ metadata_config = ConfigParser (allow_unnamed_section = True )
219
+ metadata_config .read (metadata_file )
220
+
221
+ for metadata_field in (
222
+ "GARDENLINUX_CNAME" ,
223
+ "GARDENLINUX_FEATURES" ,
224
+ "GARDENLINUX_FEATURES_PLATFORMS" ,
225
+ "GARDENLINUX_VERSION" ,
226
+ ):
227
+ if not metadata_config .has_option (UNNAMED_SECTION , metadata_field ):
228
+ raise RuntimeError (
229
+ f"Metadata file given is invalid: { metadata_file } misses { metadata_field } "
230
+ )
231
+
232
+ loaded_cname_instance = CName (
233
+ metadata_config .get (UNNAMED_SECTION , "GARDENLINUX_CNAME" )
234
+ )
235
+
236
+ commit_id = metadata_config .get (UNNAMED_SECTION , "GARDENLINUX_COMMIT_ID" )
237
+ version = metadata_config .get (UNNAMED_SECTION , "GARDENLINUX_VERSION" )
238
+
239
+ if (
240
+ loaded_cname_instance .flavor != self .flavor
241
+ or loaded_cname_instance .commit_id != commit_id
242
+ or (self ._commit_id is not None and self ._commit_id != commit_id )
243
+ or loaded_cname_instance .version != version
244
+ or (self ._version is not None and self ._version != version )
245
+ ):
246
+ raise RuntimeError (
247
+ f"Metadata file given is invalid: { metadata_file } failed consistency check - { self .cname } != { loaded_cname_instance .cname } "
248
+ )
249
+
250
+ self ._arch = loaded_cname_instance .arch
251
+ self ._flavor = loaded_cname_instance .flavor
252
+ self ._commit_id = commit_id
253
+ self ._version = version
254
+
255
+ self ._feature_set_cached = metadata_config .get (
256
+ UNNAMED_SECTION , "GARDENLINUX_FEATURES"
257
+ )
258
+
259
+ self ._platforms_cached = metadata_config .get (
260
+ UNNAMED_SECTION , "GARDENLINUX_FEATURES_PLATFORMS"
261
+ ).split ("," )
262
+
263
+ def save_to_metadata_file (
264
+ self , metadata_file : PathLike | str , overwrite : Optional [bool ] = False
265
+ ) -> None :
266
+ """
267
+ Saves the metadata file.
268
+
269
+ :param metadata_file: Metadata file containing information about the CName instance.
270
+
271
+ :since: 0.9.1
272
+ """
273
+
274
+ if not isinstance (metadata_file , PathLike ):
275
+ metadata_file = Path (metadata_file )
276
+
277
+ if not overwrite and metadata_file .exists ():
278
+ raise RuntimeError (
279
+ f"Refused to overwrite existing metadata file: { metadata_file } "
280
+ )
281
+
282
+ features = Parser ().filter_as_dict (self .flavor )
283
+
284
+ elements = "," .join (features ["element" ])
285
+ flags = "," .join (features ["flag" ])
286
+ platforms = "," .join (features ["platform" ])
287
+
288
+ metadata = f"""
289
+ ID=gardenlinux
290
+ NAME="Garden Linux"
291
+ PRETTY_NAME="Garden Linux { self .version } "
292
+ IMAGE_VERSION={ self .version }
293
+ VARIANT_ID="{ self .flavor } -{ self .arch } "
294
+ HOME_URL="https://gardenlinux.io"
295
+ SUPPORT_URL="https://github.com/gardenlinux/gardenlinux"
296
+ BUG_REPORT_URL="https://github.com/gardenlinux/gardenlinux/issues"
297
+ GARDENLINUX_CNAME="{ self .cname } "
298
+ GARDENLINUX_FEATURES="{ self .feature_set } "
299
+ GARDENLINUX_FEATURES_PLATFORMS="{ platforms } "
300
+ GARDENLINUX_FEATURES_ELEMENTS="{ elements } "
301
+ GARDENLINUX_FEATURES_FLAGS="{ flags } "
302
+ GARDENLINUX_VERSION="{ self .version } "
303
+ GARDENLINUX_COMMIT_ID="{ self .commit_id } "
304
+ GARDENLINUX_COMMIT_ID_LONG=$BUILDER_COMMIT
305
+ """ .strip ()
306
+
307
+ with metadata_file .open ("w" ) as fp :
308
+ fp .write (metadata )
0 commit comments