Move recipe class into an own file
[nitsi.git] / recipe.py
CommitLineData
3a4eb2c7
JS
1#!/usr/bin/python3
2
3import os
4
5
6
7class 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
14class 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