Skip to content

Commit fae69e6

Browse files
committed
Misc: add a small tool to graph manifest includes
This is a simple script that display a tree of manifest includes. I wrote it as a quick tool to get an idea of how manifest were structured. Requires the anytree lib. Simply pass the manifest you want to start from as an argument. Sample output on RHCOS: ``` (L)manifest.yaml └── (L)manifest-rhel-coreos-9.yaml └── manifest-rhel-9.2.yaml ├── common.yaml │ ├── fedora-coreos-config/manifests/system-configuration.yaml │ ├── fedora-coreos-config/manifests/ignition-and-ostree.yaml │ │ └── fedora-coreos-config/manifests/bootable-rpm-ostree.yaml │ ├── fedora-coreos-config/manifests/file-transfer.yaml │ ├── fedora-coreos-config/manifests/networking-tools.yaml │ ├── fedora-coreos-config/manifests/user-experience.yaml │ ├── fedora-coreos-config/manifests/shared-workarounds.yaml │ └── packages-rhcos.yaml └── packages-openshift.yaml ```
1 parent af976fa commit fae69e6

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

src/manifest_graph

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/python3 -u
2+
3+
'''
4+
Create a tree chart with all the manifest includes
5+
symlinks are displayed with a (L) prefix
6+
'''
7+
8+
import sys
9+
import yaml
10+
import os
11+
from anytree import Node, RenderTree
12+
13+
def collect_included_files(filename, parent):
14+
node = None
15+
16+
if os.path.islink(filename):
17+
node = Node("(L)"+filename, parent=parent)
18+
dest = os.readlink(filename)
19+
collect_included_files(dest, parent=node)
20+
return node
21+
else:
22+
node = Node(filename, parent=parent)
23+
24+
with open(filename, 'r') as file:
25+
try:
26+
data = yaml.safe_load(file)
27+
if data is None:
28+
return
29+
include_paths = data.get('include')
30+
if include_paths:
31+
if not isinstance(include_paths, list):
32+
include_paths = [include_paths]
33+
34+
for include_path in include_paths:
35+
if not os.path.isabs(include_path):
36+
include_path = os.path.join(os.path.dirname(filename), include_path)
37+
if os.path.exists(include_path):
38+
collect_included_files(include_path, parent=node)
39+
return node
40+
except yaml.YAMLError as e:
41+
print(f"Error parsing YAML file '{filename}': {e}")
42+
sys.exit(1)
43+
except Exception as e:
44+
print(f"Error: {e}")
45+
sys.exit(1)
46+
47+
if __name__ == "__main__":
48+
if len(sys.argv) != 2:
49+
print("Usage: python manifest_graph <yaml_file>")
50+
sys.exit(1)
51+
52+
yaml_file = sys.argv[1]
53+
if not os.path.exists(yaml_file):
54+
print(f"Error: File '{yaml_file}' not found.")
55+
sys.exit(1)
56+
57+
root = collect_included_files(yaml_file, None)
58+
59+
for pre, _, node in RenderTree(root):
60+
print("%s%s" % (pre, node.name))

0 commit comments

Comments
 (0)