c98f960bf44cefad9737828a120ab743d66534df
[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     # Default model option.  Required in case we go into debug mode
43     # before we successfully called GetAndUpdateNodeDetails().
44     vars["NODE_MODEL_OPTIONS"] = vars.get("NODE_MODEL_OPTIONS",0)
45
46     # define the basic partition paths
47     PARTITIONS= {}
48     PARTITIONS["root"]= "/dev/planetlab/root"
49     PARTITIONS["swap"]= "/dev/planetlab/swap"
50     PARTITIONS["vservers"]= "/dev/planetlab/vservers"
51     # Linux 2.6 mounts LVM with device mapper
52     PARTITIONS["mapper-root"]= "/dev/mapper/planetlab-root"
53     PARTITIONS["mapper-swap"]= "/dev/mapper/planetlab-swap"
54     PARTITIONS["mapper-vservers"]= "/dev/mapper/planetlab-vservers"
55     vars["PARTITIONS"]= PARTITIONS
56
57     log.write( "Opening connection to API server\n" )
58     try:
59         api_inst= xmlrpclib.Server( vars['BOOT_API_SERVER'], verbose=0 )
60     except KeyError, e:
61         raise BootManagerException, \
62               "configuration file does not specify API server URL"
63
64     vars['API_SERVER_INST']= api_inst
65
66     if not __check_boot_version( vars, log ):
67         raise BootManagerException, \
68               "Boot CD version insufficient to run the Boot Manager"
69     else:
70         log.write( "Running on boot cd version: %s\n" %
71                    str(vars['BOOT_CD_VERSION']) )
72
73     BOOT_CD_VERSION= vars['BOOT_CD_VERSION']
74     
75     # In case we are booted with a kernel that does not have the
76     # device mapper code compiled into the kernel.
77     if not os.path.exists("/dev/mapper"):
78         log.write( "Loading support for LVM\n" )
79         utils.sysexec_noerr( "modprobe dm_mod", log )
80
81     # for anything that needs to know we are running under the boot cd and
82     # not the runtime os
83     os.environ['PL_BOOTCD']= "1"
84         
85     return 1
86
87
88
89 def __check_boot_version( vars, log ):
90     """
91     identify which version of the boot os we are running on, and whether
92     or not we can run at all on the given version. later, this will be
93     used to identify extra packages to download to enable the boot manager
94     to run on any supported version.
95
96     2.x cds have the version file in /usr/bootme/ID, which looked like:
97     'PlanetLab BootCD v2.0.3'
98
99     3.x cds have the version file in /pl_version, which lookes like:
100     'PlanetLab BootCD 3.0-beta0.3'
101
102     All current known version strings that we support:
103     PlanetLab BootCD 3.0
104     PlanetLab BootCD 3.0-beta0.1
105     PlanetLab BootCD 3.0-beta0.3
106     PlanetLab BootCD v2.0
107     PlanetLab BootCD v2.0.1
108     PlanetLab BootCD v2.0.2
109     PlanetLab BootCD v2.0.3
110
111     Returns 1 if the boot os version is identified and will work
112     to run the boot manager. Two class variables are set:
113     BOOT_OS_MAJOR_VERSION
114     BOOT_OS_MINOR_VERSION
115     version strings with three parts parts to the version ignore the
116     middle number (so 2.0.3 is major 2, minor 3)
117
118     Returns 0 if the boot os is insufficient to run the boot manager
119     """
120
121     try:
122         # check for a 3.x version first
123         version_file= file(BOOT_VERSION_3X_FILE,'r')
124         full_version= string.strip(version_file.read())
125         version_file.close()
126
127         version_parts= string.split(full_version)
128         version= version_parts[-1]
129
130         version_numbers= string.split(version,".")
131         if len(version_numbers) == 2:
132             BOOT_OS_MAJOR_VERSION= int(version_numbers[0])
133             BOOT_OS_MINOR_VERSION= int(version_numbers[1])
134         else:
135             # for 3.x cds, if there are more than two parts
136             # separated by a ., its one of the beta cds.
137             # hardcode as a 3.0 cd
138             BOOT_OS_MAJOR_VERSION= 3
139             BOOT_OS_MINOR_VERSION= 0
140
141         vars['BOOT_CD_VERSION']= (BOOT_OS_MAJOR_VERSION,BOOT_OS_MINOR_VERSION)
142         
143         if (BOOT_OS_MAJOR_VERSION,BOOT_OS_MINOR_VERSION) >= \
144                MINIMUM_BOOT_VERSION:
145             return 1
146
147     except IOError, e:
148         pass
149     except IndexError, e:
150         pass
151     except TypeError, e:
152         pass
153
154
155     try:
156         # check for a 2.x version first
157         version_file= file(BOOT_VERSION_2X_FILE,'r')
158         full_version= string.strip(version_file.read())
159         version_file.close()
160
161         version_parts= string.split(full_version)
162         version= version_parts[-1]
163         if version[0] == 'v':
164             version= version[1:]
165
166         version_numbers= string.split(version,".")
167         if len(version_numbers) == 2:
168             BOOT_OS_MAJOR_VERSION= int(version_numbers[0])
169             BOOT_OS_MINOR_VERSION= int(version_numbers[1])
170         else:
171             BOOT_OS_MAJOR_VERSION= int(version_numbers[0])
172             BOOT_OS_MINOR_VERSION= int(version_numbers[2])
173
174         vars['BOOT_CD_VERSION']= (BOOT_OS_MAJOR_VERSION,BOOT_OS_MINOR_VERSION)
175
176         if (BOOT_OS_MAJOR_VERSION,BOOT_OS_MINOR_VERSION) >= \
177            MINIMUM_BOOT_VERSION:
178             return 1
179
180     except IOError, e:
181         pass
182     except IndexError, e:
183         pass
184     except TypeError, e:
185         pass
186
187
188     return 0
189
190
191
192 def _create_cciss_dev_entries():
193     def mkccissnod(dev,node):
194         dev = dev + " b 104 %d" % (node)
195         cmd = "mknod /dev/cciss/%s" %dev
196         utils.sysexec_noerr(cmd)
197         node = node + 1
198         return node
199
200     node = 0
201     for i in range(0,16):
202         dev = "c0d%d" % i
203         node = mkccissnod(dev,node)
204         for j in range(1,16):
205             subdev = dev + "p%d" % j
206             node = mkccissnod(subdev,node)