b3d3ab07e609d3c4dc79bf65cdf848174931fe6b
[bootmanager.git] / source / steps / GetAndUpdateNodeDetails.py
1 import string
2
3 from Exceptions import *
4 import BootAPI
5
6 MINHW_OPT  = 0x001
7 SMP_OPT    = 0x002
8 X86_64_OPT = 0x004
9 INTEL_OPT  = 0x008
10 AMD_OPT    = 0x010
11 NUMA_OPT   = 0x020
12 LAST_OPT   = 0x040
13
14 modeloptions = {'smp':SMP_OPT,
15                 'x64':X86_64_OPT,
16                 'i64':X86_64_OPT|INTEL_OPT,
17                 'a64':X86_64_OPT|AMD_OPT,
18                 'i32':INTEL_OPT,
19                 'a32':AMD_OPT,
20                 'numa':NUMA_OPT,
21                 'minhw':MINHW_OPT}
22
23 def Run( vars, log ):
24     """
25
26     Contact PLC and get the attributes for this node. Also, parse in
27     options from the node model strong.
28
29     Also, update any node network settings at PLC, minus the ip address,
30     so, upload the mac (if node_id was in conf file), gateway, network,
31     broadcast, netmask, dns1/2, and the hostname/domainname.
32
33     Expect the following keys to be set:
34     BOOT_CD_VERSION          A tuple of the current bootcd version
35     SKIP_HARDWARE_REQUIREMENT_CHECK     Whether or not we should skip hardware
36                                         requirement checks
37                                         
38     The following keys are set/updated:
39     WAS_NODE_ID_IN_CONF      Set to 1 if the node id was in the conf file
40     WAS_NODE_KEY_IN_CONF     Set to 1 if the node key was in the conf file
41     BOOT_STATE               The current node boot state
42     NODE_MODEL               The user specified model of this node
43     NODE_MODEL_OPTIONS       The options extracted from the user specified
44                              model of this node 
45     NETWORK_SETTINGS         A dictionary of the values of the network settings
46     SKIP_HARDWARE_REQUIREMENT_CHECK     Whether or not we should skip hardware
47                                         requirement checks
48     NODE_SESSION             The session value returned from BootGetNodeDetails
49     
50     Return 1 if able to contact PLC and get node info.
51     Raise a BootManagerException if anything fails.
52     """
53
54     log.write( "\n\nStep: Retrieving details of node from PLC.\n" )
55
56     # make sure we have the variables we need
57     try:
58         BOOT_CD_VERSION= vars["BOOT_CD_VERSION"]
59         if BOOT_CD_VERSION == "":
60             raise ValueError, "BOOT_CD_VERSION"
61
62         SKIP_HARDWARE_REQUIREMENT_CHECK= vars["SKIP_HARDWARE_REQUIREMENT_CHECK"]
63         if SKIP_HARDWARE_REQUIREMENT_CHECK == "":
64             raise ValueError, "SKIP_HARDWARE_REQUIREMENT_CHECK"
65
66         NETWORK_SETTINGS= vars["NETWORK_SETTINGS"]
67         if NETWORK_SETTINGS == "":
68             raise ValueError, "NETWORK_SETTINGS"
69
70         WAS_NODE_ID_IN_CONF= vars["WAS_NODE_ID_IN_CONF"]
71         if WAS_NODE_ID_IN_CONF == "":
72             raise ValueError, "WAS_NODE_ID_IN_CONF"
73
74         WAS_NODE_KEY_IN_CONF= vars["WAS_NODE_KEY_IN_CONF"]
75         if WAS_NODE_KEY_IN_CONF == "":
76             raise ValueError, "WAS_NODE_KEY_IN_CONF"
77
78     except KeyError, var:
79         raise BootManagerException, "Missing variable in vars: %s\n" % var
80     except ValueError, var:
81         raise BootManagerException, "Variable in vars, shouldn't be: %s\n" % var
82
83     details= BootAPI.call_api_function( vars, "BootGetNodeDetails", () )
84
85     vars['BOOT_STATE']= details['boot_state']
86     vars['NODE_MODEL']= string.strip(details['model'])
87     vars['NODE_SESSION']= details['session']
88     
89     log.write( "Successfully retrieved node record.\n" )
90     log.write( "Current boot state: %s\n" % vars['BOOT_STATE'] )
91     log.write( "Node make/model: %s\n" % vars['NODE_MODEL'] )
92     
93     # parse in the model options from the node_model string
94     model= vars['NODE_MODEL']
95     modelinfo = string.split(model,'/')
96     options= 0
97     for mi in modelinfo:
98         info = string.strip(mi)
99         info = info.lower()
100         options = options | modeloptions.get(info,0)
101
102     print "node model options = %d" % options
103     vars['NODE_MODEL_OPTIONS']=options
104
105     # if the end of NODE_MODEL string contains the minhw string, skip hardware
106     # requirement checks (overrides configuration)
107     if options & MINHW_OPT:
108         vars['SKIP_HARDWARE_REQUIREMENT_CHECK']=1
109         log.write( "node model indicates override to hardware requirements.\n" )
110
111     # this contains all the node networks, for now, we are only concerned
112     # in the primary network
113     node_networks= details['networks']
114     got_primary= 0
115     for network in node_networks:
116         if network['is_primary'] == 1:
117             got_primary= 1
118             break
119
120     if not got_primary:
121         raise BootManagerException, "Node did not have a primary network."
122     
123     log.write( "Primary network as returned from PLC: %s\n" % str(network) )
124
125     # if we got this far, the ip on the floppy and the ip in plc match,
126     # make the rest of the PLC information match whats on the floppy
127     network['method']= NETWORK_SETTINGS['method']
128
129     # only nodes that have the node_id specified directly in the configuration
130     # file can change their mac address
131     if WAS_NODE_ID_IN_CONF == 1:
132         network['mac']= NETWORK_SETTINGS['mac']
133         
134     network['gateway']= NETWORK_SETTINGS['gateway']
135     network['network']= NETWORK_SETTINGS['network']
136     network['broadcast']= NETWORK_SETTINGS['broadcast']
137     network['netmask']= NETWORK_SETTINGS['netmask']
138     network['dns1']= NETWORK_SETTINGS['dns1']
139     network['dns2']= NETWORK_SETTINGS['dns2']
140     
141     log.write( "Updating network settings at PLC to match floppy " \
142                "(except for node ip).\n" )
143     update_vals= {}
144     update_vals['primary_network']= network
145     BootAPI.call_api_function( vars, "BootUpdateNode", (update_vals,) )
146     
147     return 1