Ejemplo n.º 1
0
    def test_split_datastore_path(self):
        test1 = '[datastore1] myfolder/mysubfolder/myvm.vmx'
        (datastore, folder, file_name) = volumeops.split_datastore_path(test1)
        self.assertEqual(datastore, 'datastore1')
        self.assertEqual(folder, 'myfolder/mysubfolder/')
        self.assertEqual(file_name, 'myvm.vmx')

        test2 = '[datastore2 ]   myfolder/myvm.vmdk'
        (datastore, folder, file_name) = volumeops.split_datastore_path(test2)
        self.assertEqual(datastore, 'datastore2')
        self.assertEqual(folder, 'myfolder/')
        self.assertEqual(file_name, 'myvm.vmdk')

        test3 = 'myfolder/myvm.vmdk'
        self.assertRaises(IndexError, volumeops.split_datastore_path, test3)
    def test_split_datastore_path(self):
        test1 = '[datastore1] myfolder/mysubfolder/myvm.vmx'
        (datastore, folder, file_name) = volumeops.split_datastore_path(test1)
        self.assertEqual(datastore, 'datastore1')
        self.assertEqual(folder, 'myfolder/mysubfolder/')
        self.assertEqual(file_name, 'myvm.vmx')

        test2 = '[datastore2 ]   myfolder/myvm.vmdk'
        (datastore, folder, file_name) = volumeops.split_datastore_path(test2)
        self.assertEqual(datastore, 'datastore2')
        self.assertEqual(folder, 'myfolder/')
        self.assertEqual(file_name, 'myvm.vmdk')

        test3 = 'myfolder/myvm.vmdk'
        self.assertRaises(IndexError, volumeops.split_datastore_path, test3)
Ejemplo n.º 3
0
    def test_split_datastore_path(self):
        test1 = "[datastore1] myfolder/mysubfolder/myvm.vmx"
        (datastore, folder, file_name) = volumeops.split_datastore_path(test1)
        self.assertEqual(datastore, "datastore1")
        self.assertEqual(folder, "myfolder/mysubfolder/")
        self.assertEqual(file_name, "myvm.vmx")

        test2 = "[datastore2 ]   myfolder/myvm.vmdk"
        (datastore, folder, file_name) = volumeops.split_datastore_path(test2)
        self.assertEqual(datastore, "datastore2")
        self.assertEqual(folder, "myfolder/")
        self.assertEqual(file_name, "myvm.vmdk")

        test3 = "myfolder/myvm.vmdk"
        self.assertRaises(IndexError, volumeops.split_datastore_path, test3)
Ejemplo n.º 4
0
    def _clone_backing_by_copying(self, volume, backing):
        """Creates volume clone.

        Here we copy the backing on a datastore under the host and then
        register the copied backing to the inventory.
        It is assumed here that all the source backing files are in the
        same folder on the datastore.

        :param volume: New Volume object
        :param backing: Reference to backing entity that must be cloned
        :return: Reference to the cloned backing
        """
        src_path_name = self.volumeops.get_path_name(backing)
        (datastore_name,
         folder_path, filename) = volumeops.split_datastore_path(src_path_name)
        # Pick a datastore where to create the full clone under same host
        host = self.volumeops.get_host(backing)
        (datastores, resource_pool) = self.volumeops.get_dss_rp(host)
        (folder, summary) = self._get_folder_ds_summary(volume['size'],
                                                        resource_pool,
                                                        datastores)
        src_path = '[%s] %s' % (datastore_name, folder_path)
        dest_path = '[%s] %s/' % (summary.name, volume['name'])
        # Copy source backing files to a destination location
        self.volumeops.copy_backing(src_path, dest_path)
        # Register the backing to the inventory
        dest_path_name = '%s%s' % (dest_path, filename)
        clone = self.volumeops.register_backing(dest_path_name,
                                                volume['name'], folder,
                                                resource_pool)
        LOG.info(_("Successfully cloned new backing: %s.") % clone)
        return clone
Ejemplo n.º 5
0
    def _clone_backing_by_copying(self, volume, backing):
        """Creates volume clone.

        Here we copy the backing on a datastore under the host and then
        register the copied backing to the inventory.
        It is assumed here that all the source backing files are in the
        same folder on the datastore.

        :param volume: New Volume object
        :param backing: Reference to backing entity that must be cloned
        :return: Reference to the cloned backing
        """
        src_path_name = self.volumeops.get_path_name(backing)
        (datastore_name, folder_path,
         filename) = volumeops.split_datastore_path(src_path_name)
        # Pick a datastore where to create the full clone under same host
        host = self.volumeops.get_host(backing)
        (datastores, resource_pool) = self.volumeops.get_dss_rp(host)
        (folder,
         summary) = self._get_folder_ds_summary(volume['size'], resource_pool,
                                                datastores)
        src_path = '[%s] %s' % (datastore_name, folder_path)
        dest_path = '[%s] %s/' % (summary.name, volume['name'])
        # Copy source backing files to a destination location
        self.volumeops.copy_backing(src_path, dest_path)
        # Register the backing to the inventory
        dest_path_name = '%s%s' % (dest_path, filename)
        clone = self.volumeops.register_backing(dest_path_name, volume['name'],
                                                folder, resource_pool)
        LOG.info(_("Successfully cloned new backing: %s.") % clone)
        return clone
Ejemplo n.º 6
0
    def _get_ds_name_flat_vmdk_path(self, backing, vol_name):
        """Get datastore name and folder path of the flat VMDK of the backing.

        :param backing: Reference to the backing entity
        :param vol_name: Name of the volume
        :return: datastore name and folder path of the VMDK of the backing
        """
        file_path_name = self.volumeops.get_path_name(backing)
        (datastore_name,
         folder_path, _) = volumeops.split_datastore_path(file_path_name)
        flat_vmdk_path = '%s%s-flat.vmdk' % (folder_path, vol_name)
        return (datastore_name, flat_vmdk_path)
Ejemplo n.º 7
0
    def _get_ds_name_flat_vmdk_path(self, backing, vol_name):
        """Get datastore name and folder path of the flat VMDK of the backing.

        :param backing: Reference to the backing entity
        :param vol_name: Name of the volume
        :return: datastore name and folder path of the VMDK of the backing
        """
        file_path_name = self.volumeops.get_path_name(backing)
        (datastore_name, folder_path,
         _) = volumeops.split_datastore_path(file_path_name)
        flat_vmdk_path = '%s%s-flat.vmdk' % (folder_path, vol_name)
        return (datastore_name, flat_vmdk_path)
Ejemplo n.º 8
0
    def copy_volume_to_image(self, context, volume, image_service, image_meta):
        """Creates glance image from volume.

        Steps followed are:

        1. Get the name of the vmdk file which the volume points to right now.
           Can be a chain of snapshots, so we need to know the last in the
           chain.
        2. Create the snapshot. A new vmdk is created which the volume points
           to now. The earlier vmdk becomes read-only.
        3. Call CopyVirtualDisk which coalesces the disk chain to form a
           single vmdk, rather a .vmdk metadata file and a -flat.vmdk disk
           data file.
        4. Now upload the -flat.vmdk file to the image store.
        5. Delete the coalesced .vmdk and -flat.vmdk created.
        """
        LOG.debug(_("Copy Volume: %s to new image.") % volume['name'])
        VMwareEsxVmdkDriver._validate_disk_format(image_meta['disk_format'])

        backing = self.volumeops.get_backing(volume['name'])
        if not backing:
            LOG.info(_("Backing not found, creating for volume: %s") %
                     volume['name'])
            backing = self._create_backing_in_inventory(volume)

        vmdk_file_path = self.volumeops.get_vmdk_path(backing)
        datastore_name = volumeops.split_datastore_path(vmdk_file_path)[0]

        # Create a snapshot
        image_id = image_meta['id']
        snapshot_name = "snapshot-%s" % image_id
        self.volumeops.create_snapshot(backing, snapshot_name, None, True)

        # Create a copy of the snapshotted vmdk into a tmp file
        tmp_vmdk_file_path = '[%s] %s.vmdk' % (datastore_name, image_id)
        host = self.volumeops.get_host(backing)
        datacenter = self.volumeops.get_dc(host)
        self.volumeops.copy_vmdk_file(datacenter, vmdk_file_path,
                                      tmp_vmdk_file_path)
        try:
            # Upload image from copy of -flat.vmdk
            timeout = self.configuration.vmware_image_transfer_timeout_secs
            host_ip = self.configuration.vmware_host_ip
            datacenter_name = self.volumeops.get_entity_name(datacenter)
            cookies = self.session.vim.client.options.transport.cookiejar
            flat_vmdk_copy = '%s-flat.vmdk' % image_id

            vmware_images.upload_image(context, timeout, image_service,
                                       image_meta['id'],
                                       volume['project_id'], host=host_ip,
                                       data_center_name=datacenter_name,
                                       datastore_name=datastore_name,
                                       cookies=cookies,
                                       file_path=flat_vmdk_copy,
                                       snapshot_name=image_meta['name'],
                                       image_version=1)
            LOG.info(_("Done copying volume %(vol)s to a new image %(img)s") %
                     {'vol': volume['name'], 'img': image_meta['name']})
        finally:
            # Delete the coalesced .vmdk and -flat.vmdk created
            self.volumeops.delete_vmdk_file(tmp_vmdk_file_path, datacenter)
Ejemplo n.º 9
0
    def copy_volume_to_image(self, context, volume, image_service, image_meta):
        """Creates glance image from volume.

        Upload of only available volume is supported.
        Steps followed are:

        1. Get the name of the vmdk file which the volume points to right now.
           Can be a chain of snapshots, so we need to know the last in the
           chain.
        2. Call CopyVirtualDisk which coalesces the disk chain to form a
           single vmdk, rather a .vmdk metadata file and a -flat.vmdk disk
           data file.
        3. Now upload the -flat.vmdk file to the image store.
        4. Delete the coalesced .vmdk and -flat.vmdk created.
        """

        if volume['instance_uuid'] or volume['attached_host']:
            msg = _("Upload to glance of attached volume is not supported.")
            LOG.error(msg)
            raise exception.InvalidVolume(msg)

        LOG.debug(_("Copy Volume: %s to new image.") % volume['name'])
        VMwareEsxVmdkDriver._validate_disk_format(image_meta['disk_format'])

        backing = self.volumeops.get_backing(volume['name'])
        if not backing:
            LOG.info(
                _("Backing not found, creating for volume: %s") %
                volume['name'])
            backing = self._create_backing_in_inventory(volume)

        vmdk_file_path = self.volumeops.get_vmdk_path(backing)
        datastore_name = volumeops.split_datastore_path(vmdk_file_path)[0]

        # Create a copy of the vmdk into a tmp file
        image_id = image_meta['id']
        tmp_vmdk_file_path = '[%s] %s.vmdk' % (datastore_name, image_id)
        host = self.volumeops.get_host(backing)
        datacenter = self.volumeops.get_dc(host)
        self.volumeops.copy_vmdk_file(datacenter, vmdk_file_path,
                                      tmp_vmdk_file_path)
        try:
            # Upload image from copy of -flat.vmdk
            timeout = self.configuration.vmware_image_transfer_timeout_secs
            host_ip = self.configuration.vmware_host_ip
            datacenter_name = self.volumeops.get_entity_name(datacenter)
            cookies = self.session.vim.client.options.transport.cookiejar
            flat_vmdk_copy = '%s-flat.vmdk' % image_id

            vmware_images.upload_image(context,
                                       timeout,
                                       image_service,
                                       image_meta['id'],
                                       volume['project_id'],
                                       host=host_ip,
                                       data_center_name=datacenter_name,
                                       datastore_name=datastore_name,
                                       cookies=cookies,
                                       file_path=flat_vmdk_copy,
                                       snapshot_name=image_meta['name'],
                                       image_version=1)
            LOG.info(
                _("Done copying volume %(vol)s to a new image %(img)s") % {
                    'vol': volume['name'],
                    'img': image_meta['name']
                })
        finally:
            # Delete the coalesced .vmdk and -flat.vmdk created
            self.volumeops.delete_vmdk_file(tmp_vmdk_file_path, datacenter)