blob: a0d917d4cd9f74db78071e586acacea82470a1d4 [file] [log] [blame]
Scott Baker66566722015-07-27 17:42:39 -07001import os
2import pdb
3import sys
4import tempfile
5sys.path.append("/opt/tosca")
6from translator.toscalib.tosca_template import ToscaTemplate
7
Scott Baker66566722015-07-27 17:42:39 -07008from core.models import Slice,Sliver,User,Flavor,Node,Image
Scott Bakerefa6ea42015-07-31 11:48:45 -07009from nodeselect import XOSNodeSelector
Scott Baker1f9d4512015-08-03 09:56:35 -070010from imageselect import XOSImageSelector
Scott Baker66566722015-07-27 17:42:39 -070011
Scott Baker3841b372015-08-03 14:20:31 -070012import resources
13
Scott Baker66566722015-07-27 17:42:39 -070014class XOSTosca(object):
Scott Baker7e472dd2015-07-31 12:30:28 -070015 def __init__(self, tosca_yaml, parent_dir=None):
16 # TOSCA will look for imports using a relative path from where the
17 # template file is located, so we have to put the template file
18 # in a specific place.
19 if not parent_dir:
20 parent_dir = os.getcwd()
21
Scott Baker66566722015-07-27 17:42:39 -070022 try:
Scott Baker7e472dd2015-07-31 12:30:28 -070023 (tmp_handle, tmp_pathname) = tempfile.mkstemp(dir=parent_dir)
Scott Baker66566722015-07-27 17:42:39 -070024 os.write(tmp_handle, tosca_yaml)
25 os.close(tmp_handle)
26
27 self.template = ToscaTemplate(tmp_pathname)
28 finally:
29 os.remove(tmp_pathname)
30
Scott Baker9fdffff2015-08-04 23:52:18 -070031 self.compute_dependencies()
32
33 self.ordered_nodetemplates = []
34 self.ordered_names = self.topsort_dependencies()
Scott Bakerf828c3e2015-08-05 18:23:14 -070035 print "ordered_names", self.ordered_names
Scott Baker9fdffff2015-08-04 23:52:18 -070036 for name in self.ordered_names:
37 if name in self.nodetemplates_by_name:
38 self.ordered_nodetemplates.append(self.nodetemplates_by_name[name])
39
Scott Baker66566722015-07-27 17:42:39 -070040 #pdb.set_trace()
41
Scott Baker9fdffff2015-08-04 23:52:18 -070042 def compute_dependencies(self):
43 nodetemplates_by_name = {}
Scott Baker66566722015-07-27 17:42:39 -070044 for nodetemplate in self.template.nodetemplates:
Scott Baker9fdffff2015-08-04 23:52:18 -070045 nodetemplates_by_name[nodetemplate.name] = nodetemplate
46
47 self.nodetemplates_by_name = nodetemplates_by_name
48
49 for nodetemplate in self.template.nodetemplates:
50 nodetemplate.dependencies = []
51 nodetemplate.dependencies_names = []
52 for reqs in nodetemplate.requirements:
53 for (k,v) in reqs.items():
54 name = v["node"]
55 if (name in nodetemplates_by_name):
56 nodetemplate.dependencies.append(nodetemplates_by_name[name])
57 nodetemplate.dependencies_names.append(name)
58
Scott Bakerf828c3e2015-08-05 18:23:14 -070059 # go another level deep, as our requirements can have requirements...
60 for sd_req in v.get("requirements",[]):
61 for (sd_req_k, sd_req_v) in sd_req.items():
62 name = sd_req_v["node"]
63 if (name in nodetemplates_by_name):
64 nodetemplate.dependencies.append(nodetemplates_by_name[name])
65 nodetemplate.dependencies_names.append(name)
66
67
Scott Baker9fdffff2015-08-04 23:52:18 -070068 def topsort_dependencies(self):
69 # stolen from observer
70 g = self.nodetemplates_by_name
71
72 # Get set of all nodes, including those without outgoing edges
73 keys = set(g.keys())
74 values = set({})
75 for v in g.values():
76 values=values | set(v.dependencies_names)
77
78 all_nodes=list(keys|values)
79 steps = all_nodes
80
81 # Final order
82 order = []
83
84 # DFS stack, not using recursion
85 stack = []
86
87 # Unmarked set
88 unmarked = all_nodes
89
90 # visiting = [] - skip, don't expect 1000s of nodes, |E|/|V| is small
91
92 while unmarked:
93 stack.insert(0,unmarked[0]) # push first unmarked
94
95 while (stack):
96 n = stack[0]
97 add = True
98 try:
99 for m in g[n].dependencies_names:
100 if (m in unmarked):
101 add = False
102 stack.insert(0,m)
103 except KeyError:
104 pass
105 if (add):
106 if (n in steps and n not in order):
107 order.append(n)
108 item = stack.pop(0)
109 try:
110 unmarked.remove(item)
111 except ValueError:
112 pass
113
114 noorder = list(set(steps) - set(order))
115 return order + noorder
116
117 def execute(self, user):
Scott Baker13399c02015-08-05 16:35:09 -0700118 for nodetemplate in self.ordered_nodetemplates:
Scott Baker66566722015-07-27 17:42:39 -0700119 self.execute_nodetemplate(user, nodetemplate)
120
Scott Baker66566722015-07-27 17:42:39 -0700121 def execute_nodetemplate(self, user, nodetemplate):
Scott Baker3841b372015-08-03 14:20:31 -0700122 if nodetemplate.type in resources.resources:
123 cls = resources.resources[nodetemplate.type]
Scott Bakerc4005d02015-08-06 17:21:34 -0700124 #print "work on", cls.__name__, nodetemplate.name
Scott Baker5d432142015-08-07 17:06:47 -0700125 obj = cls(user, nodetemplate, self)
Scott Baker9fdb39f2015-08-04 16:44:18 -0700126 obj.create_or_update()
Scott Baker7e472dd2015-07-31 12:30:28 -0700127
Scott Baker8899be92015-08-04 17:02:29 -0700128 def destroy(self, user):
Scott Baker9fdffff2015-08-04 23:52:18 -0700129 nodetemplates = self.ordered_nodetemplates
Scott Baker8899be92015-08-04 17:02:29 -0700130 models = []
Scott Baker9fdffff2015-08-04 23:52:18 -0700131 for nodetemplate in nodetemplates:
Scott Baker8899be92015-08-04 17:02:29 -0700132 if nodetemplate.type in resources.resources:
133 cls = resources.resources[nodetemplate.type]
Scott Baker5d432142015-08-07 17:06:47 -0700134 obj = cls(user, nodetemplate, self)
Scott Baker13399c02015-08-05 16:35:09 -0700135 for model in obj.get_existing_objs():
136 models.append( (obj, model) )
Scott Baker8899be92015-08-04 17:02:29 -0700137 models.reverse()
Scott Baker13399c02015-08-05 16:35:09 -0700138 for (resource,model) in models:
Scott Baker8899be92015-08-04 17:02:29 -0700139 print "destroying", model
Scott Baker13399c02015-08-05 16:35:09 -0700140 resource.delete(model)
Scott Baker66566722015-07-27 17:42:39 -0700141
Scott Baker5d432142015-08-07 17:06:47 -0700142 def name_to_xos_class(self, user, name):
143 nt = self.nodetemplates_by_name.get(name)
144 if not nt:
145 raise Exception("failed to find nodetemplate %s" % name)
146
147 cls = resources.resources.get(nt.type)
148 if not cls:
149 raise Exception("nodetemplate %s's type does not resolve to a known resource type" % name)
150
151 return (nt, cls, cls.xos_model)
152
153 def name_to_xos_model(self, user, name):
154 (nt, cls, model_class) = self.name_to_xos_class(user, name)
155 obj = cls(user, nt, self)
156 existing_objs = obj.get_existing_objs()
157 if not existing_objs:
158 raise Exception("failed to find xos %s %s" % (cls.__name__, name))
159 return existing_objs[0]
160