b419a905bb1b2a3f7db60099f8f15990f9f96664
[bootmanager.git] / source / steps / InitializeBootManager.py
1 #!/usr/bin/python
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     # In case we are booted with a kernel that does not have the
74     # device mapper code compiled into the kernel.
75     if not os.path.exists("/dev/mapper"):
76         log.write( "Loading support for LVM\n" )
77         utils.sysexec_noerr( "modprobe dm_mod", log )
78
79     # for anything that needs to know we are running under the boot cd and
80     # not the runtime os
81     os.environ['PL_BOOTCD']= "1"
82         
83     return 1
84
85
86
87 def __check_boot_version( vars, log ):
88     """
89     identify which version of the boot os we are running on, and whether
90     or not we can run at all on the given version. later, this will be
91     used to identify extra packages to download to enable the boot manager
92     to run on any supported version.
93
94     2.x cds have the version file in /usr/bootme/ID, which looked like:
95     'PlanetLab BootCD v2.0.3'
96
97     3.x cds have the version file in /pl_version, which lookes like:
98     'PlanetLab BootCD 3.0-beta0.3'
99
100     All current known version strings that we support:
101     PlanetLab BootCD 3.0
102     PlanetLab BootCD 3.0-beta0.1
103     PlanetLab BootCD 3.0-beta0.3
104     PlanetLab BootCD v2.0
105     PlanetLab BootCD v2.0.1
106     PlanetLab BootCD v2.0.2
107     PlanetLab BootCD v2.0.3
108
109     Returns 1 if the boot os version is identified and will work
110     to run the boot manager. Two class variables are set:
111     BOOT_OS_MAJOR_VERSION
112     BOOT_OS_MINOR_VERSION
113     version strings with three parts parts to the version ignore the
114     middle number (so 2.0.3 is major 2, minor 3)
115
116     Returns 0 if the boot os is insufficient to run the boot manager
117     """
118
119     try:
120         # check for a 3.x version first
121         version_file= file(BOOT_VERSION_3X_FILE,'r')
122         full_version= string.strip(version_file.read())
123         version_file.close()
124
125         version_parts= string.split(full_version)
126         version= version_parts[-1]
127
128         version_numbers= string.split(version,".")
129         if len(version_numbers) == 2:
130             BOOT_OS_MAJOR_VERSION= int(version_numbers[0])
131             BOOT_OS_MINOR_VERSION= int(version_numbers[1])
132         else:
133             # for 3.x cds, if there are more than two parts
134             # separated by a ., its one of the beta cds.
135             # hardcode as a 3.0 cd
136             BOOT_OS_MAJOR_VERSION= 3
137             BOOT_OS_MINOR_VERSION= 0
138
139         vars['BOOT_CD_VERSION']= (BOOT_OS_MAJOR_VERSION,BOOT_OS_MINOR_VERSION)
140         
141         if (BOOT_OS_MAJOR_VERSION,BOOT_OS_MINOR_VERSION) >= \
142                MINIMUM_BOOT_VERSION:
143             return 1
144
145     except IOError, e:
146         pass
147     except IndexError, e:
148         pass
149     except TypeError, e:
150         pass
151
152
153     try:
154         # check for a 2.x version first
155         version_file= file(BOOT_VERSION_2X_FILE,'r')
156         full_version= string.strip(version_file.read())
157         version_file.close()
158
159         version_parts= string.split(full_version)
160         version= version_parts[-1]
161         if version[0] == 'v':
162             version= version[1:]
163
164         version_numbers= string.split(version,".")
165         if len(version_numbers) == 2:
166             BOOT_OS_MAJOR_VERSION= int(version_numbers[0])
167             BOOT_OS_MINOR_VERSION= int(version_numbers[1])
168         else:
169             BOOT_OS_MAJOR_VERSION= int(version_numbers[0])
170             BOOT_OS_MINOR_VERSION= int(version_numbers[2])
171
172         vars['BOOT_CD_VERSION']= (BOOT_OS_MAJOR_VERSION,BOOT_OS_MINOR_VERSION)
173
174         if (BOOT_OS_MAJOR_VERSION,BOOT_OS_MINOR_VERSION) >= \
175            MINIMUM_BOOT_VERSION:
176             return 1
177
178     except IOError, e:
179         pass
180     except IndexError, e:
181         pass
182     except TypeError, e:
183         pass
184
185
186     return 0
187
188
189
190 def _create_cciss_dev_entries():
191     def mkccissnod(dev,node):
192         dev = dev + " b 104 %d" % (node)
193         cmd = "mknod /dev/cciss/%s" %dev
194         utils.sysexec_noerr(cmd)
195         node = node + 1
196         return node
197
198     node = 0
199     for i in range(0,16):
200         dev = "c0d%d" % i
201         node = mkccissnod(dev,node)
202         for j in range(1,16):
203             subdev = dev + "p%d" % j
204             node = mkccissnod(subdev,node)