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 removeTags(final String imageId) throws Exception { final ImageInfo image = Images.lookupImage(imageId); final String imageOwnerId = image.getOwnerUserId(); DeleteTagsTask task = new DeleteTagsTask( imageOwnerId, Lists.newArrayList(image.getDisplayName()), Lists.newArrayList(TAG_KEY_STATE, TAG_KEY_MESSAGE)); CheckedListenableFuture<Boolean> result = task.dispatch(); if (result.get()) {; } final List<VmInstance> instances = this.lookupInstances(imageId); for (final VmInstance instance : instances) { final String instanceId = instance.getInstanceId(); final String instanceOwnerId = instance.getOwnerUserId(); try { task = new DeleteTagsTask( instanceOwnerId, Lists.newArrayList(instanceId), Lists.newArrayList(TAG_KEY_STATE, TAG_KEY_MESSAGE)); result = task.dispatch(); if (result.get()) {; } } catch (final Exception ex) {; } } }
private void resetImagePendingAvailable(final String imageId, final String reason) { String taskMessage = ""; /// tag image and instances with proper message try { final ImageInfo image = Images.lookupImage(imageId); final String taskId = ((MachineImageInfo) image).getImageConversionId(); if (taskId != null) { conversionTaskCache.invalidate(taskId); Optional<DiskImageConversionTask> task = conversionTaskCache.get(taskId); if (task.isPresent()) taskMessage = task.get().getStatusMessage(); } final String tagMessage = reason != null ? reason : taskMessage; this.tagResources(imageId, "failed", tagMessage); } catch (final Exception ex) {; } finally { taggedImages.remove(imageId); } 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: " + imageId, 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); } } }
/** * @see com.eucalyptus.util.Mappable#getName() * @see com.eucalyptus.cloud.UserMetadata#equals(java.lang.Object) * @param o * @return */ @Override public boolean equals(final Object o) { if (this == o) return true; if ((o == null) || (this.getClass() != o.getClass())) return false; final ImageInfo imageInfo = (ImageInfo) o; if (!this.getDisplayName().equals(imageInfo.getDisplayName())) return false; return true; }
@SuppressWarnings("unchecked") public ImageInfo grantPermission(final Account account) { EntityTransaction db = Entities.get(ImageInfo.class); try { ImageInfo entity = Entities.merge(this); entity.getPermissions().add(account.getAccountNumber()); db.commit(); } catch (Exception ex) { Logs.exhaust().error(ex, ex); db.rollback(); } return this; }
public boolean addProductCode(final String prodCode) { EntityTransaction db = Entities.get(ImageInfo.class); try { ImageInfo entity = Entities.merge(this); entity.getProductCodes().add(prodCode); db.commit(); return true; } catch (Exception ex) { Logs.exhaust().error(ex, ex); db.rollback(); return false; } }
private void tagResources(final String imageId, final String state, String statusMessage) throws Exception { final ImageInfo image = Images.lookupImage(imageId); final String imageOwnerId = image.getOwnerUserId(); final List<VmInstance> instances = this.lookupInstances(imageId); if (tagState.containsKey(imageId) && state.equals(tagState.get(imageId))) {; } else { resetTag(imageOwnerId, imageId, TAG_KEY_STATE, state); tagState.put(imageId, state); } for (final VmInstance instance : instances) { final String instanceId = instance.getInstanceId(); final String instanceOwnerId = instance.getOwnerUserId(); if (tagState.containsKey(instanceId) && state.equals(tagState.get(instanceId))) {; } else { resetTag(instanceOwnerId, instanceId, TAG_KEY_STATE, state); tagState.put(instanceId, state); } } if (statusMessage == null) statusMessage = ""; if (tagMessage.containsKey(imageId) && statusMessage.equals(tagMessage.get(imageId))) {; } else { resetTag(imageOwnerId, imageId, TAG_KEY_MESSAGE, statusMessage); tagMessage.put(imageId, statusMessage); } for (final VmInstance instance : instances) { final String instanceId = instance.getInstanceId(); final String instanceOwnerId = instance.getOwnerUserId(); if (tagMessage.containsKey(instanceId) && statusMessage.equals(tagMessage.get(instanceId))) {; } else { resetTag(instanceOwnerId, instanceId, TAG_KEY_MESSAGE, statusMessage); tagMessage.put(instanceId, statusMessage); } } }
public ImageInfo resetProductCodes() { try { Transactions.one( ImageInfo.self(this), new Callback<ImageInfo>() { @Override public void fire(final ImageInfo t) { t.getProductCodes().clear(); } }); } catch (final ExecutionException e) { LOG.debug(e, e); } return this; }
static ImageInfo self(final ImageInfo image) { return new ImageInfo(image.getDisplayName()); }
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) {; } } } } }
private void convertImages(final List<ImageInfo> images) { for (final ImageInfo image : images) { if (!(image instanceof MachineImageInfo)) continue; try { final MachineImageInfo machineImage = (MachineImageInfo) image; final String kernelId = machineImage.getKernelId(); final String ramdiskId = machineImage.getRamdiskId(); if (kernelId == null || ramdiskId == null) { LOG.warn( String.format( "Kernel and ramdisk are not found for the image %s", image.getDisplayName())); continue; } final KernelImageInfo kernel = Images.lookupKernel(kernelId); final RamdiskImageInfo ramdisk = Images.lookupRamdisk(ramdiskId); final ServiceConfiguration osg = Topology.lookup(ObjectStorage.class); final URI osgUri = osg.getUri(); final String osgPrefix = String.format( "%s://%s:%d%s", osgUri.getScheme(), osgUri.getHost(), osgUri.getPort(), osgUri.getPath()); final String kernelManifest = String.format("%s/%s", osgPrefix, kernel.getManifestLocation()); final String ramdiskManifest = String.format("%s/%s", osgPrefix, ramdisk.getManifestLocation()); final String machineManifest = String.format("%s/%s", osgPrefix, machineImage.getManifestLocation()); final String[] tokens = machineImage.getRunManifestLocation().split("/"); final String bucket = tokens[0]; final String prefix = tokens[1].replace(".manifest.xml", ""); String taskId = null; try { final ImportImageBuilder builder = new ImportImageBuilder(); final ImportImageTask task = new ImportImageTask( builder .withArchitecture(machineImage.getArchitecture().name()) .withBucket(bucket) .withPrefix(prefix) .withKernel( kernel.getDisplayName(), kernelManifest, kernel.getImageSizeBytes()) .withRamdisk( ramdisk.getDisplayName(), ramdiskManifest, ramdisk.getImageSizeBytes()) .withMachineImage( machineImage.getDisplayName(), machineManifest, machineImage.getImageSizeBytes()) .withBucketUploadPolicy(bucket, prefix)); final CheckedListenableFuture<Boolean> result = task.dispatch(); if (result.get()) { taskId = task.getTaskId(); } } catch (final Exception ex) { throw ex; } if (taskId == null) throw new Exception("ImportImage Task id is null"); Images.setConversionTaskId(machineImage.getDisplayName(), taskId); } catch (final Exception ex) { LOG.error("Failed to convert the image: " + image.getDisplayName(), ex); try { this.cleanupBuckets(Lists.newArrayList(image), false); resetImagePendingAvailable(image.getDisplayName(), "Failed to request conversion"); } 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) {; } } } } }
private void cleanupBuckets(final List<ImageInfo> images, boolean deregister) { Set<String> systemBuckets = null; if (images.size() > 0) { try { final ListBucketsTask task = new ListBucketsTask(); final CheckedListenableFuture<Boolean> result = task.dispatch(); if (result.get()) { final List<String> bucketNames = task.getBuckets(); systemBuckets = Sets.newHashSet(); systemBuckets.addAll(bucketNames); } } catch (final Exception ex) {; } } for (final ImageInfo image : images) { if (!(image instanceof MachineImageInfo)) continue; try { final MachineImageInfo machineImage = (MachineImageInfo) image; final String runManifestPath = machineImage.getRunManifestLocation(); final String manifestPath = machineImage.getManifestLocation(); if (runManifestPath == null || runManifestPath.length() <= 0) continue; if (runManifestPath.equals( manifestPath)) // should not delete if runManifest is not system-generated one continue; final String[] tokens = runManifestPath.split("/"); final String bucket = tokens[0]; if (!systemBuckets.contains(bucket)) continue; final ListObjectsInBucketTask listObjTask = new ListObjectsInBucketTask(bucket); CheckedListenableFuture<Boolean> result = listObjTask.dispatch(); List<String> keysInBucket = null; if (result.get()) { keysInBucket = listObjTask.getKeyNames(); } else throw new Exception("Failed to list bucket"); for (final String key : keysInBucket) { final DeleteObjectTask delObjTask = new DeleteObjectTask(bucket, key); final CheckedListenableFuture<Boolean> delResult = delObjTask.dispatch(); if (delResult.get()) {; } else { throw new Exception("Failed to delete object " + bucket + ":" + key); } } final DeleteBucketTask delBucketTask = new DeleteBucketTask(bucket); result = delBucketTask.dispatch(); if (result.get()) {; } else throw new Exception("Failed to delete the bucket " + bucket); if (deregister) Images.setImageState(image.getDisplayName(), ImageMetadata.State.deregistered); } catch (final Exception ex) { LOG.error( "Failed to cleanup buckets and objects of deregistered image " + image.getDisplayName(), ex); } } }
private void createBuckets(final List<ImageInfo> images) throws Exception { Set<String> systemBuckets = null; if (images.size() > 0) { try { final ListBucketsTask task = new ListBucketsTask(); final CheckedListenableFuture<Boolean> result = task.dispatch(); if (result.get()) { final List<String> bucketNames = task.getBuckets(); systemBuckets = Sets.newHashSet(); systemBuckets.addAll(bucketNames); } } catch (final Exception ex) { throw new Exception("Failed to check the existing buckets", ex); } } String newBucket = null; for (final ImageInfo image : images) { try { if (!(image instanceof MachineImageInfo)) continue; final MachineImageInfo machineImage = (MachineImageInfo) image; final String manifestLocation = machineImage.getManifestLocation(); final String[] tokens = manifestLocation.split("/"); final String bucketName = tokens[0]; final String prefix = tokens[1].replace(".manifest.xml", ""); do { newBucket = String.format( "%s-%s-%s", BUCKET_PREFIX, Crypto.generateAlphanumericId(5, ""), bucketName); if (newBucket.length() > 63) { newBucket = String.format("%s-%s", BUCKET_PREFIX, Crypto.generateAlphanumericId(8, "")); } newBucket = newBucket.toLowerCase(); } while (systemBuckets.contains(newBucket)); try { final CreateBucketTask task = new CreateBucketTask(newBucket); final CheckedListenableFuture<Boolean> result = task.dispatch(); if (result.get()) {; } } catch (final Exception ex) { throw new Exception("Failed to create a system-owned bucket for converted image", ex); } // set run manifest path final String runManifestPath = String.format("%s/%s.manifest.xml", newBucket, prefix); try { machineImage.setRunManifestLocation(runManifestPath); Images.setRunManifestLocation(machineImage.getDisplayName(), runManifestPath); } catch (final Exception ex) { throw new Exception("Failed to update run manifest location"); } } catch (final Exception ex) { LOG.error( String.format( "Unable to create the bucket %s for image %s", newBucket, image.getDisplayName())); resetImagePendingAvailable(image.getDisplayName(), "Failed to create bucket"); throw ex; } } }