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