bugfix
[plcapi.git] / PLC / Methods / GetNodeFlavour.py
index 79943f9..f41b637 100644 (file)
@@ -1,23 +1,23 @@
-# $Id$
-# $URL$
+import traceback
+
 from PLC.Method import Method
 from PLC.Auth import Auth
 from PLC.Faults import *
 from PLC.Parameter import *
 from PLC.Nodes import Node, Nodes
 
-from PLC.Accessors.Accessors_standard import *                 # import node accessors
+from PLC.Accessors.Accessors_standard import *                  # import node accessors
 
 class GetNodeFlavour(Method):
     """
     Returns detailed information on a given node's flavour, i.e. its
-    base installation. 
+    base installation.
 
     This depends on the global PLC settings in the PLC_FLAVOUR area,
     optionnally overridden by any of the following tags if set on that node:
 
-    'arch', 'pldistro', 'fcdistro', (xxx fcdistro not yet supported)
-    'deployment', 'extensions',
+    'arch', 'pldistro', 'fcdistro',
+    'deployment', 'extensions', 'virt', 
     """
 
     roles = ['admin', 'user', 'node']
@@ -28,38 +28,60 @@ class GetNodeFlavour(Method):
               Node.fields['hostname']),
         ]
 
-    returns = { 
-        'nodefamily' : Parameter (str, "the node-family this node should be based upon"),
+    returns = {
+        'nodefamily' : Parameter (str, "the nodefamily this node should be based upon"),
+        'fcdistro': Parameter (str, "the fcdistro this node should be based upon"),
         'extensions' : [ Parameter (str, "extensions to add to the base install") ],
         'plain' : Parameter (bool, "use plain bootstrapfs image if set (for tests)" ) ,
         }
 
-    
+
     ########## nodefamily
-    def nodefamily (self, auth, node_id, arch):
+    def nodefamily (self, auth, node_id, fcdistro, pldistro, arch):
 
         # the deployment tag, if set, wins
-        deployment = GetNodeDeployment (self.api).call(auth,node_id)
+        # xxx Thierry: this probably is wrong; we need fcdistro to be set anyway
+        # for generating the proper yum config....
+        deployment = GetNodeDeployment (self.api,self.caller).call(auth,node_id)
         if deployment: return deployment
 
-        pldistro = GetNodePldistro (self.api).call(auth, node_id)
-        if not pldistro: pldistro = self.api.config.PLC_FLAVOUR_NODE_PLDISTRO
-
-        ###fcdistro = GetNodeFcdistro (self.api).call(auth, node_id)
-        ###if not fcdistro: fcdistro = self.api.config.PLC_FLAVOUR_NODE_FCDISTRO
-
         # xxx would make sense to check the corresponding bootstrapfs is available
-        ###return "%s-%s-%s"%(pldistro,fcdistro,arch)
-        return "%s-%s"%(pldistro,arch)
-
-    def extensions (self, auth, node_id, arch):
+        return "%s-%s-%s"%(pldistro,fcdistro,arch)
+
+    ##########
+    # parse PLC_FLAVOUR_VIRT_MAP 
+    known_virts=['vs','lxc']
+    default_virt='vs'
+    def virt_from_virt_map (self, node_fcdistro):
+        map={}
         try:
-            return [ "%s-%s"%(e,arch) for e in GetNodeExtensions(self.api).call(auth,node_id).split() ]
+            assigns=[x.strip() for x in self.api.config.PLC_FLAVOUR_VIRT_MAP.split(';')]
+            for assign in assigns:
+                (left,right)=[x.strip() for x in assign.split(':')]
+                if right not in GetNodeFlavour.known_virts:
+                    print "GetNodeFlavour, unknown 'virt' %s - ignored" % right
+                    continue
+                for fcdistro in [ x.strip() for x in left.split(',')]:
+                    map[fcdistro]=right
+        except:
+            print "GetNodeFlavour, issue with parsing PLC_FLAVOUR_VIRT_MAP=%s - returning '%s'"%\
+                (self.api.config.PLC_FLAVOUR_VIRT_MAP,GetNodeFlavour.default_virt)
+            traceback.print_exc()
+            return GetNodeFlavour.default_virt
+#        print 'virt_from_virt_map, using map',map
+        if node_fcdistro in map:  return map[node_fcdistro]
+        if 'default' in map: return map['default']
+        return GetNodeFlavour.default_virt
+            
+
+    def extensions (self, auth, node_id, fcdistro, arch):
+        try:
+            return [ "%s-%s-%s"%(e,fcdistro,arch) for e in GetNodeExtensions(self.api,self.caller).call(auth,node_id).split() ]
         except:
             return []
 
     def plain (self, auth, node_id):
-        return not not GetNodePlainBootstrapfs(self.api).call(auth,node_id)
+        return not not GetNodePlainBootstrapfs(self.api,self.caller).call(auth,node_id)
 
     def call(self, auth, node_id_or_name):
         # Get node information
@@ -69,11 +91,34 @@ class GetNodeFlavour(Method):
         node = nodes[0]
         node_id = node['node_id']
 
-        arch = GetNodeArch (self.api).call(auth,node_id)
-        if not arch: arch = self.api.config.PLC_FLAVOUR_NODE_ARCH
+        arch = GetNodeArch (self.api,self.caller).call(auth,node_id)
+        # if not set, use the global default and tag the node, in case the global default changes later on
+        if not arch:
+            arch = self.api.config.PLC_FLAVOUR_NODE_ARCH
+            SetNodeArch (self.api,self.caller).call(auth,node_id,arch)
+
+        fcdistro = GetNodeFcdistro (self.api,self.caller).call(auth, node_id)
+        if not fcdistro:
+            fcdistro = self.api.config.PLC_FLAVOUR_NODE_FCDISTRO
+            SetNodeFcdistro (self.api,self.caller).call (auth, node_id, fcdistro)
+
+        pldistro = GetNodePldistro (self.api,self.caller).call(auth, node_id)
+        if not pldistro:
+            pldistro = self.api.config.PLC_FLAVOUR_NODE_PLDISTRO
+            SetNodePldistro(self.api,self.caller).call(auth,node_id,pldistro)
+
+        virt = GetNodeVirt (self.api,self.caller).call(auth, node_id)
+        if not virt:
+            virt = self.virt_from_virt_map (fcdistro)
+            SetNodeVirt (self.api, self.caller).call (auth, node_id, virt)
 
         # xxx could use some sanity checking, and could provide fallbacks
-        return { 'nodefamily' : self.nodefamily(auth,node_id, arch),
-                 'extensions' : self.extensions(auth,node_id, arch),
-                 'plain' : self.plain(auth,node_id),
-                 }
+        return {
+            'arch'      : arch,
+            'fcdistro'  : fcdistro,
+            'pldistro'  : pldistro,
+            'virt'      : virt,
+            'nodefamily': self.nodefamily(auth,node_id, fcdistro, pldistro, arch),
+            'extensions': self.extensions(auth,node_id, fcdistro, arch),
+            'plain'     : self.plain(auth,node_id),
+            }