Skip to content

Commit 443c7c2

Browse files
committed
port glcli back from python_gardenlinux_cli
1 parent e68538b commit 443c7c2

File tree

8 files changed

+806
-2
lines changed

8 files changed

+806
-2
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ black = "^24.8.0"
2929
gl-cname = "python_gardenlinux_lib.cname:main"
3030
gl-flavors-parse = "python_gardenlinux_lib.flavors.parse_flavors:main"
3131
flavors-parse = "python_gardenlinux_lib.flavors.parse_flavors:main"
32+
glcli = "python_gardenlinux_lib.glcli.glcli:main"
3233

3334
[tool.pytest.ini_options]
3435
pythonpath = [

src/python_gardenlinux_lib/cname.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def main():
2121

2222
re_match = re.match(
2323
"([a-zA-Z0-9]+(-[a-zA-Z0-9\\_\\-]*?)?)(-([a-z0-9]+)(-([a-z0-9.]+)-([a-z0-9]+))*)?$",
24-
args.cname
24+
args.cname,
2525
)
2626

2727
assert re_match, f"not a valid cname {args.cname}"
@@ -72,11 +72,13 @@ def main():
7272

7373
print(cname)
7474

75+
7576
def get_cname_base(sorted_features):
7677
return reduce(
77-
lambda a, b : a + ("-" if not b.startswith("_") else "") + b, sorted_features
78+
lambda a, b: a + ("-" if not b.startswith("_") else "") + b, sorted_features
7879
)
7980

81+
8082
def get_minimal_feature_set(graph):
8183
return set([node for (node, degree) in graph.in_degree() if degree == 0])
8284

src/python_gardenlinux_lib/constants.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,19 @@
22

33
# It is important that this list is sorted in descending length of the entries
44
GL_MEDIA_TYPES = [
5+
"secureboot.aws-efivars",
6+
"secureboot.kek.auth",
57
"gcpimage.tar.gz.log",
8+
"secureboot.pk.auth",
9+
"secureboot.kek.crt",
10+
"secureboot.kek.der",
11+
"secureboot.db.auth",
612
"firecracker.tar.gz",
13+
"secureboot.pk.crt",
14+
"secureboot.pk.der",
15+
"secureboot.db.crt",
16+
"secureboot.db.der",
17+
"secureboot.db.arn",
718
"platform.test.log",
819
"platform.test.xml",
920
"gcpimage.tar.gz",
@@ -12,11 +23,15 @@
1223
"pxe.tar.gz.log",
1324
"root.squashfs",
1425
"manifest.log",
26+
"squashfs.log",
1527
"release.log",
28+
"vmlinuz.log",
29+
"initrd.log",
1630
"pxe.tar.gz",
1731
"qcow2.log",
1832
"test-log",
1933
"boot.efi",
34+
"squashfs",
2035
"manifest",
2136
"vmdk.log",
2237
"tar.log",
@@ -69,12 +84,27 @@
6984
"vhd.log": "application/io.gardenlinux.log",
7085
"ova.log": "application/io.gardenlinux.log",
7186
"vmlinuz": "application/io.gardenlinux.kernel",
87+
"vmlinuz.log": "application/io.gardenlinux.log",
7288
"initrd": "application/io.gardenlinux.initrd",
89+
"initrd.log": "application/io.gardenlinux.log",
7390
"root.squashfs": "application/io.gardenlinux.squashfs",
91+
"squashfs": "application/io.gardenlinux.squashfs",
92+
"squashfs.log": "application/io.gardenlinux.log",
7493
"boot.efi": "application/io.gardenlinux.efi",
7594
"platform.test.log": "application/io.gardenlinux.io.platform.test.log",
7695
"platform.test.xml": "application/io.gardenlinux.io.platform.test.xml",
7796
"chroot.test.log": "application/io.gardenlinux.io.chroot.test.log",
7897
"chroot.test.xml": "application/io.gardenlinux.io.chroot.test.xml",
7998
"oci.log": "application/io.gardenlinux.log",
99+
"secureboot.pk.crt": "application/io.gardenlinux.cert.secureboot.pk.crt",
100+
"secureboot.pk.der": "application/io.gardenlinux.cert.secureboot.pk.der",
101+
"secureboot.pk.auth": "application/io.gardenlinux.cert.secureboot.pk.auth",
102+
"secureboot.kek.crt": "application/io.gardenlinux.cert.secureboot.kek.crt",
103+
"secureboot.kek.der": "application/io.gardenlinux.cert.secureboot.kek.der",
104+
"secureboot.kek.auth": "application/io.gardenlinux.cert.secureboot.kek.auth",
105+
"secureboot.db.crt": "application/io.gardenlinux.cert.secureboot.db.crt",
106+
"secureboot.db.der": "application/io.gardenlinux.cert.secureboot.db.der",
107+
"secureboot.db.auth": "application/io.gardenlinux.cert.secureboot.db.auth",
108+
"secureboot.db.arn": "application/io.gardenlinux.cert.secureboot.db.arn",
109+
"secureboot.aws-efivars": "application/io.gardenlinux.cert.secureboot.aws-efivars",
80110
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import hashlib
2+
3+
4+
def verify_sha256(checksum: str, data: bytes):
5+
data_checksum = f"sha256:{hashlib.sha256(data).hexdigest()}"
6+
if checksum != data_checksum:
7+
raise ValueError(f"Invalid checksum. {checksum} != {data_checksum}")
8+
9+
10+
def calculate_sha256(file_path: str) -> str:
11+
"""Calculate the SHA256 checksum of a file."""
12+
sha256_hash = hashlib.sha256()
13+
with open(file_path, "rb") as f:
14+
for byte_block in iter(lambda: f.read(4096), b""):
15+
sha256_hash.update(byte_block)
16+
return sha256_hash.hexdigest()

src/python_gardenlinux_lib/features/parse_features.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def get_gardenlinux_commit(gardenlinux_root: str, limit: Optional[int] = None) -
3838
else:
3939
return commit_str
4040

41+
4142
def get_features_dict(
4243
cname: str, gardenlinux_root: str, feature_dir_name: str = "features"
4344
) -> dict:
@@ -61,6 +62,7 @@ def get_features_dict(
6162

6263
return features_by_type
6364

65+
6466
def get_features_graph(
6567
cname: str, gardenlinux_root: str, feature_dir_name: str = "features"
6668
) -> networkx.graph:
@@ -78,6 +80,7 @@ def get_features_graph(
7880

7981
return graph
8082

83+
8184
def get_features_list(
8285
cname: str, gardenlinux_root: str, feature_dir_name: str = "features"
8386
) -> list:
@@ -93,6 +96,7 @@ def get_features_list(
9396

9497
return features
9598

99+
96100
def get_features(
97101
cname: str, gardenlinux_root: str, feature_dir_name: str = "features"
98102
) -> str:
@@ -107,6 +111,7 @@ def get_features(
107111

108112
return ",".join(features)
109113

114+
110115
def construct_layer_metadata(
111116
filetype: str, cname: str, version: str, arch: str, commit: str
112117
) -> dict:
@@ -125,6 +130,7 @@ def construct_layer_metadata(
125130
"annotations": {"io.gardenlinux.image.layer.architecture": arch},
126131
}
127132

133+
128134
def construct_layer_metadata_from_filename(filename: str, arch: str) -> dict:
129135
"""
130136
:param str filename: filename of the blob
@@ -138,6 +144,7 @@ def construct_layer_metadata_from_filename(filename: str, arch: str) -> dict:
138144
"annotations": {"io.gardenlinux.image.layer.architecture": arch},
139145
}
140146

147+
141148
def get_file_set_from_cname(cname: str, version: str, arch: str, gardenlinux_root: str):
142149
"""
143150
:param str cname: the target cname of the image
@@ -160,6 +167,7 @@ def get_file_set_from_cname(cname: str, version: str, arch: str, gardenlinux_roo
160167
)
161168
return file_set
162169

170+
163171
def get_oci_metadata_from_fileset(fileset: list, arch: str):
164172
"""
165173
:param str arch: arch of the target image
@@ -175,6 +183,7 @@ def get_oci_metadata_from_fileset(fileset: list, arch: str):
175183

176184
return oci_layer_metadata_list
177185

186+
178187
def get_oci_metadata(cname: str, version: str, arch: str, gardenlinux_root: str):
179188
"""
180189
:param str cname: the target cname of the image
@@ -197,6 +206,7 @@ def get_oci_metadata(cname: str, version: str, arch: str, gardenlinux_root: str)
197206

198207
return oci_layer_metadata_list
199208

209+
200210
def lookup_media_type_for_filetype(filetype: str) -> str:
201211
"""
202212
:param str filetype: filetype of the target layer
@@ -209,6 +219,7 @@ def lookup_media_type_for_filetype(filetype: str) -> str:
209219
f"media type for {filetype} is not defined. You may want to add the definition to parse_features_lib"
210220
)
211221

222+
212223
def lookup_media_type_for_file(filename: str) -> str:
213224
"""
214225
:param str filename: filename of the target layer
@@ -222,6 +233,7 @@ def lookup_media_type_for_file(filename: str) -> str:
222233
f"media type for {filename} is not defined. You may want to add the definition to parse_features_lib"
223234
)
224235

236+
225237
def deduce_feature_name(feature_dir: str):
226238
"""
227239
:param str feature_dir: Directory of single Feature
@@ -232,20 +244,23 @@ def deduce_feature_name(feature_dir: str):
232244
raise ValueError("Expected name from parse_feature_yaml function to be set")
233245
return parsed["name"]
234246

247+
235248
def deduce_archive_filetypes(feature_dir):
236249
"""
237250
:param str feature_dir: Directory of single Feature
238251
:return: str list of filetype for archive
239252
"""
240253
return deduce_filetypes_from_string(feature_dir, "image")
241254

255+
242256
def deduce_image_filetypes(feature_dir):
243257
"""
244258
:param str feature_dir: Directory of single Feature
245259
:return: str list of filetype for image
246260
"""
247261
return deduce_filetypes_from_string(feature_dir, "convert")
248262

263+
249264
def deduce_filetypes(feature_dir):
250265
"""
251266
:param str feature_dir: Directory of single Feature
@@ -260,6 +275,7 @@ def deduce_filetypes(feature_dir):
260275
image_file_types.extend(archive_file_types)
261276
return image_file_types
262277

278+
263279
def deduce_filetypes_from_string(feature_dir: str, script_base_name: str):
264280
"""
265281
Garden Linux features can optionally have an image.<filetype> or convert.<filetype> script,
@@ -283,6 +299,7 @@ def deduce_filetypes_from_string(feature_dir: str, script_base_name: str):
283299

284300
return sorted(result)
285301

302+
286303
def read_feature_files(feature_dir):
287304
"""
288305
Legacy function copied from gardenlinux/builder
@@ -312,6 +329,7 @@ def read_feature_files(feature_dir):
312329
raise ValueError("Graph is not directed acyclic graph")
313330
return feature_graph
314331

332+
315333
def parse_feature_yaml(feature_yaml_file: str):
316334
"""
317335
Legacy function copied from gardenlinux/builder
@@ -328,9 +346,11 @@ def parse_feature_yaml(feature_yaml_file: str):
328346
content = yaml.safe_load(f)
329347
return {"name": name, "content": content}
330348

349+
331350
def __get_node_features(node):
332351
return node.get("content", {}).get("features", {})
333352

353+
334354
def filter_graph(feature_graph, feature_set, ignore_excludes=False):
335355
filter_set = set(feature_graph.nodes())
336356

@@ -369,29 +389,35 @@ def filter_func(node):
369389
raise ValueError("Including explicitly excluded feature")
370390
return graph
371391

392+
372393
def sort_set(input_set, order_list):
373394
return [item for item in order_list if item in input_set]
374395

396+
375397
def __sort_key(graph, node):
376398
prefix_map = {"platform": "0", "element": "1", "flag": "2"}
377399
node_type = __get_node_type(graph.nodes.get(node, {}))
378400
prefix = prefix_map[node_type]
379401
return f"{prefix}-{node}"
380402

403+
381404
def sort_nodes(graph):
382405
def key_function(node):
383406
return __sort_key(graph, node)
384407

385408
return list(networkx.lexicographical_topological_sort(graph, key=key_function))
386409

410+
387411
def __reverse_cname_base(cname):
388412
cname = cname.replace("_", "-_")
389413
return set(cname.split("-"))
390414

415+
391416
def __reverse_sort_nodes(graph):
392417
reverse_graph = graph.reverse()
393418
assert networkx.is_directed_acyclic_graph(reverse_graph)
394419
return sort_nodes(reverse_graph)
395420

421+
396422
def __get_node_type(node):
397423
return node.get("content", {}).get("type")

0 commit comments

Comments
 (0)