do a topsort on the nodetemplates to respect requirements
diff --git a/xos/tosca/engine.py b/xos/tosca/engine.py
index a01ddd6..b5ce94b 100644
--- a/xos/tosca/engine.py
+++ b/xos/tosca/engine.py
@@ -28,10 +28,84 @@
finally:
os.remove(tmp_pathname)
+ self.compute_dependencies()
+
+ self.ordered_nodetemplates = []
+ self.ordered_names = self.topsort_dependencies()
+ for name in self.ordered_names:
+ if name in self.nodetemplates_by_name:
+ self.ordered_nodetemplates.append(self.nodetemplates_by_name[name])
+
#pdb.set_trace()
- def execute(self, user):
+ def compute_dependencies(self):
+ nodetemplates_by_name = {}
for nodetemplate in self.template.nodetemplates:
+ nodetemplates_by_name[nodetemplate.name] = nodetemplate
+
+ self.nodetemplates_by_name = nodetemplates_by_name
+
+ for nodetemplate in self.template.nodetemplates:
+ nodetemplate.dependencies = []
+ nodetemplate.dependencies_names = []
+ for reqs in nodetemplate.requirements:
+ for (k,v) in reqs.items():
+ name = v["node"]
+ if (name in nodetemplates_by_name):
+ nodetemplate.dependencies.append(nodetemplates_by_name[name])
+ nodetemplate.dependencies_names.append(name)
+
+ def topsort_dependencies(self):
+ # stolen from observer
+ g = self.nodetemplates_by_name
+
+ # Get set of all nodes, including those without outgoing edges
+ keys = set(g.keys())
+ values = set({})
+ for v in g.values():
+ values=values | set(v.dependencies_names)
+
+ all_nodes=list(keys|values)
+ steps = all_nodes
+
+ # Final order
+ order = []
+
+ # DFS stack, not using recursion
+ stack = []
+
+ # Unmarked set
+ unmarked = all_nodes
+
+ # visiting = [] - skip, don't expect 1000s of nodes, |E|/|V| is small
+
+ while unmarked:
+ stack.insert(0,unmarked[0]) # push first unmarked
+
+ while (stack):
+ n = stack[0]
+ add = True
+ try:
+ for m in g[n].dependencies_names:
+ if (m in unmarked):
+ add = False
+ stack.insert(0,m)
+ except KeyError:
+ pass
+ if (add):
+ if (n in steps and n not in order):
+ order.append(n)
+ item = stack.pop(0)
+ try:
+ unmarked.remove(item)
+ except ValueError:
+ pass
+
+ noorder = list(set(steps) - set(order))
+ return order + noorder
+
+ def execute(self, user):
+ for nodetemplate in self.ordered_nodetemplates: # self.template.nodetemplates:
self.execute_nodetemplate(user, nodetemplate)
def execute_nodetemplate(self, user, nodetemplate):
@@ -44,13 +118,14 @@
def execute_nodetemplate(self, user, nodetemplate):
if nodetemplate.type in resources.resources:
cls = resources.resources[nodetemplate.type]
- #print "work on", cls.__name__, nodetemplate.name
+ print "work on", cls.__name__, nodetemplate.name
obj = cls(user, nodetemplate)
obj.create_or_update()
def destroy(self, user):
+ nodetemplates = self.ordered_nodetemplates
models = []
- for nodetemplate in self.template.nodetemplates:
+ for nodetemplate in nodetemplates:
if nodetemplate.type in resources.resources:
cls = resources.resources[nodetemplate.type]
obj = cls(user, nodetemplate)