upgrade mode was not working; CheckForNewDisks was erroneously taking the disk as...
[bootmanager.git] / source / steps / CheckForNewDisks.py
index 67e1792..38d8464 100644 (file)
+#!/usr/bin/python
+#
+# Copyright (c) 2003 Intel Corporation
+# All rights reserved.
+#
+# Copyright (c) 2004-2006 The Trustees of Princeton University
+# All rights reserved.
+
 import string
 
 import InstallPartitionDisks
 from Exceptions import *
 import string
 
 import InstallPartitionDisks
 from Exceptions import *
-from systeminfo import systeminfo
-import compatibility
+import systeminfo
 import utils
 import os
 
 import utils
 import os
 
+import ModelOptions
+
 
 
-def Run( vars, log ):
+def Run(vars, log):
     """
     Find any new large block devices we can add to the vservers volume group
     
     Expect the following variables to be set:
     SYSIMG_PATH          the path where the system image will be mounted
     """
     Find any new large block devices we can add to the vservers volume group
     
     Expect the following variables to be set:
     SYSIMG_PATH          the path where the system image will be mounted
-    BOOT_CD_VERSION          A tuple of the current bootcd version
     MINIMUM_DISK_SIZE       any disks smaller than this size, in GB, are not used
     MINIMUM_DISK_SIZE       any disks smaller than this size, in GB, are not used
+    NODE_MODEL_OPTIONS   the node's model options
     
     Set the following variables upon successfully running:
     ROOT_MOUNTED             the node root file system is mounted
     """
 
     
     Set the following variables upon successfully running:
     ROOT_MOUNTED             the node root file system is mounted
     """
 
-    log.write( "\n\nStep: Checking for unused disks to add to LVM.\n" )
+    log.write("\n\nStep: Checking for unused disks to add to LVM.\n")
 
     # make sure we have the variables we need
     try:
 
     # make sure we have the variables we need
     try:
-        BOOT_CD_VERSION= vars["BOOT_CD_VERSION"]
-        if BOOT_CD_VERSION == "":
-            raise ValueError, "BOOT_CD_VERSION"
-
-        SYSIMG_PATH= vars["SYSIMG_PATH"]
+        SYSIMG_PATH = vars["SYSIMG_PATH"]
         if SYSIMG_PATH == "":
         if SYSIMG_PATH == "":
-            raise ValueError, "SYSIMG_PATH"
+            raise ValueError("SYSIMG_PATH")
 
 
-        MINIMUM_DISK_SIZE= int(vars["MINIMUM_DISK_SIZE"])
-        
-    except KeyError, var:
-        raise BootManagerException, "Missing variable in vars: %s\n" % var
-    except ValueError, var:
-        raise BootManagerException, "Variable in vars, shouldn't be: %s\n" % var
+        MINIMUM_DISK_SIZE = int(vars["MINIMUM_DISK_SIZE"])
 
 
-    sysinfo= systeminfo()
+        PARTITIONS = vars["PARTITIONS"]
+        if PARTITIONS == None:
+            raise ValueError("PARTITIONS")
+        
+        NODE_MODEL_OPTIONS = vars["NODE_MODEL_OPTIONS"]
+    except KeyError as var:
+        raise BootManagerException("Missing variable in vars: {}\n".format(var))
+    except ValueError as var:
+        raise BootManagerException("Variable in vars, shouldn't be: {}\n".format(var))
 
 
-    all_devices= sysinfo.get_block_device_list()
+    devices_dict = systeminfo.get_block_devices_dict(vars, log)
     
     
-    # find out if there are unused disks in all_devices that are greater
-    # than old cds need extra utilities to run lvm
-    if BOOT_CD_VERSION[0] == 2:
-        compatibility.setup_lvm_2x_cd( vars, log )
-        
     # will contain the new devices to add to the volume group
     # will contain the new devices to add to the volume group
-    new_devices= []
+    new_devices = []
 
     # total amount of new space in gb
 
     # total amount of new space in gb
-    extended_gb_size= 0
+    extended_gb_size = 0
     
     
-    for device in all_devices.keys():
+    for device, details in devices_dict.items():
 
 
-        (major,minor,blocks,gb_size,readonly)= all_devices[device]
+        (major, minor, blocks, gb_size, readonly) = details
 
         if device[:14] == "/dev/planetlab":
 
         if device[:14] == "/dev/planetlab":
-            log.write( "Skipping device %s in volume group.\n" % device )
+            log.write("Skipping device {} in volume group.\n".format(device))
             continue
 
         if readonly:
             continue
 
         if readonly:
-            log.write( "Skipping read only device %s\n" % device )
+            log.write("Skipping read only device {}\n".format(device))
             continue
 
         if gb_size < MINIMUM_DISK_SIZE:
             continue
 
         if gb_size < MINIMUM_DISK_SIZE:
-            log.write( "Skipping too small device %s (%4.2f)\n" %
-                       (device,gb_size) )
+            log.write("Skipping too small device {} ({:4.2f}) Gb\n"\
+                      .format(device, gb_size))
             continue
 
             continue
 
-        log.write( "Checking device %s to see if it is part " \
-                   "of the volume group.\n" % device )
+        log.write("Checking device {} to see if it is part " \
+                   "of the volume group.\n".format(device))
+
+        # Thierry - June 2015
+        # when introducing the 'upgrade' verb, we ran into the situation
+        # where 'pvdisplay' at this point displays e.g. /dev/sda, instead
+        # of /dev/sda1
+        # we thus consider that if either of these is known, then
+        # the disk is already part of LVM
+        first_partition = InstallPartitionDisks.get_partition_path_from_device(device, vars, log)
+        probe_first_part = "pvdisplay {} | grep -q planetlab".format(first_partition)
+        probe_device     = "pvdisplay {} | grep -q planetlab".format(device)
+        already_added = utils.sysexec_noerr(probe_first_part, log, shell=True) \
+                     or utils.sysexec_noerr(probe_device, log, shell=True) 
 
 
-        # this is the lvm partition, if it exists on that device
-        lvm_partition= "%s1" % device
-        already_added= utils.sysexec_noerr( "pvdisplay %s | grep -q 'planetlab'" %
-                                            lvm_partition )
-        
         if already_added:
         if already_added:
-            log.write( "It appears %s is part of the volume group, continuing.\n" %
-                       device )
+            log.write("It appears {} is part of the volume group, continuing.\n"\
+                      .format(device))
             continue
 
         # just to be extra paranoid, ignore the device if it already has
         # an lvm partition on it (new disks won't have this, and that is
         # what this code is for, so it should be ok).
             continue
 
         # just to be extra paranoid, ignore the device if it already has
         # an lvm partition on it (new disks won't have this, and that is
         # what this code is for, so it should be ok).
-        has_lvm= utils.sysexec_noerr( "sfdisk -l %s | grep -q 'Linux LVM'" %
-                                      device )
+        cmd = "parted --script --list {} | grep -q lvm$".format(device)
+        has_lvm = utils.sysexec_noerr(cmd, log, shell=True)
         if has_lvm:
         if has_lvm:
-            log.write( "It appears %s has/had lvm already setup on "\
-                       "it, continuing.\n" % device )
-            continue
+            log.write("It appears {} has lvm already setup on it.\n".format(device))
+            paranoid = False
+            if paranoid:
+                log.write("Too paranoid to add {} to vservers lvm.\n".format(device))
+                continue
         
         
+        if not InstallPartitionDisks.single_partition_device(device, vars, log):
+            log.write("Unable to partition {}, not using it.\n".format(device))
+            continue
 
 
-        log.write( "Attempting to add %s to the volume group\n" % device )
+        log.write("Successfully partitioned {}\n".format(device))
 
 
-        if not InstallPartitionDisks.single_partition_device( device, vars, log ):
-            log.write( "Unable to partition %s, not using it.\n" % device )
+        if NODE_MODEL_OPTIONS & ModelOptions.RAWDISK:
+            log.write("Running on a raw disk node, not using it.\n")
             continue
 
             continue
 
-        log.write( "Successfully initialized %s\n" % device )
+        part_path = InstallPartitionDisks.get_partition_path_from_device(device,
+                                                                         vars, log)
 
 
-        part_path= InstallPartitionDisks.get_partition_path_from_device( device,
-                                                                         vars, log )
-        if not InstallPartitionDisks.create_lvm_physical_volume( part_path,
-                                                                 vars, log ):
-            log.write( "Unable to create lvm physical volume %s, not using it.\n" %
-                       part_path )
+        log.write("Attempting to add {} to the volume group\n".format(device))
+
+        if not InstallPartitionDisks.create_lvm_physical_volume(part_path,
+                                                                 vars, log):
+            log.write("Unable to create lvm physical volume {}, not using it.\n"\
+                      .format(part_path))
             continue
 
             continue
 
-        log.write( "Adding %s to list of devices to add to " \
-                   "planetlab volume group.\n" % device )
+        log.write("Adding {} to list of devices to add to "
+                   "planetlab volume group.\n".format(device))
 
 
-        extended_gb_size= extended_gb_size + gb_size
-        new_devices.append( part_path )
+        extended_gb_size = extended_gb_size + gb_size
+        new_devices.append(part_path)
         
 
     if len(new_devices) > 0:
 
         
 
     if len(new_devices) > 0:
 
-        log.write( "Extending planetlab volume group.\n" )
+        log.write("Extending planetlab volume group.\n")
         
         
-        log.write( "Unmounting disks.\n" )
+        log.write("Unmounting disks.\n")
         try:
             # backwards compat, though, we should never hit this case post PL 3.2
         try:
             # backwards compat, though, we should never hit this case post PL 3.2
-            os.stat("%s/rcfs/taskclass"%SYSIMG_PATH)
-            utils.sysexec_noerr( "chroot %s umount /rcfs" % SYSIMG_PATH, log )
-        except OSError, e:
+            os.stat("{}/rcfs/taskclass".format(SYSIMG_PATH))
+            utils.sysexec_chroot_noerr(SYSIMG_PATH, "umount /rcfs", log)
+        except OSError as e:
             pass
 
         # umount in order to extend disk size
             pass
 
         # umount in order to extend disk size
-        utils.sysexec_noerr( "umount %s/proc" % SYSIMG_PATH, log )
-        utils.sysexec_noerr( "umount %s/vservers" % SYSIMG_PATH, log )
-        utils.sysexec_noerr( "umount %s" % SYSIMG_PATH, log )
-        utils.sysexec( "vgchange -an", log )
+        utils.sysexec_noerr("umount {}/proc".format(SYSIMG_PATH), log)
+        utils.sysexec_noerr("umount {}/vservers".format(SYSIMG_PATH), log)
+        utils.sysexec_noerr("umount {}".format(SYSIMG_PATH), log)
+        utils.sysexec("vgchange -an", log)
         
         
-        vars['ROOT_MOUNTED']= 0
-
-        if not utils.sysexec_noerr( "vgextend planetlab %s" %
-                                    string.join(new_devices," "), log ):
-            log.write( "Failed to add physical volumes %s to " \
-                       "volume group, continuing.\n" % string.join(new_devices," "))
-            return 1
+        vars['ROOT_MOUNTED'] = 0
+
+        while True:
+            cmd = "vgextend planetlab {}".format(" ".join(new_devices))
+            if not utils.sysexec_noerr(cmd, log):
+                log.write("Failed to add physical volumes {} to "\
+                           "volume group, continuing.\n".format(" ".join(new_devices)))
+                res = 1
+                break
+            
+            # now, get the number of unused extents, and extend the vserver
+            # logical volume by that much.
+            remaining_extents = \
+               InstallPartitionDisks.get_remaining_extents_on_vg(vars, log)
+
+            log.write("Extending vservers logical volume.\n")
+            utils.sysexec("vgchange -ay", log)
+            cmd = "lvextend -l +{} {}".format(remaining_extents, PARTITIONS["vservers"])
+            if not utils.sysexec_noerr(cmd, log):
+                log.write("Failed to extend vservers logical volume, continuing\n")
+                res = 1
+                break
+
+            log.write("making the ext filesystem match new logical volume size.\n")
+
+            vars['ROOT_MOUNTED'] = 1
+            cmd = "mount {} {}".format(PARTITIONS["root"], SYSIMG_PATH)
+            utils.sysexec_noerr(cmd, log)
+            cmd = "mount {} {}/vservers".format(PARTITIONS["vservers"], SYSIMG_PATH)
+            utils.sysexec_noerr(cmd, log)
+            cmd = "resize2fs {}".format(PARTITIONS["vservers"])
+            resize = utils.sysexec_noerr(cmd,log)
+            utils.sysexec_noerr("umount {}/vservers".format(SYSIMG_PATH), log)
+            utils.sysexec_noerr("umount {}".format(SYSIMG_PATH), log)
+            vars['ROOT_MOUNTED'] = 0
+
+            utils.sysexec("vgchange -an", log)
+
+            if not resize:
+                log.write("Failed to resize vservers partition, continuing.\n")
+                res = 1
+                break
+            else:
+                log.write("Extended vservers partition by {:4.2f} Gb\n"\
+                          .format(extended_gb_size))
+                res = 1
+                break
 
 
-        # now, get the number of unused extents, and extend the vserver
-        # logical volume by that much.
-        remaining_extents= \
-               InstallPartitionDisks.get_remaining_extents_on_vg( vars, log )
-
-        log.write( "Extending vservers logical volume.\n" )
-        
-        # make all LVMs known again for lvextend/resize2fs to work
-        utils.sysexec( "vgchange -ay", log )
-
-        if not utils.sysexec_noerr("lvextend -l +%s /dev/planetlab/vservers" %
-                                   remaining_extents, log):
-            log.write( "Failed to extend vservers logical volume, continuing\n" )
-            return 1
-
-        log.write( "making the ext3 filesystem match new logical volume size.\n" )
-        if BOOT_CD_VERSION[0] == 2:
-            resize = utils.sysexec_noerr("resize2fs /dev/planetlab/vservers",log)
-        elif BOOT_CD_VERSION[0] == 3:
-            vars['ROOT_MOUNTED']= 1
-            utils.sysexec_noerr( "mount /dev/planetlab/root %s" % SYSIMG_PATH, log )
-            utils.sysexec_noerr( "mount /dev/planetlab/vservers %s/vservers" % SYSIMG_PATH, log )
-            resize = utils.sysexec_noerr("ext2online /dev/planetlab/vservers",log)
-            utils.sysexec_noerr( "umount %s/vservers" % SYSIMG_PATH, log )
-            utils.sysexec_noerr( "umount %s" % SYSIMG_PATH, log )
-            vars['ROOT_MOUNTED']= 0
-
-        if not resize:
-            log.write( "Failed to resize vservers partition, continuing\n" )
-            return 1
-        else:
-            log.write( "Succesfully extended vservers partition by %4.2f GB\n" %
-                       extended_gb_size )
-            return 1
     else:
     else:
-        log.write( "No new disk devices to add to volume group.\n" )
-        return 1
+        log.write("No new disk devices to add to volume group.\n")
+        res = 1
+
+    return res