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