private void updateTags(final List<String> images) throws Exception {
   for (final String imageId : images) {
     try {
       final ImageInfo image = Images.lookupImage(imageId);
       final ImageMetadata.State imgState = image.getState();
       final String taskId = ((MachineImageInfo) image).getImageConversionId();
       if (ImageMetadata.State.pending_available.equals(
           imgState)) {; // do nothing for images not yet in conversion
       } else if (ImageMetadata.State.pending_conversion.equals(imgState)) {
         String message = "";
         try {
           Optional<DiskImageConversionTask> task = conversionTaskCache.get(taskId);
           if (task.isPresent()) {
             message = task.get().getStatusMessage();
           }
         } catch (final Exception ex) {;
         }
         // if needed, we can add messages as well; not sure yet if the messages are clear
         this.tagResources(imageId, "active", message);
         taggedImages.add(imageId);
       } else if (ImageMetadata.State.available.equals(imgState)
           && taggedImages.contains(imageId)) {
         try {
           this.removeTags(imageId);
         } catch (final Exception ex) {;
         } finally {
           taggedImages.remove(imageId);
         }
       }
     } catch (final Exception ex) {
       LOG.error("Failed to update tags for resources in conversion", ex);
     }
   }
 }
 private void updateTags(final List<String> images) throws Exception {
   for (final String imageId : images) {
     try {
       final ImageInfo image = Images.lookupImage(imageId);
       final ImageMetadata.State imgState = image.getState();
       final String taskId = ((MachineImageInfo) image).getImageConversionId();
       if (ImageMetadata.State.pending_available.equals(
           imgState)) {; // do nothing for images not yet in conversion
       } else if (ImageMetadata.State.pending_conversion.equals(imgState)) {
         String message = "";
         try {
           Optional<DiskImageConversionTask> task = conversionTaskCache.get(taskId);
           if (task.isPresent()) {
             message = task.get().getStatusMessage();
           }
         } catch (final Exception ex) {;
         }
         // if needed, we can add messages as well; not sure yet if the messages are clear
         this.tagResources(imageId, "active", message);
         taggedImages.add(imageId);
       } else if (ImageMetadata.State.available.equals(imgState)
           && taggedImages.contains(imageId)) {
         try {
           this.removeTags(imageId);
         } catch (final Exception ex) {;
         } finally {
           taggedImages.remove(imageId);
         }
       } else if (ImageMetadata.State.failed.equals(imgState) && taggedImages.contains(imageId)) {
         String message = "";
         try {
           conversionTaskCache.invalidate(taskId);
           Optional<DiskImageConversionTask> task = conversionTaskCache.get(taskId);
           if (task.isPresent()) message = task.get().getStatusMessage();
         } catch (final Exception ex) {;
         } finally {
           taggedImages.remove(imageId);
         }
         this.tagResources(imageId, "failed", message);
         try (final TransactionResource db = Entities.transactionFor(ImageInfo.class)) {
           try {
             final ImageInfo entity = Entities.uniqueResult(Images.exampleWithImageId(imageId));
             entity.setState(ImageMetadata.State.pending_available);
             entity.setImageFormat(ImageMetadata.ImageFormat.partitioned.name());
             ((MachineImageInfo) entity).setImageConversionId(null);
             Entities.persist(entity);
             db.commit();
           } catch (final Exception ex) {
             LOG.error("Failed to mark the image state available for conversion", ex);
           }
         }
       }
     } catch (final Exception ex) {
       LOG.error("Failed to update tags for resources in conversion", ex);
     }
   }
 }
  private void checkConversion(final List<ImageInfo> images) {
    for (final ImageInfo image : images) {
      if (!(image instanceof MachineImageInfo)) continue;
      try {
        final MachineImageInfo machineImage = (MachineImageInfo) image;
        final String taskId = machineImage.getImageConversionId();
        if (taskId == null || taskId.length() <= 0)
          throw new Exception(
              "Image " + machineImage.getDisplayName() + " has no conversion task Id");

        final DescribeConversionTasks task =
            new DescribeConversionTasks(Lists.newArrayList(machineImage.getImageConversionId()));

        final CheckedListenableFuture<Boolean> result = task.dispatch();
        List<DiskImageConversionTask> ctasks = null;
        if (result.get()) {
          ctasks = task.getTasks();
        }
        boolean conversionSuccess = true;
        String errorMessage = null;
        if (ctasks.size() <= 0) {
          /// consider this task as done when describe tasks has no result
          conversionSuccess = true;
        } else {
          DiskImageConversionTask ct = ctasks.get(0);
          if ("completed".equals(ct.getState())) {
            conversionSuccess = true;
          } else if ("active".equals(ct.getState())) {
            continue;
          } else {
            conversionSuccess = false;
            errorMessage = ct.getStatusMessage();
          }
        }
        if (conversionSuccess) {
          /// if user deregistered the image while in conversion
          if (ImageMetadata.State.deregistered_cleanup.equals(image.getState())) {
            try {
              this.cleanupBuckets(Lists.newArrayList(image), true);
            } catch (final Exception ex) {;
            }
          } else {
            Images.setImageFormat(
                machineImage.getDisplayName(), ImageMetadata.ImageFormat.fulldisk);
            /// the service and the backend (NC) rely on virtualizationType=HVM when they prepare
            // full-disk type instances
            Images.setImageState(machineImage.getDisplayName(), ImageMetadata.State.available);
            try {
              generateDownloadManifests(machineImage.getDisplayName());
            } catch (final Exception ex) {;
            }
          }
        } else {
          LOG.warn(
              "Conversion task for image "
                  + image.getDisplayName()
                  + " has failed: "
                  + errorMessage);
          try {
            this.cleanupBuckets(Lists.newArrayList(image), false);
            this.resetImagePendingAvailable(image.getDisplayName(), null);
          } catch (final Exception ex) {
            LOG.error(
                "Failed to cleanup the image's system bucket; setting image state failed: "
                    + image.getDisplayName());
            Images.setImageState(machineImage.getDisplayName(), ImageMetadata.State.failed);
          }
        }
      } catch (final Exception ex) {
        LOG.warn("Conversion task for image " + image.getDisplayName() + " has failed: ", ex);
        try {
          this.cleanupBuckets(Lists.newArrayList(image), false);
          this.resetImagePendingAvailable(
              image.getDisplayName(), "Failed to check conversion status");
        } catch (final Exception ex2) {
          LOG.error(
              "Failed to cleanup the image's system bucket; setting image state failed: "
                  + image.getDisplayName());
          try {
            Images.setImageState(image.getDisplayName(), ImageMetadata.State.failed);
          } catch (final Exception ex3) {;
          }
        }
      }
    }
  }