コード例 #1
0
 private void syncDbRecordsMergeFailure() {
   DiskImage curr = getDestinationDiskImage();
   while (!curr.getImageId().equals(getDiskImage().getImageId())) {
     curr = getDbFacade().getDiskImageDao().getSnapshotById(curr.getParentId());
     getImageDao().updateStatus(curr.getImageId(), ImageStatus.ILLEGAL);
   }
 }
コード例 #2
0
 @Override
 public String getVolumeStringRepresentation() {
   return MemoryUtils.createMemoryStateString(
       storageDomainId,
       storagePool.getId(),
       memoryDisk.getId(),
       memoryDisk.getImageId(),
       metadataDisk.getId(),
       metadataDisk.getImageId());
 }
コード例 #3
0
 public static void fillImagesBySnapshots(VM vm) {
   for (Disk disk : vm.getDiskMap().values()) {
     if (disk.getDiskStorageType().isInternal()) {
       DiskImage diskImage = (DiskImage) disk;
       diskImage.getSnapshots().addAll(getAllImageSnapshots(diskImage.getImageId()));
     }
   }
 }
コード例 #4
0
 // function return the index of image that is its child
 private static int getNextImage(List<DiskImage> images, DiskImage curr) {
   for (int i = 0; i < images.size(); i++) {
     if (images.get(i).getParentId().equals(curr.getImageId())) {
       return i;
     }
   }
   return -1;
 }
コード例 #5
0
 /**
  * Returns a list of image IDs for the specified DiskImages collection.
  *
  * @param diskImages collection of DiskImages
  * @return list of image IDs ordered by the order of the retrieved list.
  */
 public static List<Guid> getDiskImageIds(List<DiskImage> diskImages) {
   List<Guid> result = new ArrayList<>();
   if (diskImages != null) {
     for (DiskImage diskImage : diskImages) {
       result.add(diskImage.getImageId());
     }
   }
   return result;
 }
コード例 #6
0
 /**
  * Gets a map of DiskImage IDs to DiskImage objects
  *
  * @param diskImages collection of DiskImage objects to create the map for
  * @return map object is the collection is not null
  */
 public static Map<Guid, DiskImage> getDiskImagesByIdMap(Collection<DiskImage> diskImages) {
   Map<Guid, DiskImage> result = new HashMap<>();
   if (diskImages != null) {
     for (DiskImage diskImage : diskImages) {
       result.put(diskImage.getImageId(), diskImage);
     }
   }
   return result;
 }
コード例 #7
0
 /**
  * Adds a disk image (Adds image, disk, and relevant entities , but not VmDevice) This may be
  * useful for Clone VMs, where besides adding images it is required to copy all vm devices
  * (VmDeviceUtils.copyVmDevices) from the source VM.
  */
 public static void addDiskImageWithNoVmDevice(DiskImage image) {
   addDiskImageWithNoVmDevice(
       image,
       image.getActive(),
       new ImageStorageDomainMap(
           image.getImageId(),
           image.getStorageIds().get(0),
           image.getQuotaId(),
           image.getDiskProfileId()));
 }
コード例 #8
0
 private void updateDiskVmSnapshotId() {
   Guid snapshotId = getSnapshotDao().getId(getVmId(), SnapshotType.ACTIVE);
   if (disk.getDiskStorageType().isInternal()) {
     DiskImage diskImage = ((DiskImage) disk);
     getImageDao().updateImageVmSnapshotId(diskImage.getImageId(), snapshotId);
   } else {
     throw new EngineException(
         EngineError.StorageException,
         "update of snapshot id was initiated for unsupported disk type");
   }
 }
コード例 #9
0
 /**
  * Adds a disk image (Adds image with active flag according to the value in image, using the first
  * storage domain in the storage id as entry to the storage domain map)
  *
  * @param image DiskImage to add
  */
 public static void addDiskImage(DiskImage image, Guid vmId) {
   addDiskImage(
       image,
       image.getActive(),
       new ImageStorageDomainMap(
           image.getImageId(),
           image.getStorageIds().get(0),
           image.getQuotaId(),
           image.getDiskProfileId()),
       vmId);
 }
コード例 #10
0
 /**
  * Add image and related entities to DB (Adds image, disk image dynamic and image storage domain
  * map)
  *
  * @param image the image to add
  * @param active if true the image will be active
  * @param imageStorageDomainMap entry of mapping between the storage domain and the image
  */
 public static void addImage(
     DiskImage image, boolean active, ImageStorageDomainMap imageStorageDomainMap) {
   image.setActive(active);
   DbFacade.getInstance().getImageDao().save(image.getImage());
   DiskImageDynamic diskDynamic = new DiskImageDynamic();
   diskDynamic.setId(image.getImageId());
   diskDynamic.setActualSize(image.getActualSizeInBytes());
   DbFacade.getInstance().getDiskImageDynamicDao().save(diskDynamic);
   if (imageStorageDomainMap != null) {
     DbFacade.getInstance().getImageStorageDomainMapDao().save(imageStorageDomainMap);
   }
 }
コード例 #11
0
  /**
   * Prepare a single {@link org.ovirt.engine.core.common.businessentities.Snapshot} object
   * representing a snapshot of a given VM without the given disk, substituting a new disk in its
   * place if a new disk is provided to the method.
   */
  public static Snapshot prepareSnapshotConfigWithAlternateImage(
      Snapshot snapshot, Guid oldImageId, DiskImage newImage) {
    try {
      OvfManager ovfManager = new OvfManager();
      String snapConfig = snapshot.getVmConfiguration();

      if (snapshot.isVmConfigurationAvailable() && snapConfig != null) {
        VM vmSnapshot = new VM();
        ArrayList<DiskImage> snapshotImages = new ArrayList<>();

        ovfManager.importVm(snapConfig, vmSnapshot, snapshotImages, new ArrayList<>());

        // Remove the image from the disk list
        Iterator<DiskImage> diskIter = snapshotImages.iterator();
        while (diskIter.hasNext()) {
          DiskImage imageInList = diskIter.next();
          if (imageInList.getImageId().equals(oldImageId)) {
            log.debug(
                "Recreating vmSnapshot '{}' without the image '{}'", snapshot.getId(), oldImageId);
            diskIter.remove();
            break;
          }
        }

        if (newImage != null) {
          log.debug(
              "Adding image '{}' to vmSnapshot '{}'", newImage.getImageId(), snapshot.getId());
          snapshotImages.add(newImage);
        }

        String newOvf =
            ovfManager.exportVm(
                vmSnapshot, snapshotImages, ClusterUtils.getCompatibilityVersion(vmSnapshot));
        snapshot.setVmConfiguration(newOvf);
      }
    } catch (OvfReaderException e) {
      log.error("Can't remove image '{}' from snapshot '{}'", oldImageId, snapshot.getId());
    }
    return snapshot;
  }
コード例 #12
0
  public static DiskImage cloneDiskImage(
      Guid storageDomainId,
      Guid newImageGroupId,
      Guid newImageGuid,
      DiskImage srcDiskImage,
      Guid diskProfileId,
      Guid snapshotId,
      DiskImage diskImageFromClient) {

    DiskImage clonedDiskImage = DiskImage.copyOf(srcDiskImage);
    clonedDiskImage.setImageId(newImageGuid);
    clonedDiskImage.setParentId(Guid.Empty);
    clonedDiskImage.setImageTemplateId(Guid.Empty);
    clonedDiskImage.setVmSnapshotId(snapshotId);
    clonedDiskImage.setId(newImageGroupId);
    clonedDiskImage.setLastModifiedDate(new Date());
    clonedDiskImage.setvolumeFormat(srcDiskImage.getVolumeFormat());
    clonedDiskImage.setVolumeType(srcDiskImage.getVolumeType());
    ArrayList<Guid> storageIds = new ArrayList<>();
    storageIds.add(storageDomainId);
    clonedDiskImage.setStorageIds(storageIds);
    clonedDiskImage.setDiskProfileId(diskProfileId);

    // If volume information was changed at client , use its volume information.
    // If volume information was not changed at client - use the volume information of the ancestral
    // image
    if (diskImageFromClient != null) {
      if (volumeInfoChanged(diskImageFromClient, srcDiskImage)) {
        changeVolumeInfo(clonedDiskImage, diskImageFromClient);
      } else {
        DiskImage ancestorDiskImage = getDiskImageDao().getAncestor(srcDiskImage.getImageId());
        changeVolumeInfo(clonedDiskImage, ancestorDiskImage);
      }
    } else {
      DiskImage ancestorDiskImage = getDiskImageDao().getAncestor(srcDiskImage.getImageId());
      changeVolumeInfo(clonedDiskImage, ancestorDiskImage);
    }

    return clonedDiskImage;
  }
コード例 #13
0
 private VmTemplate createVmTemplate() {
   if (vmTemplate == null) {
     vmTemplate = new VmTemplate();
     vmTemplate.setStoragePoolId(STORAGE_POOL_ID);
     DiskImage image = createDiskImageTemplate();
     vmTemplate.getDiskTemplateMap().put(image.getImageId(), image);
     HashMap<Guid, DiskImage> diskImageMap = new HashMap<>();
     DiskImage diskImage = createDiskImage(REQUIRED_DISK_SIZE_GB);
     diskImageMap.put(diskImage.getId(), diskImage);
     vmTemplate.setDiskImageMap(diskImageMap);
   }
   return vmTemplate;
 }
コード例 #14
0
  private boolean removeVm() {
    final List<DiskImage> diskImages =
        DisksFilter.filterImageDisks(getVm().getDiskList(), ONLY_NOT_SHAREABLE, ONLY_ACTIVE);

    final List<LunDisk> lunDisks =
        DisksFilter.filterLunDisks(getVm().getDiskMap().values(), ONLY_NOT_SHAREABLE);

    for (VmNic nic : getInterfaces()) {
      new ExternalNetworkManager(nic).deallocateIfExternal();
    }

    removeMemoryVolumes();

    TransactionSupport.executeInNewTransaction(
        () -> {
          removeVmFromDb();
          if (getParameters().isRemoveDisks()) {
            for (DiskImage image : diskImages) {
              getCompensationContext().snapshotEntityStatus(image.getImage(), ImageStatus.ILLEGAL);
              ImagesHandler.updateImageStatus(image.getImage().getId(), ImageStatus.LOCKED);
            }

            for (LunDisk lunDisk : lunDisks) {
              ImagesHandler.removeLunDisk(lunDisk);
            }

            getCompensationContext().stateChanged();
          } else {
            for (DiskImage image : diskImages) {
              imageDao.updateImageVmSnapshotId(image.getImageId(), null);
            }
          }
          return null;
        });

    Collection<DiskImage> unremovedDisks = Collections.emptyList();
    if (getParameters().isRemoveDisks()) {
      if (!diskImages.isEmpty()) {
        unremovedDisks = removeVmImages(diskImages).getActionReturnValue();
      }
      unremovedDisks.addAll(removeCinderDisks());
      if (!unremovedDisks.isEmpty()) {
        processUnremovedDisks(unremovedDisks);
        return false;
      }
    }

    vmDeleted.fire(getVmId());
    return true;
  }
コード例 #15
0
  private ImagesContainterParametersBase buildRemoveSnapshotSingleDiskParameters() {
    ImagesContainterParametersBase parameters = new ImagesContainterParametersBase(imageId, vmId);

    DiskImage dest =
        DbFacade.getInstance().getDiskImageDao().getAllSnapshotsForParent(imageId).get(0);

    parameters.setDestinationImageId(dest.getImageId());
    parameters.setEntityInfo(enclosingCommand.getParameters().getEntityInfo());
    parameters.setParentParameters(enclosingCommand.getParameters());
    parameters.setParentCommand(enclosingCommand.getActionType());
    parameters.setWipeAfterDelete(dest.isWipeAfterDelete());
    parameters.setSessionId(enclosingCommand.getParameters().getSessionId());
    return parameters;
  }
コード例 #16
0
  private void setUpDaoMocks() {
    // Disk Image Dao
    List<Disk> returnArray = new ArrayList<>();
    returnArray.add(pluggedDisk);
    returnArray.add(unpluggedDisk);
    returnArray.add(pluggedDiskSnapshot);
    returnArray.add(unpluggedDiskSnapshot);

    when(diskDaoMock.getAllForVm(vmID, getUser().getId(), getQueryParameters().isFiltered()))
        .thenReturn(returnArray);

    when(diskVmElementDao.get(any(VmDeviceId.class)))
        .thenReturn(new DiskVmElement(new VmDeviceId()));

    // Snapshots
    doReturn(
            new ArrayList<>(
                Collections.nCopies(
                    NUM_DISKS_OF_EACH_KIND, createDiskSnapshot(pluggedDisk.getId()))))
        .when(diskImageDao)
        .getAllSnapshotsForLeaf(pluggedDisk.getImageId());
    doReturn(Collections.nCopies(NUM_DISKS_OF_EACH_KIND, createDiskSnapshot(unpluggedDisk.getId())))
        .when(diskImageDao)
        .getAllSnapshotsForLeaf(unpluggedDisk.getImageId());
    doReturn(
            new ArrayList<>(
                Collections.nCopies(
                    NUM_DISKS_OF_EACH_KIND, createDiskSnapshot(pluggedDiskSnapshot.getId()))))
        .when(diskImageDao)
        .getAllSnapshotsForLeaf(pluggedDiskSnapshot.getImageId());
    doReturn(
            Collections.nCopies(
                NUM_DISKS_OF_EACH_KIND, createDiskSnapshot(unpluggedDiskSnapshot.getId())))
        .when(diskImageDao)
        .getAllSnapshotsForLeaf(unpluggedDiskSnapshot.getImageId());
  }
コード例 #17
0
 public static List<DiskImage> getSnapshotsDummiesForStorageAllocations(
     Collection<DiskImage> originalDisks) {
   List<DiskImage> diskDummies = new ArrayList<>();
   for (DiskImage snapshot : originalDisks) {
     DiskImage clone = DiskImage.copyOf(snapshot);
     // Add the child snapshot into which the deleted snapshot is going to be merged to the
     // DiskImage for StorageDomainValidator to handle
     List<DiskImage> snapshots =
         DbFacade.getInstance().getDiskImageDao().getAllSnapshotsForParent(clone.getImageId());
     clone.getSnapshots().clear();
     clone
         .getSnapshots()
         .add(clone); // Add the clone itself since snapshots should contain the entire chain.
     clone.getSnapshots().addAll(snapshots);
     diskDummies.add(clone);
   }
   return diskDummies;
 }
コード例 #18
0
 private static DiskImage isImageExist(Guid storagePoolId, DiskImage image) {
   DiskImage fromIrs = null;
   try {
     Guid storageDomainId = image.getStorageIds().get(0);
     Guid imageGroupId = image.getId() != null ? image.getId() : Guid.Empty;
     fromIrs =
         (DiskImage)
             Backend.getInstance()
                 .getResourceManager()
                 .runVdsCommand(
                     VDSCommandType.GetImageInfo,
                     new GetImageInfoVDSCommandParameters(
                         storagePoolId, storageDomainId, imageGroupId, image.getImageId()))
                 .getReturnValue();
   } catch (Exception e) {
     log.debug("Unable to get image info from from storage", e);
   }
   return fromIrs;
 }
コード例 #19
0
  @Mapping(
      from = org.ovirt.engine.core.common.businessentities.storage.Disk.class,
      to = DiskSnapshot.class)
  public static DiskSnapshot map(
      org.ovirt.engine.core.common.businessentities.storage.Disk entity, DiskSnapshot template) {
    if (template == null) {
      template = new DiskSnapshot();
    }
    DiskSnapshot model = (DiskSnapshot) DiskMapper.map(entity, template);

    Disk disk = new Disk();
    disk.setId(entity.getId().toString());
    model.setDisk(disk);

    DiskImage diskImage = (DiskImage) entity;
    model.setId(diskImage.getImageId().toString());
    model.setImageId(null);

    return model;
  }
コード例 #20
0
 public static DiskImage createDiskImageWithExcessData(DiskImage diskImage, Guid sdId) {
   DiskImage dummy = DiskImage.copyOf(diskImage);
   dummy.setStorageIds(new ArrayList<>(Collections.singletonList(sdId)));
   dummy.getSnapshots().addAll(getAllImageSnapshots(dummy.getImageId()));
   return dummy;
 }
コード例 #21
0
  /**
   * After merging the snapshots, update the image and snapshot records in the database to reflect
   * the changes. This handles either forward or backwards merge (detected). It will either then
   * remove the images, or mark them illegal (to handle the case where image deletion failed).
   *
   * @param removeImages Remove the images from the database, or if false, only mark them illegal
   */
  private void syncDbRecords(boolean removeImages) {
    // If deletion failed after a backwards merge, the snapshots' images need to be swapped
    // as they would upon success.  Instead of removing them, mark them illegal.
    DiskImage baseImage = getDiskImage();
    DiskImage topImage = getDestinationDiskImage();

    // The vdsm merge verb may decide to perform a forward or backward merge.
    if (topImage == null) {
      log.debug("No merge destination image, not updating image/snapshot association");
    } else if (getParameters().getMergeStatusReturnValue().getBlockJobType()
        == VmBlockJobType.PULL) {
      // For forward merge, the volume format and type may change.
      topImage.setvolumeFormat(baseImage.getVolumeFormat());
      topImage.setVolumeType(baseImage.getVolumeType());
      topImage.setParentId(baseImage.getParentId());
      topImage.setImageStatus(ImageStatus.OK);

      getBaseDiskDao().update(topImage);
      getImageDao().update(topImage.getImage());
      updateDiskImageDynamic(topImage);

      updateVmConfigurationForImageRemoval(
          baseImage.getImage().getSnapshotId(), baseImage.getImageId());
    } else {
      // For backwards merge, the prior base image now has the data associated with the newer
      // snapshot we want to keep.  Re-associate this older image with the newer snapshot.
      // The base snapshot is deleted if everything went well.  In case it's not deleted, we
      // hijack it to preserve a link to the broken image.  This makes the image discoverable
      // so that we can retry the deletion later, yet doesn't corrupt the VM image chain.
      List<DiskImage> children =
          DbFacade.getInstance().getDiskImageDao().getAllSnapshotsForParent(topImage.getImageId());
      if (!children.isEmpty()) {
        DiskImage childImage = children.get(0);
        childImage.setParentId(baseImage.getImageId());
        getImageDao().update(childImage.getImage());
      }

      Image oldTopImage = topImage.getImage();
      topImage.setImage(baseImage.getImage());
      baseImage.setImage(oldTopImage);

      Guid oldTopSnapshotId = topImage.getImage().getSnapshotId();
      topImage.getImage().setSnapshotId(baseImage.getImage().getSnapshotId());
      baseImage.getImage().setSnapshotId(oldTopSnapshotId);

      boolean oldTopIsActive = topImage.getImage().isActive();
      topImage.getImage().setActive(baseImage.getImage().isActive());
      VolumeClassification baseImageVolumeClassification =
          VolumeClassification.getVolumeClassificationByActiveFlag(baseImage.getImage().isActive());
      topImage.getImage().setVolumeClassification(baseImageVolumeClassification);
      baseImage.getImage().setActive(oldTopIsActive);
      VolumeClassification oldTopVolumeClassification =
          VolumeClassification.getVolumeClassificationByActiveFlag(oldTopIsActive);
      topImage.getImage().setVolumeClassification(oldTopVolumeClassification);

      topImage.setSize(baseImage.getSize());
      topImage.setImageStatus(ImageStatus.OK);
      getBaseDiskDao().update(topImage);
      getImageDao().update(topImage.getImage());
      updateDiskImageDynamic(topImage);

      getBaseDiskDao().update(baseImage);
      getImageDao().update(baseImage.getImage());

      updateVmConfigurationForImageChange(
          topImage.getImage().getSnapshotId(), baseImage.getImageId(), topImage);
      updateVmConfigurationForImageRemoval(
          baseImage.getImage().getSnapshotId(), topImage.getImageId());
    }

    Set<Guid> imagesToUpdate = getParameters().getMergeStatusReturnValue().getImagesToRemove();
    if (imagesToUpdate == null) {
      log.error("Failed to update orphaned images in db: image list could not be retrieved");
      return;
    }
    for (Guid imageId : imagesToUpdate) {
      if (removeImages) {
        getImageDao().remove(imageId);
      } else {
        // The (illegal && no-parent && no-children) status indicates an orphaned image.
        Image image = getImageDao().get(imageId);
        image.setStatus(ImageStatus.ILLEGAL);
        image.setParentId(Guid.Empty);
        getImageDao().update(image);
      }
    }
  }
コード例 #22
0
 public static void removeImage(DiskImage diskImage) {
   DbFacade.getInstance().getImageStorageDomainMapDao().remove(diskImage.getImageId());
   DbFacade.getInstance().getDiskImageDynamicDao().remove(diskImage.getImageId());
   DbFacade.getInstance().getImageDao().remove(diskImage.getImageId());
 }