Programmatic version of creating the cciss devices.
[bootmanager.git] / source / steps / InitializeBootManager.py
1 import os
2 import xmlrpclib
3 import socket
4 import string
5
6 from Exceptions import *
7 import utils
8
9
10 # locations of boot os version files
11 BOOT_VERSION_2X_FILE='/usr/bootme/ID'
12 BOOT_VERSION_3X_FILE='/pl_version'
13
14 # minimium version of the boot os we need to run, as a (major,minor) tuple
15 MINIMUM_BOOT_VERSION= (2,0)
16
17 # minimum version of python required to run the boot manager
18 MINIMUM_PYTHON_VERSION= (2,2,0)
19
20
21 def Run( vars, log ):
22     """
23     Setup the boot manager so it can run, do any extra necessary
24     hardware setup (to fix old cd problems)
25
26     Sets the following variables:
27     BOOT_CD_VERSION           A two number tuple of the boot cd version
28     """
29
30     log.write( "\n\nStep: Initializing the BootManager.\n" )
31
32     
33     log.write( "Opening connection to API server\n" )
34     try:
35         api_inst= xmlrpclib.Server( vars['BOOT_API_SERVER'], verbose=0 )
36     except KeyError, e:
37         raise BootManagerException, \
38               "configuration file does not specify API server URL"
39
40     vars['API_SERVER_INST']= api_inst
41
42     if not __check_boot_version( vars, log ):
43         raise BootManagerException, \
44               "Boot CD version insufficient to run the Boot Manager"
45     else:
46         log.write( "Running on boot cd version: %s\n" %
47                    str(vars['BOOT_CD_VERSION']) )
48
49     BOOT_CD_VERSION= vars['BOOT_CD_VERSION']
50     
51     # old cds need extra modules loaded for compaq smart array
52     if BOOT_CD_VERSION[0] == 2:
53
54         has_smartarray= utils.sysexec_noerr(
55             'lspci | egrep "0e11:b178|0e11:4070|0e11:4080|0e11:4082|0e11:4083"')
56         
57         if has_smartarray:
58             log.write( "Loading support for Compaq smart array\n" )
59             utils.sysexec_noerr( "modprobe cciss", log )
60             _create_cciss_dev_entries()
61             
62
63         has_fusion= utils.sysexec_noerr('lspci | egrep "1000:0030"')
64         
65         if has_fusion:
66             log.write( "Loading support for Fusion MPT SCSI controllers\n" )
67             utils.sysexec_noerr( "modprobe mptscsih", log )
68
69     # for anything that needs to know we are running under the boot cd and
70     # not the runtime os
71     os.environ['PL_BOOTCD']= "1"
72         
73     return 1
74
75
76
77 def __check_boot_version( vars, log ):
78     """
79     identify which version of the boot os we are running on, and whether
80     or not we can run at all on the given version. later, this will be
81     used to identify extra packages to download to enable the boot manager
82     to run on any supported version.
83
84     2.x cds have the version file in /usr/bootme/ID, which looked like:
85     'PlanetLab BootCD v2.0.3'
86
87     3.x cds have the version file in /pl_version, which lookes like:
88     'PlanetLab BootCD 3.0-beta0.3'
89
90     All current known version strings that we support:
91     PlanetLab BootCD 3.0
92     PlanetLab BootCD 3.0-beta0.1
93     PlanetLab BootCD 3.0-beta0.3
94     PlanetLab BootCD v2.0
95     PlanetLab BootCD v2.0.1
96     PlanetLab BootCD v2.0.2
97     PlanetLab BootCD v2.0.3
98
99     Returns 1 if the boot os version is identified and will work
100     to run the boot manager. Two class variables are set:
101     BOOT_OS_MAJOR_VERSION
102     BOOT_OS_MINOR_VERSION
103     version strings with three parts parts to the version ignore the
104     middle number (so 2.0.3 is major 2, minor 3)
105
106     Returns 0 if the boot os is insufficient to run the boot manager
107     """
108
109     try:
110         # check for a 3.x version first
111         version_file= file(BOOT_VERSION_3X_FILE,'r')
112         full_version= string.strip(version_file.read())
113         version_file.close()
114
115         version_parts= string.split(full_version)
116         version= version_parts[-1]
117
118         version_numbers= string.split(version,".")
119         if len(version_numbers) == 2:
120             BOOT_OS_MAJOR_VERSION= int(version_numbers[0])
121             BOOT_OS_MINOR_VERSION= int(version_numbers[1])
122         else:
123             # for 3.x cds, if there are more than two parts
124             # separated by a ., its one of the beta cds.
125             # hardcode as a 3.0 cd
126             BOOT_OS_MAJOR_VERSION= 3
127             BOOT_OS_MINOR_VERSION= 0
128
129         vars['BOOT_CD_VERSION']= (BOOT_OS_MAJOR_VERSION,BOOT_OS_MINOR_VERSION)
130         
131         if (BOOT_OS_MAJOR_VERSION,BOOT_OS_MINOR_VERSION) >= \
132                MINIMUM_BOOT_VERSION:
133             return 1
134
135     except IOError, e:
136         pass
137     except IndexError, e:
138         pass
139     except TypeError, e:
140         pass
141
142
143     try:
144         # check for a 2.x version first
145         version_file= file(BOOT_VERSION_2X_FILE,'r')
146         full_version= string.strip(version_file.read())
147         version_file.close()
148
149         version_parts= string.split(full_version)
150         version= version_parts[-1]
151         if version[0] == 'v':
152             version= version[1:]
153
154         version_numbers= string.split(version,".")
155         if len(version_numbers) == 2:
156             BOOT_OS_MAJOR_VERSION= int(version_numbers[0])
157             BOOT_OS_MINOR_VERSION= int(version_numbers[1])
158         else:
159             BOOT_OS_MAJOR_VERSION= int(version_numbers[0])
160             BOOT_OS_MINOR_VERSION= int(version_numbers[2])
161
162         vars['BOOT_CD_VERSION']= (BOOT_OS_MAJOR_VERSION,BOOT_OS_MINOR_VERSION)
163
164         if (BOOT_OS_MAJOR_VERSION,BOOT_OS_MINOR_VERSION) >= \
165            MINIMUM_BOOT_VERSION:
166             return 1
167
168     except IOError, e:
169         pass
170     except IndexError, e:
171         pass
172     except TypeError, e:
173         pass
174
175
176     return 0
177
178
179
180 def _create_cciss_dev_entries():
181     def mkccissnod(dev,node):
182         dev = dev + " b 104 %d" % (node)
183         cmd = "mknod /dev/cciss/%s" %dev
184         utils.sysexec_noerr(cmd)
185         node = node + 1
186         return node
187
188     node = 0
189     for i in range(0,16):
190         dev = "c0d%d" % i
191         node = mkccissnod(dev,node)
192         for j in range(1,16):
193             subdev = dev + "p%d" % j
194             node = mkccissnod(subdev,node)