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