Ejemplo n.º 1
0
    def doBackup(self, progress_callback, target_disk, backup_partnum,
                 boot_partnum, storage_partnum, logs_partnum,
                 partition_table_type):

        tool = PartitionTool(target_disk)
        boot_part = tool.getPartition(boot_partnum)
        boot_device = partitionDevice(target_disk,
                                      boot_partnum) if boot_part else None
        logs_partition = tool.getPartition(logs_partnum)

        # Check if possible to create new partition layout, increasing the size, using plugin result
        if self.safe2upgrade and logs_partition is None and partition_table_type == constants.PARTITION_GPT:
            if storage_partnum > 0:
                # Get current Volume Group
                rc, out = util.runCmd2(
                    ['pvs', '-o', 'pv_name,vg_name', '--noheadings'],
                    with_stdout=True)
                vgs_list = out.strip().splitlines()
                target_dev = getMajMin(target_disk)
                self.vgs_output = [
                    i for i in vgs_list if diskutil.parentdev_from_devpath(
                        i.strip().split()[0]) == target_dev
                ]
                if self.vgs_output:
                    self.vgs_output = self.vgs_output[0]
                    self.vgs_output = self.vgs_output.split()[1]
                    self.vgs_output = self.vgs_output.strip()
                    # Remove current Volume Group
                    util.runCmd2(['vgremove', '-f', self.vgs_output])
                    # Remove LVM Phisical Volume
                    storage_part = partitionDevice(target_disk,
                                                   storage_partnum)
                    util.runCmd2(['pvremove', storage_part])
                # Delete LVM partition
                tool.deletePartition(storage_partnum)
            # Resize backup partition
            tool.resizePartition(number=backup_partnum,
                                 sizeBytes=constants.backup_size * 2**20)
            # Write partition table
            tool.commit(log=True)

        # format the backup partition:
        backup_partition = partitionDevice(target_disk, backup_partnum)
        try:
            util.mkfs('ext3', backup_partition)
        except Exception as e:
            raise RuntimeError(
                "Backup: Failed to format filesystem on %s: %s" %
                (backup_partition, e))
        progress_callback(10)

        # copy the files across:
        primary_fs = util.TempMount(self.source.root_device,
                                    'primary-',
                                    options=['ro'],
                                    boot_device=boot_device)
        try:
            backup_fs = util.TempMount(backup_partition, 'backup-')
            try:
                just_dirs = ['dev', 'proc', 'lost+found', 'sys']
                top_dirs = os.listdir(primary_fs.mount_point)
                val = 10
                for x in top_dirs:
                    if x in just_dirs:
                        path = os.path.join(backup_fs.mount_point, x)
                        if not os.path.exists(path):
                            os.mkdir(path, 0755)
                    else:
                        cmd = ['cp', '-a'] + \
                              [ os.path.join(primary_fs.mount_point, x) ] + \
                              ['%s/' % backup_fs.mount_point]
                        if util.runCmd2(cmd) != 0:
                            raise RuntimeError, "Backup of %s directory failed" % x
                    val += 90 / len(top_dirs)
                    progress_callback(val)

                if partition_table_type == constants.PARTITION_GPT:
                    # save the GPT table
                    rc, err = util.runCmd2([
                        "sgdisk", "-b",
                        os.path.join(backup_fs.mount_point, '.xen-gpt.bin'),
                        target_disk
                    ],
                                           with_stderr=True)
                    if rc != 0:
                        raise RuntimeError, "Failed to save partition layout: %s" % err
            finally:
                # replace rolling pool upgrade bootloader config
                def replace_config(config_file, destination):
                    src = os.path.join(backup_fs.mount_point,
                                       constants.ROLLING_POOL_DIR, config_file)
                    if os.path.exists(src):
                        util.runCmd2([
                            'cp', '-f', src,
                            os.path.join(backup_fs.mount_point, destination)
                        ])

                map(replace_config,
                    ('efi-grub.cfg', 'grub.cfg', 'menu.lst', 'extlinux.conf'),
                    ('boot/efi/EFI/xenserver/grub.cfg', 'boot/grub',
                     'boot/grub', 'boot'))

                fh = open(
                    os.path.join(backup_fs.mount_point,
                                 '.xen-backup-partition'), 'w')
                fh.close()
                backup_fs.unmount()
        finally:
            primary_fs.unmount()
Ejemplo n.º 2
0
    def prepareTarget(self, progress_callback, primary_disk, target_boot_mode,
                      boot_partnum, primary_partnum, logs_partnum,
                      swap_partnum, storage_partnum, partition_table_type,
                      new_partition_layout):
        """ Modify partition layout prior to installation. """

        if partition_table_type == constants.PARTITION_GPT:
            tool = PartitionTool(primary_disk, partition_table_type)
            logs_partition = tool.getPartition(logs_partnum)

            # Create the new partition layout (5,2,1,4,6,3) after the backup
            # 1 - dom0 partition
            # 2 - backup partition
            # 3 - LVM partition
            # 4 - Boot partition
            # 5 - logs partition
            # 6 - swap partition

            if self.safe2upgrade and logs_partition is None:

                new_partition_layout = True

                # Rename old dom0 and Boot (if any) partitions (10 and 11 are temporary number which let us create
                # dom0 and Boot partitions using the same numbers)
                tool.renamePartition(srcNumber=primary_partnum,
                                     destNumber=10,
                                     overwrite=False)
                boot_part = tool.getPartition(boot_partnum)
                if boot_part:
                    tool.renamePartition(srcNumber=boot_partnum,
                                         destNumber=11,
                                         overwrite=False)
                # Create new bigger dom0 partition
                tool.createPartition(tool.ID_LINUX,
                                     sizeBytes=constants.root_size * 2**20,
                                     number=primary_partnum)
                # Create Boot partition
                if target_boot_mode == constants.TARGET_BOOT_MODE_UEFI:
                    tool.createPartition(tool.ID_EFI_BOOT,
                                         sizeBytes=constants.boot_size * 2**20,
                                         number=boot_partnum)
                else:
                    tool.createPartition(tool.ID_BIOS_BOOT,
                                         sizeBytes=constants.boot_size * 2**20,
                                         number=boot_partnum)
                # Create swap partition
                tool.createPartition(tool.ID_LINUX_SWAP,
                                     sizeBytes=constants.swap_size * 2**20,
                                     number=swap_partnum)
                # Create storage LVM partition
                if storage_partnum > 0 and self.vgs_output:
                    tool.createPartition(tool.ID_LINUX_LVM,
                                         number=storage_partnum)
                # Create logs partition using the old dom0 + Boot (if any) partitions
                tool.deletePartition(10)
                if boot_part:
                    tool.deletePartition(11)
                tool.createPartition(tool.ID_LINUX,
                                     sizeBytes=constants.logs_size * 2**20,
                                     startBytes=1024 * 1024,
                                     number=logs_partnum)

                tool.commit(log=True)

                if storage_partnum > 0 and self.vgs_output:
                    storage_part = partitionDevice(primary_disk,
                                                   storage_partnum)
                    rc, out = util.runCmd2(
                        ['pvs', '-o', 'pv_name,vg_name', '--noheadings'],
                        with_stdout=True)
                    vgs_list = out.strip().splitlines()
                    primary_dev = getMajMin(primary_disk)
                    vgs_output_wrong = [
                        i for i in vgs_list if diskutil.parentdev_from_devpath(
                            i.strip().split()[0]) == primary_dev
                    ]
                    if vgs_output_wrong:
                        vgs_output_wrong = vgs_output_wrong[0].strip()
                        if ' ' in vgs_output_wrong:
                            _, vgs_label = vgs_output_wrong.split(None, 1)
                            util.runCmd2(['vgremove', '-f', vgs_label])
                    util.runCmd2(['vgcreate', self.vgs_output, storage_part])

                    if self.storage_type == 'ext':
                        _, sr_uuid = self.vgs_output.split('-', 1)
                        util.runCmd2([
                            'lvcreate', '-n', sr_uuid, '-l', '100%VG',
                            self.vgs_output
                        ])
                        try:
                            util.mkfs(
                                'ext3',
                                '/dev/' + self.vgs_output + '/' + sr_uuid,
                                ['-F'])
                        except Exception as e:
                            raise RuntimeError(
                                "Backup: Failed to format filesystem on %s: %s"
                                % (storage_part, e))

                return new_partition_layout

            else:

                # If the boot partition already, exists, no partition updates are
                # necessary.
                part = tool.getPartition(boot_partnum)
                if part:
                    if logs_partition is None:
                        return new_partition_layout  #FALSE
                    else:
                        new_partition_layout = True
                        return new_partition_layout