/************************************************************************* * Copyright 2013-2014 Eucalyptus Systems, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need * additional information or have any questions. ************************************************************************/ package com.eucalyptus.imaging.backend; import java.util.Date; import java.util.List; import java.util.NoSuchElementException; import javax.annotation.Nullable; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; import javax.persistence.PersistenceContext; import org.apache.log4j.Logger; import com.eucalyptus.blockstorage.Volumes; import com.eucalyptus.compute.common.ConversionTask; import com.eucalyptus.compute.common.DiskImageDescription; import com.eucalyptus.compute.common.DiskImageDetail; import com.eucalyptus.compute.common.DiskImageVolume; import com.eucalyptus.compute.common.DiskImageVolumeDescription; import com.eucalyptus.compute.common.ImportVolumeTaskDetails; import com.eucalyptus.compute.common.Volume; import com.eucalyptus.compute.common.backend.ImportVolumeType; import com.eucalyptus.compute.common.internal.identifier.ResourceIdentifiers; import com.eucalyptus.context.Context; import com.eucalyptus.context.Contexts; import com.eucalyptus.imaging.ImportTaskProperties; import com.eucalyptus.resources.client.Ec2Client; import com.eucalyptus.util.Dates; import com.eucalyptus.auth.principal.OwnerFullName; import com.eucalyptus.util.TypeMapper; import com.google.common.base.Function; import com.google.common.collect.Lists; @Entity @PersistenceContext( name = "eucalyptus_imaging" ) @DiscriminatorValue( value = "volume-imaging-task" ) public class ImportVolumeImagingTask extends VolumeImagingTask { private static Logger LOG = Logger.getLogger( ImportVolumeImagingTask.class ); protected ImportVolumeImagingTask( ) {} protected ImportVolumeImagingTask(final OwnerFullName owner, final String taskId){ super(owner, taskId); } protected ImportVolumeImagingTask( OwnerFullName ownerFullName, ConversionTask conversionTask) { super( ownerFullName, conversionTask, ImportTaskState.NEW, 0L ); } public static ImportVolumeImagingTask create( final OwnerFullName ownerFullName, final ConversionTask conversionTask ) { return new ImportVolumeImagingTask( ownerFullName, conversionTask); } public static ImportVolumeImagingTask named(final OwnerFullName owner, final String taskId){ return new ImportVolumeImagingTask(owner, taskId); } public String getAvailabilityZone( ) { try{ return this.getTask().getImportVolume().getAvailabilityZone(); }catch(final Exception ex){ return null; } } public String getVolumeId( ) { try{ return this.getTask().getImportVolume().getVolume().getId(); }catch(final Exception ex){ return null; } } public Integer getVolumeSize( ) { try{ return this.getTask().getImportVolume().getVolume().getSize(); }catch(final Exception ex){ return null; } } public void setVolumeId( String volumeId ) { this.getTask().getImportVolume( ).getVolume( ).setId( volumeId ); this.serializeTaskToJSON(); } private void setVolumeSize( Integer volumeSize ) { this.getTask().getImportVolume().getVolume().setSize(volumeSize); this.serializeTaskToJSON(); } private void setAvailabilityZone( String availabilityZone ) { this.getTask().getImportVolume().setAvailabilityZone(availabilityZone); this.serializeTaskToJSON(); } public String getFormat( ) { try{ return this.getTask().getImportVolume().getImage().getFormat(); }catch(final Exception ex){ return null; } } public void setFormat( String format ) { this.getTask().getImportVolume().getImage().setFormat(format); this.serializeTaskToJSON(); } public Long getBytes( ) { try{ return this.getTask().getImportVolume().getBytesConverted(); }catch(final Exception ex){ return null; } } public void setBytes( Long bytes ) { this.getTask().getImportVolume().setBytesConverted(bytes); this.serializeTaskToJSON(); } public String getImportManifestUrl( ) { try{ return this.getTask().getImportVolume().getImage().getImportManifestUrl(); }catch(final Exception ex){ return null; } } public void setImportManifestUrl( String importManifestUrl ) { this.getTask().getImportVolume().getImage().setImportManifestUrl(importManifestUrl); this.serializeTaskToJSON(); } public String getDescription( ) { try{ return this.getTask().getImportVolume().getDescription(); }catch(final Exception ex){ return null; } } public void setDescription( String description ) { this.getTask().getImportVolume().setDescription(description); this.serializeTaskToJSON(); } @Override public boolean cleanUp(){ if (getCleanUpDone()) return true; final ImportVolumeTaskDetails volumeDetails = this.getTask().getImportVolume(); if(volumeDetails.getVolume()!=null && volumeDetails.getVolume().getId()!=null){ String volumeId = volumeDetails.getVolume().getId(); try{ // verify that volume actually exist Volumes.setSystemManagedFlag(null, volumeId, false); final List<Volume> eucaVolumes = Ec2Client.getInstance().describeVolumes(this.getOwnerUserId(), Lists.newArrayList(volumeId)); if (eucaVolumes.size() != 0) { Ec2Client.getInstance().deleteVolume(this.getOwnerUserId(), volumeId); } setCleanUpDone(true); } catch(final NoSuchElementException ex) { LOG.debug("Can't find volume with ID " + volumeId + ". Probably it was already deleted"); setCleanUpDone(true); } catch(final Exception ex){ LOG.error(ex); LOG.warn(String.format("Failed to delete the volume %s for import task %s", volumeDetails.getVolume().getId(), this.getDisplayName())); } } return true; } @TypeMapper enum VolumeImagingTaskTransform implements Function<ImportVolumeType, ImportVolumeImagingTask> { INSTANCE; @Nullable @Override public ImportVolumeImagingTask apply( @Nullable final ImportVolumeType request ) { final DiskImageDetail imageDetails = request.getImage( ); final DiskImageVolume volumeDetails = request.getVolume( ); Context ctx = Contexts.lookup( ); String conversionTaskId = ResourceIdentifiers.generateString("import-vol"); conversionTaskId = conversionTaskId.toLowerCase(); ConversionTask conversionTask = new ConversionTask( ); conversionTask.setConversionTaskId( conversionTaskId ); conversionTask.setExpirationTime( new Date( Dates.hoursFromNow( Integer.parseInt(ImportTaskProperties.IMPORT_TASK_EXPIRATION_HOURS) ).getTime( ) ).toString( ) ); conversionTask.setState( ImportTaskState.NEW.getExternalTaskStateName() ); conversionTask.setStatusMessage( "" ); // conversionTask.setResourceTagSet( request.get );//GRZE:TODO: fill this in, where the hell does it come from? final DiskImageVolumeDescription volumeImageDescription = new DiskImageVolumeDescription( ) { { this.setSize( volumeDetails.getSize( ) ); } }; final DiskImageDescription diskImageDescription = new DiskImageDescription( ) { { ///TODO: remove this later String manifestUrl = imageDetails.getImportManifestUrl( ); this.setImportManifestUrl( manifestUrl ); this.setFormat( imageDetails.getFormat( ) ); this.setSize( imageDetails.getBytes( ) ); } }; ImportVolumeTaskDetails volumeTaskDetails = new ImportVolumeTaskDetails( ) { { this.setAvailabilityZone( request.getAvailabilityZone( ) ); this.setBytesConverted( 0L ); this.setDescription( request.getDescription( ) ); } }; volumeTaskDetails.setImage( diskImageDescription ); volumeTaskDetails.setVolume( volumeImageDescription ); conversionTask.setImportVolume( volumeTaskDetails ); return create( ctx.getUserFullName( ), conversionTask); } } }