public static void fillImagesMapBasedOnTemplate(
      VmTemplate template,
      List<StorageDomain> domains,
      Map<Guid, DiskImage> diskInfoDestinationMap,
      Map<Guid, StorageDomain> destStorages) {
    Map<Guid, StorageDomain> storageDomainsMap = new HashMap<>();
    for (StorageDomain storageDomain : domains) {
      StorageDomainValidator validator = new StorageDomainValidator(storageDomain);
      if (validator.isDomainExistAndActive().isValid()
          && validator.domainIsValidDestination().isValid()) {
        storageDomainsMap.put(storageDomain.getId(), storageDomain);
      }
    }
    for (DiskImage image : template.getDiskTemplateMap().values()) {
      for (Guid storageId : image.getStorageIds()) {
        if (storageDomainsMap.containsKey(storageId)) {
          ArrayList<Guid> storageIds = new ArrayList<>();
          storageIds.add(storageId);
          image.setStorageIds(storageIds);
          diskInfoDestinationMap.put(image.getId(), image);
          break;
        }
      }
    }

    if (destStorages != null) {
      for (DiskImage diskImage : diskInfoDestinationMap.values()) {
        Guid storageDomainId = diskImage.getStorageIds().get(0);
        destStorages.put(storageDomainId, storageDomainsMap.get(storageDomainId));
      }
    }
  }
 @Override
 public List<QuotaConsumptionParameter> getQuotaStorageConsumptionParameters() {
   if (getParameters().isRemoveDisks()) {
     List<QuotaConsumptionParameter> list = new ArrayList<>();
     ImagesHandler.fillImagesBySnapshots(getVm());
     for (DiskImage disk : getVm().getDiskList()) {
       for (DiskImage snapshot : disk.getSnapshots()) {
         if (snapshot.getQuotaId() != null && !Guid.Empty.equals(snapshot.getQuotaId())) {
           if (snapshot.getActive()) {
             list.add(
                 new QuotaStorageConsumptionParameter(
                     snapshot.getQuotaId(),
                     null,
                     QuotaStorageConsumptionParameter.QuotaAction.RELEASE,
                     disk.getStorageIds().get(0),
                     (double) snapshot.getSizeInGigabytes()));
           } else {
             list.add(
                 new QuotaStorageConsumptionParameter(
                     snapshot.getQuotaId(),
                     null,
                     QuotaStorageConsumptionParameter.QuotaAction.RELEASE,
                     disk.getStorageIds().get(0),
                     snapshot.getActualSize()));
           }
         }
       }
     }
     return list;
   }
   return Collections.emptyList();
 }
 /** Get a list of all domains id that the template is on */
 private Set<Guid> getStorageDomainsByDisks(
     List<DiskImage> disks, boolean isFillStorageTodDiskMap) {
   Set<Guid> domainsList = new HashSet<>();
   if (disks != null) {
     for (DiskImage disk : disks) {
       domainsList.addAll(disk.getStorageIds());
       if (isFillStorageTodDiskMap) {
         for (Guid storageDomainId : disk.getStorageIds()) {
           MultiValueMapUtils.addToMap(storageDomainId, disk, storageToDisksMap);
         }
       }
     }
   }
   return domainsList;
 }
 /**
  * @param images The images to get the storage domain IDs for
  * @return A unique {@link Set} of all the storage domain IDs relevant to all the given images
  */
 public static Set<Guid> getAllStorageIdsForImageIds(Collection<DiskImage> images) {
   Set<Guid> domainsIds = new HashSet<>();
   for (DiskImage image : images) {
     domainsIds.addAll(image.getStorageIds());
   }
   return domainsIds;
 }
  public boolean checkDestDomains() {
    List<Guid> validDomains = new ArrayList<>();
    for (DiskImage diskImage : diskInfoDestinationMap.values()) {
      Guid domainId = diskImage.getStorageIds().get(0);
      if (validDomains.contains(domainId)) {
        continue;
      }
      StorageDomain domain = destStorages.get(domainId);
      if (domain == null) {
        domain =
            getStorageDomainDao().getForStoragePool(domainId, getVmTemplate().getStoragePoolId());
        destStorages.put(domainId, domain);
      }
      if (storageToDisksMap.containsKey(domainId)) {
        int numOfDisksOnDomain = storageToDisksMap.get(domainId).size();
        if (numOfDisksOnDomain > 0
            && (domain.getStorageDomainType() == StorageDomainType.ImportExport)) {
          return failCanDoAction(EngineMessage.ACTION_TYPE_FAILED_STORAGE_DOMAIN_TYPE_ILLEGAL);
        }
      }
      validDomains.add(domainId);
    }

    return validateSpaceRequirements();
  }
 /**
  * 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()));
 }
 /**
  * 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);
 }
 protected boolean setAndValidateDiskProfiles() {
   if (diskInfoDestinationMap != null && !diskInfoDestinationMap.isEmpty()) {
     Map<DiskImage, Guid> map = new HashMap<>();
     for (DiskImage diskImage : diskInfoDestinationMap.values()) {
       map.put(diskImage, diskImage.getStorageIds().get(0));
     }
     return validate(
         DiskProfileHelper.setAndValidateDiskProfiles(
             map, getStoragePool().getCompatibilityVersion(), getCurrentUser()));
   }
   return true;
 }
 private boolean imageStorageValidation() {
   // If the VM is not an image then it does not use the storage domain.
   // If the VM is not in UP or PAUSED status, then we know that there is no running qemu process,
   // so we don't need to check the storage domain activity.
   if (getDisk().getDiskStorageType() != DiskStorageType.IMAGE
       || !getVm().getStatus().isRunningOrPaused()) {
     return true;
   }
   DiskImage diskImage = (DiskImage) getDisk();
   StorageDomain storageDomain =
       getStorageDomainDao()
           .getForStoragePool(diskImage.getStorageIds().get(0), diskImage.getStoragePoolId());
   StorageDomainValidator storageDomainValidator = getStorageDomainValidator(storageDomain);
   return validate(storageDomainValidator.isDomainExistAndActive());
 }
 public static Map<Guid, List<DiskImage>> buildStorageToDiskMap(
     Collection<DiskImage> images, Map<Guid, DiskImage> diskInfoDestinationMap) {
   Map<Guid, List<DiskImage>> storageToDisksMap = new HashMap<>();
   for (DiskImage disk : images) {
     DiskImage diskImage = diskInfoDestinationMap.get(disk.getId());
     Guid storageDomainId = diskImage.getStorageIds().get(0);
     List<DiskImage> diskList = storageToDisksMap.get(storageDomainId);
     if (diskList == null) {
       diskList = new ArrayList<>();
       storageToDisksMap.put(storageDomainId, diskList);
     }
     diskList.add(disk);
   }
   return storageToDisksMap;
 }
 public static Map<Guid, Set<Guid>> findDomainsInApplicableStatusForDisks(
     Iterable<DiskImage> diskImages,
     Map<Guid, StorageDomain> storageDomains,
     Set<StorageDomainStatus> applicableStatuses) {
   Map<Guid, Set<Guid>> disksApplicableDomainsMap = new HashMap<>();
   for (DiskImage diskImage : diskImages) {
     Set<Guid> diskApplicableDomain = new HashSet<>();
     for (Guid storageDomainID : diskImage.getStorageIds()) {
       StorageDomain domain = storageDomains.get(storageDomainID);
       if (applicableStatuses.contains(domain.getStatus())) {
         diskApplicableDomain.add(domain.getId());
       }
     }
     disksApplicableDomainsMap.put(diskImage.getId(), diskApplicableDomain);
   }
   return disksApplicableDomainsMap;
 }
  @Override
  public List<QuotaConsumptionParameter> getQuotaStorageConsumptionParameters() {
    List<QuotaConsumptionParameter> list = new ArrayList<>();
    for (DiskImage disk : diskInfoDestinationMap.values()) {
      list.add(
          new QuotaStorageConsumptionParameter(
              disk.getQuotaId(),
              null,
              QuotaConsumptionParameter.QuotaAction.CONSUME,
              disk.getStorageIds().get(0),
              (double)
                  (disk.getSizeInGigabytes()
                      * getParameters().getVmsCount()
                      * getBlockSparseInitSizeInGB())));
    }

    return list;
  }
 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;
 }
 @Override
 public List<QuotaConsumptionParameter> getQuotaStorageConsumptionParameters() {
   List<QuotaConsumptionParameter> list = new ArrayList<>();
   fetchImageTemplates();
   if (imageTemplates != null) {
     for (DiskImage disk : imageTemplates) {
       if (disk.getQuotaId() != null && !Guid.Empty.equals(disk.getQuotaId())) {
         for (Guid storageId : disk.getStorageIds()) {
           list.add(
               new QuotaStorageConsumptionParameter(
                   disk.getQuotaId(),
                   null,
                   QuotaStorageConsumptionParameter.QuotaAction.RELEASE,
                   storageId,
                   (double) disk.getSizeInGigabytes()));
         }
       }
     }
   }
   return list;
 }
  @Override
  protected boolean canDoAction() {
    if (getVdsGroup() == null) {
      return failCanDoAction(EngineMessage.VDS_CLUSTER_IS_NOT_VALID);
    }

    // A Pool cannot be added in a cluster without a defined architecture
    if (getVdsGroup().getArchitecture() == ArchitectureType.undefined) {
      return failCanDoAction(EngineMessage.ACTION_TYPE_FAILED_CLUSTER_UNDEFINED_ARCHITECTURE);
    }

    VmPool pool = getVmPoolDao().getByName(getParameters().getVmPool().getName());
    if (pool != null
        && (getActionType() == VdcActionType.AddVmPoolWithVms
            || !pool.getVmPoolId().equals(getParameters().getVmPoolId()))) {
      return failCanDoAction(EngineMessage.ACTION_TYPE_FAILED_NAME_ALREADY_USED);
    }

    setStoragePoolId(getVdsGroup().getStoragePoolId());
    if (!validate(new StoragePoolValidator(getStoragePool()).isUp())) {
      return false;
    }

    // check if the selected template is compatible with Cluster architecture.
    if (!getVmTemplate().getId().equals(VmTemplateHandler.BLANK_VM_TEMPLATE_ID)
        && getVdsGroup().getArchitecture() != getVmTemplate().getClusterArch()) {
      return failCanDoAction(EngineMessage.ACTION_TYPE_FAILED_TEMPLATE_IS_INCOMPATIBLE);
    }

    if (!verifyAddVM()) {
      return false;
    }

    if (getVmTemplate().getDiskTemplateMap().values().size() != diskInfoDestinationMap.size()) {
      log.error(
          "Can not found any default active domain for one of the disks of template with id '{}'",
          getVmTemplate().getId());
      addCanDoActionMessage(EngineMessage.ACTION_TYPE_FAILED_MISSED_STORAGES_FOR_SOME_DISKS);
      return false;
    }

    List<Guid> storageIds = new ArrayList<>();
    for (DiskImage diskImage : diskInfoDestinationMap.values()) {
      Guid storageId = diskImage.getStorageIds().get(0);
      if (!storageIds.contains(storageId) && !areTemplateImagesInStorageReady(storageId)) {
        return false;
      }
      storageIds.add(storageId);
    }

    if (getActionType() == VdcActionType.AddVmPoolWithVms && getParameters().getVmsCount() < 1) {
      return failCanDoAction(EngineMessage.VM_POOL_CANNOT_CREATE_WITH_NO_VMS);
    }

    if (getParameters().getVmStaticData().isStateless()) {
      return failCanDoAction(EngineMessage.ACTION_TYPE_FAILED_VM_FROM_POOL_CANNOT_BE_STATELESS);
    }

    if (getParameters().getVmPool().getPrestartedVms()
        > getParameters().getVmPool().getAssignedVmsCount() + getParameters().getVmsCount()) {
      return failCanDoAction(
          EngineMessage.ACTION_TYPE_FAILED_PRESTARTED_VMS_CANNOT_EXCEED_VMS_COUNT);
    }

    if (Boolean.TRUE.equals(getParameters().isVirtioScsiEnabled())
        && !FeatureSupported.virtIoScsi(getVdsGroup().getCompatibilityVersion())) {
      return failCanDoAction(
          EngineMessage.VIRTIO_SCSI_INTERFACE_IS_NOT_AVAILABLE_FOR_CLUSTER_LEVEL);
    }
    if (!setAndValidateDiskProfiles()) {
      return false;
    }
    if (!setAndValidateCpuProfile()) {
      return false;
    }
    return checkDestDomains();
  }