]>
Commit | Line | Data |
---|---|---|
3a4eb2c7 JS |
1 | #!/usr/bin/python3 |
2 | ||
3 | import os | |
4 | ||
5 | ||
6 | ||
7 | class RecipeExeption(Exception): | |
8 | pass | |
9 | ||
10 | ||
11 | ||
12 | # Should read the test, check if the syntax are valid | |
13 | # and return tuples with the ( host, command ) structure | |
14 | class recipe(): | |
15 | def __init__(self, path, circle=[]): | |
16 | self.log = log(4) | |
17 | self.recipe_file = path | |
18 | self.path = os.path.dirname(self.recipe_file) | |
19 | self.log.debug("Path of recipe is: {}".format(self.recipe_file)) | |
20 | self._recipe = None | |
21 | self._machines = None | |
22 | ||
23 | self.in_recursion = True | |
24 | if len(circle) == 0: | |
25 | self.in_recursion = False | |
26 | ||
27 | self.circle = circle | |
28 | self.log.debug(circle) | |
29 | self.log.debug(self.circle) | |
30 | ||
31 | if not os.path.isfile(self.recipe_file): | |
32 | self.log.error("No such file: {}".format(self.recipe_file)) | |
33 | ||
34 | try: | |
35 | with open(self.recipe_file) as fobj: | |
36 | self.raw_recipe = fobj.readlines() | |
37 | except FileNotFoundError as error: | |
38 | self.log.error("No such file: {}".format(vm_xml_file)) | |
39 | ||
40 | @property | |
41 | def recipe(self): | |
42 | if not self._recipe: | |
43 | self.parse() | |
44 | ||
45 | return self._recipe | |
46 | ||
47 | @property | |
48 | def machines(self): | |
49 | if not self._machines: | |
50 | self._machines = [] | |
51 | for line in self._recipe: | |
52 | if line[0] != "all" and line[0] not in self._machines: | |
53 | self._machines.append(line[0]) | |
54 | ||
55 | return self._machines | |
56 | ||
57 | def parse(self): | |
58 | self._recipe = [] | |
59 | i = 1 | |
60 | for line in self.raw_recipe: | |
61 | raw_line = line.split(":") | |
62 | if len(raw_line) < 2: | |
63 | self.log.error("Error parsing the recipe in line {}".format(i)) | |
64 | raise RecipeExeption | |
65 | cmd = raw_line[1].strip() | |
66 | raw_line = raw_line[0].strip().split(" ") | |
67 | if len(raw_line) == 0: | |
68 | self.log.error("Failed to parse the recipe in line {}".format(i)) | |
69 | raise RecipeExeption | |
70 | ||
71 | if raw_line[0].strip() == "": | |
72 | self.log.error("Failed to parse the recipe in line {}".format(i)) | |
73 | raise RecipeExeption | |
74 | ||
75 | machine = raw_line[0].strip() | |
76 | ||
77 | if len(raw_line) == 2: | |
78 | extra = raw_line[1].strip() | |
79 | else: | |
80 | extra = "" | |
81 | ||
82 | # We could get a machine here or a include statement | |
83 | if machine == "include": | |
84 | path = cmd.strip() | |
85 | path = os.path.normpath(self.path + "/" + path) | |
86 | path = path + "/recipe" | |
87 | if path in self.circle: | |
88 | self.log.error("Detect import loop!") | |
89 | raise RecipeExeption | |
90 | self.circle.append(path) | |
91 | recipe_to_include = recipe(path, circle=self.circle) | |
92 | ||
93 | if machine == "include": | |
94 | self._recipe.extend(recipe_to_include.recipe) | |
95 | else: | |
96 | # Support also something like 'alice,bob: echo' | |
97 | machines = machine.split(",") | |
98 | for machine in machines: | |
99 | self._recipe.append((machine.strip(), extra.strip(), cmd.strip())) | |
100 | i = i + 1 | |
101 | ||
102 | if not self.in_recursion: | |
103 | tmp_recipe = [] | |
104 | for line in self._recipe: | |
105 | if line[0] != "all": | |
106 | tmp_recipe.append(line) | |
107 | else: | |
108 | for machine in self.machines: | |
109 | tmp_recipe.append((machine.strip(), line[1], line[2])) | |
110 | ||
111 | self._recipe = tmp_recipe |