Cleaning out rcfs/ckrm related operations in a backward compatible manner.
[bootmanager.git] / source / steps / CheckForNewDisks.py
1 import string
2
3 import InstallPartitionDisks
4 from Exceptions import *
5 from systeminfo import systeminfo
6 import compatibility
7 import utils
8 import os
9
10
11 def Run( vars, log ):
12     """
13     Find any new large block devices we can add to the vservers volume group
14     
15     Expect the following variables to be set:
16     SYSIMG_PATH          the path where the system image will be mounted
17     BOOT_CD_VERSION          A tuple of the current bootcd version
18     MINIMUM_DISK_SIZE       any disks smaller than this size, in GB, are not used
19     
20     Set the following variables upon successfully running:
21     ROOT_MOUNTED             the node root file system is mounted
22     """
23
24     log.write( "\n\nStep: Checking for unused disks to add to LVM.\n" )
25
26     # make sure we have the variables we need
27     try:
28         BOOT_CD_VERSION= vars["BOOT_CD_VERSION"]
29         if BOOT_CD_VERSION == "":
30             raise ValueError, "BOOT_CD_VERSION"
31
32         SYSIMG_PATH= vars["SYSIMG_PATH"]
33         if SYSIMG_PATH == "":
34             raise ValueError, "SYSIMG_PATH"
35
36         MINIMUM_DISK_SIZE= int(vars["MINIMUM_DISK_SIZE"])
37         
38     except KeyError, var:
39         raise BootManagerException, "Missing variable in vars: %s\n" % var
40     except ValueError, var:
41         raise BootManagerException, "Variable in vars, shouldn't be: %s\n" % var
42
43     sysinfo= systeminfo()
44
45     all_devices= sysinfo.get_block_device_list()
46     
47     # find out if there are unused disks in all_devices that are greater
48     # than old cds need extra utilities to run lvm
49     if BOOT_CD_VERSION[0] == 2:
50         compatibility.setup_lvm_2x_cd( vars, log )
51         
52     # will contain the new devices to add to the volume group
53     new_devices= []
54
55     # total amount of new space in gb
56     extended_gb_size= 0
57     
58     for device in all_devices.keys():
59
60         (major,minor,blocks,gb_size,readonly)= all_devices[device]
61
62         if device[:14] == "/dev/planetlab":
63             log.write( "Skipping device %s in volume group.\n" % device )
64             continue
65
66         if readonly:
67             log.write( "Skipping read only device %s\n" % device )
68             continue
69
70         if gb_size < MINIMUM_DISK_SIZE:
71             log.write( "Skipping too small device %s (%4.2f)\n" %
72                        (device,gb_size) )
73             continue
74
75         log.write( "Checking device %s to see if it is part " \
76                    "of the volume group.\n" % device )
77
78         # this is the lvm partition, if it exists on that device
79         lvm_partition= "%s1" % device
80         already_added= utils.sysexec_noerr( "pvdisplay %s | grep -q 'planetlab'" %
81                                             lvm_partition )
82         
83         if already_added:
84             log.write( "It appears %s is part of the volume group, continuing.\n" %
85                        device )
86             continue
87
88         # just to be extra paranoid, ignore the device if it already has
89         # an lvm partition on it (new disks won't have this, and that is
90         # what this code is for, so it should be ok).
91         has_lvm= utils.sysexec_noerr( "sfdisk -l %s | grep -q 'Linux LVM'" %
92                                       device )
93         if has_lvm:
94             log.write( "It appears %s has/had lvm already setup on "\
95                        "it, continuing.\n" % device )
96             continue
97         
98
99         log.write( "Attempting to add %s to the volume group\n" % device )
100
101         if not InstallPartitionDisks.single_partition_device( device, vars, log ):
102             log.write( "Unable to partition %s, not using it.\n" % device )
103             continue
104
105         log.write( "Successfully initialized %s\n" % device )
106
107         part_path= InstallPartitionDisks.get_partition_path_from_device( device,
108                                                                          vars, log )
109         if not InstallPartitionDisks.create_lvm_physical_volume( part_path,
110                                                                  vars, log ):
111             log.write( "Unable to create lvm physical volume %s, not using it.\n" %
112                        part_path )
113             continue
114
115         log.write( "Adding %s to list of devices to add to " \
116                    "planetlab volume group.\n" % device )
117
118         extended_gb_size= extended_gb_size + gb_size
119         new_devices.append( part_path )
120         
121
122     if len(new_devices) > 0:
123
124         log.write( "Extending planetlab volume group.\n" )
125         
126         log.write( "Unmounting disks.\n" )
127         try:
128             # backwards compat, though, we should never hit this case post PL 3.2
129             os.stat("%s/rcfs/taskclass"%SYSIMG_PATH)
130             utils.sysexec_noerr( "chroot %s umount /rcfs" % SYSIMG_PATH, log )
131         except OSError, e:
132             pass
133
134         utils.sysexec_noerr( "umount /dev/planetlab/vservers", log )
135         utils.sysexec_noerr( "umount /dev/planetlab/root", log )
136         utils.sysexec( "vgchange -an", log )
137         
138         vars['ROOT_MOUNTED']= 0
139
140         if not utils.sysexec_noerr( "vgextend planetlab %s" %
141                                     string.join(new_devices," "), log ):
142             log.write( "Failed to add physical volumes %s to " \
143                        "volume group, continuing.\n" % string.join(new_devices," "))
144             return 1
145
146         # now, get the number of unused extents, and extend the vserver
147         # logical volume by that much.
148         remaining_extents= \
149                InstallPartitionDisks.get_remaining_extents_on_vg( vars, log )
150
151         log.write( "Extending vservers logical volume.\n" )
152         
153         if not utils.sysexec_noerr("lvextend -l +%s /dev/planetlab/vservers" %
154                                    remaining_extents, log):
155             log.write( "Failed to extend vservers logical volume, continuing\n" )
156             return 1
157
158         log.write( "making the ext3 filesystem match new logical volume size.\n" )
159         if not utils.sysexec_noerr("resize2fs /dev/planetlab/vservers",log):
160             log.write( "Failed to make ext3 file system match, continuing\n" )
161             return 1
162             
163         log.write( "Succesfully extended vservers partition by %4.2f GB\n" %
164                    extended_gb_size )
165     else:
166         log.write( "No new disk devices to add to volume group.\n" )
167
168     return 1