Scott Baker | 6656672 | 2015-07-27 17:42:39 -0700 | [diff] [blame] | 1 | import os |
| 2 | import pdb |
| 3 | import sys |
| 4 | import tempfile |
| 5 | sys.path.append("/opt/tosca") |
| 6 | from translator.toscalib.tosca_template import ToscaTemplate |
| 7 | |
Scott Baker | 6656672 | 2015-07-27 17:42:39 -0700 | [diff] [blame] | 8 | from core.models import Slice,Sliver,User,Flavor,Node,Image |
Scott Baker | efa6ea4 | 2015-07-31 11:48:45 -0700 | [diff] [blame] | 9 | from nodeselect import XOSNodeSelector |
Scott Baker | 1f9d451 | 2015-08-03 09:56:35 -0700 | [diff] [blame] | 10 | from imageselect import XOSImageSelector |
Scott Baker | 6656672 | 2015-07-27 17:42:39 -0700 | [diff] [blame] | 11 | |
Scott Baker | 3841b37 | 2015-08-03 14:20:31 -0700 | [diff] [blame] | 12 | import resources |
| 13 | |
Scott Baker | 6656672 | 2015-07-27 17:42:39 -0700 | [diff] [blame] | 14 | class XOSTosca(object): |
Scott Baker | 7e472dd | 2015-07-31 12:30:28 -0700 | [diff] [blame] | 15 | 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 Baker | 6656672 | 2015-07-27 17:42:39 -0700 | [diff] [blame] | 22 | try: |
Scott Baker | 7e472dd | 2015-07-31 12:30:28 -0700 | [diff] [blame] | 23 | (tmp_handle, tmp_pathname) = tempfile.mkstemp(dir=parent_dir) |
Scott Baker | 6656672 | 2015-07-27 17:42:39 -0700 | [diff] [blame] | 24 | 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 Baker | 9fdffff | 2015-08-04 23:52:18 -0700 | [diff] [blame] | 31 | self.compute_dependencies() |
| 32 | |
| 33 | self.ordered_nodetemplates = [] |
| 34 | self.ordered_names = self.topsort_dependencies() |
| 35 | for name in self.ordered_names: |
| 36 | if name in self.nodetemplates_by_name: |
| 37 | self.ordered_nodetemplates.append(self.nodetemplates_by_name[name]) |
| 38 | |
Scott Baker | 6656672 | 2015-07-27 17:42:39 -0700 | [diff] [blame] | 39 | #pdb.set_trace() |
| 40 | |
Scott Baker | 9fdffff | 2015-08-04 23:52:18 -0700 | [diff] [blame] | 41 | def compute_dependencies(self): |
| 42 | nodetemplates_by_name = {} |
Scott Baker | 6656672 | 2015-07-27 17:42:39 -0700 | [diff] [blame] | 43 | for nodetemplate in self.template.nodetemplates: |
Scott Baker | 9fdffff | 2015-08-04 23:52:18 -0700 | [diff] [blame] | 44 | nodetemplates_by_name[nodetemplate.name] = nodetemplate |
| 45 | |
| 46 | self.nodetemplates_by_name = nodetemplates_by_name |
| 47 | |
| 48 | for nodetemplate in self.template.nodetemplates: |
| 49 | nodetemplate.dependencies = [] |
| 50 | nodetemplate.dependencies_names = [] |
| 51 | for reqs in nodetemplate.requirements: |
| 52 | for (k,v) in reqs.items(): |
| 53 | name = v["node"] |
| 54 | if (name in nodetemplates_by_name): |
| 55 | nodetemplate.dependencies.append(nodetemplates_by_name[name]) |
| 56 | nodetemplate.dependencies_names.append(name) |
| 57 | |
| 58 | def topsort_dependencies(self): |
| 59 | # stolen from observer |
| 60 | g = self.nodetemplates_by_name |
| 61 | |
| 62 | # Get set of all nodes, including those without outgoing edges |
| 63 | keys = set(g.keys()) |
| 64 | values = set({}) |
| 65 | for v in g.values(): |
| 66 | values=values | set(v.dependencies_names) |
| 67 | |
| 68 | all_nodes=list(keys|values) |
| 69 | steps = all_nodes |
| 70 | |
| 71 | # Final order |
| 72 | order = [] |
| 73 | |
| 74 | # DFS stack, not using recursion |
| 75 | stack = [] |
| 76 | |
| 77 | # Unmarked set |
| 78 | unmarked = all_nodes |
| 79 | |
| 80 | # visiting = [] - skip, don't expect 1000s of nodes, |E|/|V| is small |
| 81 | |
| 82 | while unmarked: |
| 83 | stack.insert(0,unmarked[0]) # push first unmarked |
| 84 | |
| 85 | while (stack): |
| 86 | n = stack[0] |
| 87 | add = True |
| 88 | try: |
| 89 | for m in g[n].dependencies_names: |
| 90 | if (m in unmarked): |
| 91 | add = False |
| 92 | stack.insert(0,m) |
| 93 | except KeyError: |
| 94 | pass |
| 95 | if (add): |
| 96 | if (n in steps and n not in order): |
| 97 | order.append(n) |
| 98 | item = stack.pop(0) |
| 99 | try: |
| 100 | unmarked.remove(item) |
| 101 | except ValueError: |
| 102 | pass |
| 103 | |
| 104 | noorder = list(set(steps) - set(order)) |
| 105 | return order + noorder |
| 106 | |
| 107 | def execute(self, user): |
| 108 | for nodetemplate in self.ordered_nodetemplates: # self.template.nodetemplates: |
Scott Baker | 6656672 | 2015-07-27 17:42:39 -0700 | [diff] [blame] | 109 | self.execute_nodetemplate(user, nodetemplate) |
| 110 | |
Scott Baker | 6656672 | 2015-07-27 17:42:39 -0700 | [diff] [blame] | 111 | def execute_nodetemplate(self, user, nodetemplate): |
Scott Baker | 3841b37 | 2015-08-03 14:20:31 -0700 | [diff] [blame] | 112 | if nodetemplate.type in resources.resources: |
| 113 | cls = resources.resources[nodetemplate.type] |
Scott Baker | 9fdb39f | 2015-08-04 16:44:18 -0700 | [diff] [blame] | 114 | #print "work on", cls.__name__, nodetemplate.name |
Scott Baker | 3841b37 | 2015-08-03 14:20:31 -0700 | [diff] [blame] | 115 | obj = cls(user, nodetemplate) |
Scott Baker | 9fdb39f | 2015-08-04 16:44:18 -0700 | [diff] [blame] | 116 | obj.create_or_update() |
Scott Baker | 7e472dd | 2015-07-31 12:30:28 -0700 | [diff] [blame] | 117 | |
Scott Baker | 8899be9 | 2015-08-04 17:02:29 -0700 | [diff] [blame] | 118 | def execute_nodetemplate(self, user, nodetemplate): |
| 119 | if nodetemplate.type in resources.resources: |
| 120 | cls = resources.resources[nodetemplate.type] |
Scott Baker | 9fdffff | 2015-08-04 23:52:18 -0700 | [diff] [blame] | 121 | print "work on", cls.__name__, nodetemplate.name |
Scott Baker | 8899be9 | 2015-08-04 17:02:29 -0700 | [diff] [blame] | 122 | obj = cls(user, nodetemplate) |
| 123 | obj.create_or_update() |
Scott Baker | 172797e | 2015-07-31 13:28:38 -0700 | [diff] [blame] | 124 | |
Scott Baker | 8899be9 | 2015-08-04 17:02:29 -0700 | [diff] [blame] | 125 | def destroy(self, user): |
Scott Baker | 9fdffff | 2015-08-04 23:52:18 -0700 | [diff] [blame] | 126 | nodetemplates = self.ordered_nodetemplates |
Scott Baker | 8899be9 | 2015-08-04 17:02:29 -0700 | [diff] [blame] | 127 | models = [] |
Scott Baker | 9fdffff | 2015-08-04 23:52:18 -0700 | [diff] [blame] | 128 | for nodetemplate in nodetemplates: |
Scott Baker | 8899be9 | 2015-08-04 17:02:29 -0700 | [diff] [blame] | 129 | if nodetemplate.type in resources.resources: |
| 130 | cls = resources.resources[nodetemplate.type] |
| 131 | obj = cls(user, nodetemplate) |
| 132 | models = models + list(obj.get_existing_objs()) |
| 133 | models.reverse() |
| 134 | for model in models: |
| 135 | print "destroying", model |
| 136 | model.delete(purge=True) # XXX change before deploying |
Scott Baker | 6656672 | 2015-07-27 17:42:39 -0700 | [diff] [blame] | 137 | |