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