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