remove PLC.Debug.log, use PLC.Logger.logger instead
[plcapi.git] / PLC / Methods / GetNodeFlavour.py
1 import traceback
2
3 from PLC.Logger import logger
4 from PLC.Method import Method
5 from PLC.Auth import Auth
6 from PLC.Faults import *
7 from PLC.Parameter import *
8 from PLC.Nodes import Node, Nodes
9
10 from PLC.Accessors.Accessors_standard import *                  # import node accessors
11
12 class GetNodeFlavour(Method):
13     """
14     Returns detailed information on a given node's flavour, i.e. its
15     base installation.
16
17     This depends on the global PLC settings in the PLC_FLAVOUR area,
18     optionnally overridden by any of the following tags if set on that node:
19
20     'arch', 'pldistro', 'fcdistro',
21     'deployment', 'extensions', 'virt', 
22     """
23
24     roles = ['admin', 'user', 'node']
25
26     accepts = [
27         Auth(),
28         Mixed(Node.fields['node_id'],
29               Node.fields['hostname']),
30         ]
31
32     returns = {
33         'nodefamily' : Parameter (str, "the nodefamily this node should be based upon"),
34         'fcdistro': Parameter (str, "the fcdistro this node should be based upon"),
35         'extensions' : [ Parameter (str, "extensions to add to the base install") ],
36         'plain' : Parameter (bool, "use plain bootstrapfs image if set (for tests)" ) ,
37         }
38
39
40     ########## nodefamily
41     def nodefamily (self, auth, node_id, fcdistro, pldistro, arch):
42
43         # the deployment tag, if set, wins
44         # xxx Thierry: this probably is wrong; we need fcdistro to be set anyway
45         # for generating the proper yum config....
46         deployment = GetNodeDeployment (self.api,self.caller).call(auth,node_id)
47         if deployment: return deployment
48
49         # xxx would make sense to check the corresponding bootstrapfs is available
50         return "%s-%s-%s"%(pldistro,fcdistro,arch)
51
52     ##########
53     # parse PLC_FLAVOUR_VIRT_MAP 
54     known_virts=['vs','lxc']
55     default_virt='vs'
56     def virt_from_virt_map (self, node_fcdistro):
57         map={}
58         try:
59             assigns=[x.strip() for x in self.api.config.PLC_FLAVOUR_VIRT_MAP.split(';')]
60             for assign in assigns:
61                 (left,right)=[x.strip() for x in assign.split(':')]
62                 if right not in GetNodeFlavour.known_virts:
63                     logger.error("GetNodeFlavour, unknown 'virt' %s - ignored" % right)
64                     continue
65                 for fcdistro in [ x.strip() for x in left.split(',')]:
66                     map[fcdistro]=right
67         except:
68             logger.exception("GetNodeFlavour, issue with parsing PLC_FLAVOUR_VIRT_MAP=%s - returning '%s'"%\
69                              (self.api.config.PLC_FLAVOUR_VIRT_MAP, GetNodeFlavour.default_virt))
70             return GetNodeFlavour.default_virt
71 #        print 'virt_from_virt_map, using map',map
72         if node_fcdistro in map:  return map[node_fcdistro]
73         if 'default' in map: return map['default']
74         return GetNodeFlavour.default_virt
75             
76
77     def extensions (self, auth, node_id, fcdistro, arch):
78         try:
79             return [ "%s-%s-%s"%(e,fcdistro,arch) for e in GetNodeExtensions(self.api,self.caller).call(auth,node_id).split() ]
80         except:
81             return []
82
83     def plain (self, auth, node_id):
84         return not not GetNodePlainBootstrapfs(self.api,self.caller).call(auth,node_id)
85
86     def call(self, auth, node_id_or_name):
87         # Get node information
88         nodes = Nodes(self.api, [node_id_or_name])
89         if not nodes:
90             raise PLCInvalidArgument, "No such node %r"%node_id_or_name
91         node = nodes[0]
92         node_id = node['node_id']
93
94         arch = GetNodeArch (self.api,self.caller).call(auth,node_id)
95         # if not set, use the global default and tag the node, in case the global default changes later on
96         if not arch:
97             arch = self.api.config.PLC_FLAVOUR_NODE_ARCH
98             SetNodeArch (self.api,self.caller).call(auth,node_id,arch)
99
100         fcdistro = GetNodeFcdistro (self.api,self.caller).call(auth, node_id)
101         if not fcdistro:
102             fcdistro = self.api.config.PLC_FLAVOUR_NODE_FCDISTRO
103             SetNodeFcdistro (self.api,self.caller).call (auth, node_id, fcdistro)
104
105         pldistro = GetNodePldistro (self.api,self.caller).call(auth, node_id)
106         if not pldistro:
107             pldistro = self.api.config.PLC_FLAVOUR_NODE_PLDISTRO
108             SetNodePldistro(self.api,self.caller).call(auth,node_id,pldistro)
109
110         virt = GetNodeVirt (self.api,self.caller).call(auth, node_id)
111         if not virt:
112             virt = self.virt_from_virt_map (fcdistro)
113             # do not save in node - if a node was e.g. f14 and it gets set to f16
114             # we do not want to have to re-set virt
115             # SetNodeVirt (self.api, self.caller).call (auth, node_id, virt)
116
117         # xxx could use some sanity checking, and could provide fallbacks
118         return {
119             'arch'      : arch,
120             'fcdistro'  : fcdistro,
121             'pldistro'  : pldistro,
122             'virt'      : virt,
123             'nodefamily': self.nodefamily(auth,node_id, fcdistro, pldistro, arch),
124             'extensions': self.extensions(auth,node_id, fcdistro, arch),
125             'plain'     : self.plain(auth,node_id),
126             }