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