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