diff options
Diffstat (limited to 'scripts/resolve-profile.py.in')
-rw-r--r-- | scripts/resolve-profile.py.in | 133 |
1 files changed, 0 insertions, 133 deletions
diff --git a/scripts/resolve-profile.py.in b/scripts/resolve-profile.py.in deleted file mode 100644 index 2905423..0000000 --- a/scripts/resolve-profile.py.in +++ /dev/null | |||
@@ -1,133 +0,0 @@ | |||
1 | @PYTHON@ | ||
2 | # vim: set ts=4 et: | ||
3 | |||
4 | import os | ||
5 | import sys | ||
6 | import json | ||
7 | import shutil | ||
8 | import argparse | ||
9 | from datetime import datetime, timedelta | ||
10 | |||
11 | from pyhocon import ConfigFactory | ||
12 | |||
13 | |||
14 | # Just group together our transforms | ||
15 | class Transforms: | ||
16 | |||
17 | NOW = datetime.utcnow() | ||
18 | TOMORROW = NOW + timedelta(days=1) | ||
19 | |||
20 | unquote = lambda x: x.strip('"') | ||
21 | |||
22 | @staticmethod | ||
23 | def force_iso_date(input): | ||
24 | return datetime.fromisoformat(input).isoformat(timespec="seconds") | ||
25 | |||
26 | @classmethod | ||
27 | def resolve_tomorrow(cls, input): | ||
28 | return cls.TOMORROW.isoformat(timespec="seconds") | ||
29 | |||
30 | @classmethod | ||
31 | def resolve_now(cls, input): | ||
32 | return cls.NOW.strftime("%Y%m%d%H%M%S") | ||
33 | |||
34 | @classmethod | ||
35 | def fold_comma(cls, input): | ||
36 | return ",".join([cls.unquote(k) for k in input.keys()]) | ||
37 | |||
38 | @classmethod | ||
39 | def fold_space(cls, input): | ||
40 | return " ".join([cls.unquote(k) for k in input.keys()]) | ||
41 | |||
42 | @classmethod | ||
43 | def fold_repos(cls, input): | ||
44 | return "\n".join( | ||
45 | f"@{v} {cls.unquote(k)}" if isinstance(v, str) else cls.unquote(k) | ||
46 | for k, v in input.items()) | ||
47 | |||
48 | @staticmethod | ||
49 | def fold_packages(input): | ||
50 | return " ".join( | ||
51 | f"{k}@{v}" if isinstance(v, str) else k | ||
52 | for k, v in input.items()) | ||
53 | |||
54 | @staticmethod | ||
55 | def fold_services(input): | ||
56 | return " ".join( | ||
57 | "{}={}".format(k, ",".join(v.keys())) | ||
58 | for k, v in input.items()) | ||
59 | |||
60 | |||
61 | class ConfigBuilder: | ||
62 | |||
63 | _CFG_TRANSFORMS = { | ||
64 | "ami_access" : Transforms.fold_comma, | ||
65 | "ami_regions" : Transforms.fold_comma, | ||
66 | "kernel_modules" : Transforms.fold_comma, | ||
67 | "kernel_options" : Transforms.fold_space, | ||
68 | "repos" : Transforms.fold_repos, | ||
69 | "pkgs" : Transforms.fold_packages, | ||
70 | "svcs" : Transforms.fold_services, | ||
71 | "revision" : Transforms.resolve_now, | ||
72 | "end_of_life" : lambda x: \ | ||
73 | Transforms.force_iso_date(Transforms.resolve_tomorrow(x)), | ||
74 | } | ||
75 | |||
76 | def __init__(self, config_path, out_dir): | ||
77 | self.config_path = config_path | ||
78 | self.out_dir = out_dir | ||
79 | |||
80 | def build(self, profile): | ||
81 | build_config = ConfigFactory.parse_file(self.config_path) | ||
82 | |||
83 | for build, cfg in build_config["BUILDS"].items(): | ||
84 | build_dir = os.path.join(self.out_dir, build) | ||
85 | |||
86 | # Always start fresh | ||
87 | shutil.rmtree(build_dir, ignore_errors=True) | ||
88 | os.makedirs(build_dir) | ||
89 | |||
90 | cfg["profile"] = profile | ||
91 | cfg["profile_build"] = build | ||
92 | |||
93 | # Order of operations is important here | ||
94 | for k, v in cfg.items(): | ||
95 | transform = self._CFG_TRANSFORMS.get(k) | ||
96 | if transform: | ||
97 | cfg[k] = transform(v) | ||
98 | |||
99 | if isinstance(v, str) and "{var." in v: | ||
100 | cfg[k] = v.format(var=cfg) | ||
101 | |||
102 | with open(os.path.join(build_dir, "vars.json"), "w") as out: | ||
103 | json.dump(cfg, out, indent=4, separators=(",", ": ")) | ||
104 | |||
105 | |||
106 | def find_repo_root(): | ||
107 | path = os.getcwd() | ||
108 | |||
109 | while ".git" not in set(os.listdir(path)) and path != "/": | ||
110 | path = os.path.dirname(path) | ||
111 | |||
112 | if path == "/": | ||
113 | raise Exception("No repo found, stopping at /") | ||
114 | |||
115 | return path | ||
116 | |||
117 | |||
118 | def main(args): | ||
119 | parser = argparse.ArgumentParser(description="Build Packer JSON variable " | ||
120 | "files from HOCON build profiles") | ||
121 | parser.add_argument("profile", help="name of profile to build") | ||
122 | args = parser.parse_args() | ||
123 | |||
124 | root = find_repo_root() | ||
125 | |||
126 | ConfigBuilder( | ||
127 | os.path.join(root, "profiles", f"{args.profile}.conf"), | ||
128 | os.path.join(root, "build", "profile", args.profile) | ||
129 | ).build(args.profile) | ||
130 | |||
131 | |||
132 | if __name__ == "__main__": | ||
133 | main(sys.argv) | ||