Skip to content

Commit

Permalink
deleteOnTerminate and related BFE fixes RT: #5055, fix to resource id…
Browse files Browse the repository at this point in the history
… collision rate, remove uses of broken Threads.enqueue(Runnable)
  • Loading branch information
chris grzegorczyk committed Jan 6, 2012
2 parents ca74cb0 + 2df7b8b commit 917f7a3
Show file tree
Hide file tree
Showing 20 changed files with 160 additions and 150 deletions.
Expand Up @@ -26,6 +26,7 @@
import com.eucalyptus.crypto.Signatures;
import com.eucalyptus.records.EventRecord;
import com.eucalyptus.records.EventType;
import com.google.common.primitives.Longs;

public class DefaultCryptoProvider implements CryptoProvider, CertificateProvider, HmacProvider {
public static String KEY_ALGORITHM = "RSA";
Expand Down Expand Up @@ -192,12 +193,18 @@ public String generateSystemToken( byte[] data ) {
}

@Override
public String generateId( final String userId, final String prefix ) {
public String generateId( final String seed, final String prefix ) {
Adler32 hash = new Adler32( );
String key = userId + (System.currentTimeMillis( ) * Math.random( ));
String key = seed;
hash.update( key.getBytes( ) );
String imageId = String.format( "%s-%08X", prefix, hash.getValue( ) );
return imageId;
/**
* @see http://tools.ietf.org/html/rfc3309
*/
for ( int i = key.length( ); i < 128; i += 8 ) {
hash.update( Longs.toByteArray( Double.doubleToRawLongBits( System.currentTimeMillis( ) * Math.random( ) ) ) );
}
String id = String.format( "%s-%08X", prefix, hash.getValue( ) );
return id;
}

@Override
Expand Down
Expand Up @@ -101,6 +101,7 @@
import com.eucalyptus.vm.VmInstance;
import com.eucalyptus.vm.VmInstance.VmState;
import com.eucalyptus.vm.VmInstances;
import com.eucalyptus.vm.VmVolumeAttachment;
import com.eucalyptus.ws.client.ServiceDispatcher;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
Expand Down Expand Up @@ -246,11 +247,11 @@ public DescribeVolumesResponseType DescribeVolumes( DescribeVolumesType request
try {

final Map<String, AttachedVolume> attachedVolumes = new HashMap<String, AttachedVolume>( );
for ( VmInstance vm : VmInstances.list( Predicates.not( VmState.TERMINATED ) ) ) {
vm.eachVolumeAttachment( new Predicate<AttachedVolume>( ) {
for ( final VmInstance vm : VmInstances.list( Predicates.not( VmState.TERMINATED ) ) ) {
vm.eachVolumeAttachment( new Predicate<VmVolumeAttachment>( ) {
@Override
public boolean apply( AttachedVolume arg0 ) {
return attachedVolumes.put( arg0.getVolumeId( ), arg0 ) == null;
public boolean apply( VmVolumeAttachment arg0 ) {
return attachedVolumes.put( arg0.getVolumeId( ), VmVolumeAttachment.asAttachedVolume( vm ).apply( arg0 ) ) == null;
}
} );
}
Expand Down Expand Up @@ -354,7 +355,7 @@ public AttachVolumeResponseType AttachVolume( AttachVolumeType request ) throws
AttachedVolume attachVol = new AttachedVolume( volume.getDisplayName( ), vm.getInstanceId( ), request.getDevice( ), request.getRemoteDevice( ) );
volume.setState( State.BUSY );
attachVol.setStatus( "attaching" );
vm.addVolumeAttachment( attachVol );
vm.addTransientVolume( attachVol );
AsyncRequests.newRequest( new VolumeAttachCallback( request, attachVol ) ).dispatch( cluster.getConfiguration( ) );

EventRecord.here( VolumeManager.class, EventClass.VOLUME, EventType.VOLUME_ATTACH )
Expand Down
Expand Up @@ -188,7 +188,7 @@ public static Volume lookup( final OwnerFullName ownerFullName, final String vol
}

public static Volume createStorageVolume( final ServiceConfiguration sc, final UserFullName owner, final String snapId, final Integer newSize, final BaseMessage request ) throws ExecutionException {
final String newId = Crypto.generateId( owner.getAccountNumber( ), ID_PREFIX );
final String newId = Crypto.generateId( owner.getUniqueId( ), ID_PREFIX );
final Volume newVol = Transactions.save( Volume.create( sc, owner, snapId, newSize, newId ), new Callback<Volume>( ) {

@Override
Expand Down
Expand Up @@ -64,10 +64,10 @@
package com.eucalyptus.cloud.run;

import java.util.NoSuchElementException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import javax.persistence.EntityTransaction;
import org.apache.log4j.Logger;
import com.eucalyptus.address.Address;
import com.eucalyptus.blockstorage.Volume;
import com.eucalyptus.blockstorage.Volumes;
import com.eucalyptus.cloud.ResourceToken;
Expand All @@ -94,8 +94,6 @@
import com.eucalyptus.records.EventType;
import com.eucalyptus.records.Logs;
import com.eucalyptus.system.Threads;
import com.eucalyptus.util.Callback;
import com.eucalyptus.util.Callback.Success;
import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.util.Exceptions;
import com.eucalyptus.util.LogUtil;
Expand All @@ -115,7 +113,6 @@
import edu.ucsb.eucalyptus.cloud.VmRunResponseType;
import edu.ucsb.eucalyptus.msgs.AttachStorageVolumeResponseType;
import edu.ucsb.eucalyptus.msgs.AttachStorageVolumeType;
import edu.ucsb.eucalyptus.msgs.BaseMessage;
import edu.ucsb.eucalyptus.msgs.BlockDeviceMappingItemType;
import edu.ucsb.eucalyptus.msgs.DescribeStorageVolumesResponseType;
import edu.ucsb.eucalyptus.msgs.DescribeStorageVolumesType;
Expand Down Expand Up @@ -151,15 +148,16 @@ public boolean apply( final Allocation allocInfo ) {
try {
EventRecord.here( ClusterAllocator.class, EventType.VM_PREPARE, LogUtil.dumpObject( allocInfo ) ).info( );
final ServiceConfiguration config = Topology.lookup( ClusterController.class, allocInfo.getPartition( ) );
final Runnable runnable = new Runnable( ) {
final Callable<Boolean> runnable = new Callable<Boolean>( ) {
@Override
public void run( ) {
public Boolean call( ) {
try {
new ClusterAllocator( allocInfo ).run( );
} catch ( final Exception ex ) {
LOG.warn( "Failed to prepare allocator for: " + allocInfo.getAllocationTokens( ) );
LOG.error( "Failed to prepare allocator for: " + allocInfo.getAllocationTokens( ), ex );
}
return Boolean.TRUE;
}
};
Threads.enqueue( config, 32, runnable );
Expand Down Expand Up @@ -240,7 +238,11 @@ private void setupVolumeMessages( ) throws NoSuchElementException, MetadataExcep
Volume vol = null;
if ( !vm.getBootRecord( ).hasPersistentVolumes( ) ) {
vol = Volumes.createStorageVolume( sc, this.allocInfo.getOwnerFullName( ), imgInfo.getSnapshotId( ), sizeGb, this.allocInfo.getRequest( ) );
vm.addPersistentVolume( "/dev/sda1", vol );
if ( deleteOnTerminate ) {
vm.addPersistentVolume( "/dev/sda1", vol );
} else {
vm.addPermanentVolume( "/dev/sda1", vol );
}
} else {
final VmVolumeAttachment volumeAttachment = vm.getBootRecord( ).getPersistentVolumes( ).iterator( ).next( );
vol = Volumes.lookup( null, volumeAttachment.getVolumeId( ) );
Expand Down
Expand Up @@ -24,6 +24,7 @@
import com.eucalyptus.vm.VmType;
import com.eucalyptus.vm.VmTypes;
import com.google.common.base.Function;
import com.eucalyptus.vm.VmVolumeAttachment;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
Expand All @@ -34,7 +35,6 @@
import edu.ucsb.eucalyptus.cloud.VmDescribeResponseType;
import edu.ucsb.eucalyptus.cloud.VmDescribeType;
import edu.ucsb.eucalyptus.cloud.VmInfo;
import edu.ucsb.eucalyptus.msgs.AttachedVolume;
import edu.ucsb.eucalyptus.msgs.VmTypeInfo;

public class VmStateCallback extends StateUpdateMessageCallback<Cluster, VmDescribeType, VmDescribeResponseType> {
Expand Down Expand Up @@ -227,9 +227,9 @@ private static Predicate<VmInstance> volumeFilter( ) {

@Override
public boolean apply( VmInstance input ) {
return input.eachVolumeAttachment( new Predicate<AttachedVolume>( ) {
return input.eachVolumeAttachment( new Predicate<VmVolumeAttachment>( ) {
@Override
public boolean apply( AttachedVolume arg0 ) {
public boolean apply( VmVolumeAttachment arg0 ) {
return arg0.getStatus( ).endsWith( "ing" );
}
} );
Expand Down
Expand Up @@ -79,7 +79,6 @@
import org.w3c.dom.NodeList;
import com.eucalyptus.auth.Accounts;
import com.eucalyptus.auth.AuthException;
import com.eucalyptus.auth.policy.PolicySpec;
import com.eucalyptus.auth.util.Hashes;
import com.eucalyptus.blockstorage.WalrusUtil;
import com.eucalyptus.cloud.ImageMetadata;
Expand All @@ -89,6 +88,7 @@
import com.eucalyptus.component.id.Eucalyptus;
import com.eucalyptus.context.Context;
import com.eucalyptus.context.Contexts;
import com.eucalyptus.crypto.Crypto;
import com.eucalyptus.entities.EntityWrapper;
import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.util.FullName;
Expand All @@ -103,20 +103,12 @@
public class ImageUtil {
private static Logger LOG = Logger.getLogger( ImageUtil.class );

public static String generateImageId( final String imagePrefix, final String imageLocation ) {
Adler32 hash = new Adler32( );
String key = imageLocation + System.currentTimeMillis( );
hash.update( key.getBytes( ) );
String imageId = String.format( "%s-%08X", imagePrefix, hash.getValue( ) );
return imageId;
}

public static String newImageId( final String imagePrefix, final String imageLocation ) {
EntityWrapper<ImageInfo> db = EntityWrapper.get( ImageInfo.class );
String testId = generateImageId( imagePrefix, imageLocation );
String testId = Crypto.generateId( imageLocation, imagePrefix );
ImageInfo query = Images.exampleWithImageId( testId );
LOG.info( "Trying to lookup using created AMI id=" + query.getDisplayName( ) );
for ( ; db.query( query ).size( ) != 0; query.setDisplayName( generateImageId( imagePrefix, imageLocation ) ) );
for ( ; db.query( query ).size( ) != 0; query.setDisplayName( Crypto.generateId( imageLocation, imagePrefix ) ) );
db.commit( );
LOG.info( "Assigning imageId=" + query.getDisplayName( ) );
return query.getDisplayName( );
Expand Down
Expand Up @@ -17,6 +17,7 @@
import com.eucalyptus.cloud.ImageMetadata.StaticDiskImage;
import com.eucalyptus.context.Context;
import com.eucalyptus.context.Contexts;
import com.eucalyptus.crypto.Crypto;
import com.eucalyptus.entities.EntityWrapper;
import com.eucalyptus.entities.TransactionExecutionException;
import com.eucalyptus.entities.Transactions;
Expand Down Expand Up @@ -111,25 +112,6 @@ public Long apply( final OwnerFullName input ) {
}
}

private static String generateImageId( final String imagePrefix, final String imageLocation ) {
Adler32 hash = new Adler32( );
String key = imageLocation + System.currentTimeMillis( );
hash.update( key.getBytes( ) );
String imageId = String.format( "%s-%08X", imagePrefix, hash.getValue( ) );
return imageId;
}

private static String newImageId( final String imagePrefix, final String imageLocation ) {
EntityWrapper<ImageInfo> db = EntityWrapper.get( ImageInfo.class );
String testId = generateImageId( imagePrefix, imageLocation );
ImageInfo query = Images.exampleWithImageId( testId );
LOG.info( "Trying to lookup using created AMI id=" + query.getDisplayName( ) );
for ( ; db.query( query ).size( ) != 0; query.setDisplayName( generateImageId( imagePrefix, imageLocation ) ) );
db.commit( );
LOG.info( "Assigning imageId=" + query.getDisplayName( ) );
return query.getDisplayName( );
}

@TypeMapper
public enum KernelImageDetails implements Function<KernelImageInfo, ImageDetails> {
INSTANCE;
Expand Down Expand Up @@ -454,7 +436,7 @@ public static ImageInfo createFromDeviceMapping( UserFullName userFullName, Stri
: snapVolumeSize;
Long imageSizeBytes = targetVolumeSizeGB * 1024l * 1024l * 1024l;
Boolean targetDeleteOnTermination = Boolean.TRUE.equals( rootBlockDevice.getEbs( ).getDeleteOnTermination( ) );
String imageId = generateImageId( ImageMetadata.Type.machine.getTypePrefix( ), snapshotId );
String imageId = Crypto.generateId( snapshotId, ImageMetadata.Type.machine.getTypePrefix( ) );

BlockStorageImageInfo ret = new BlockStorageImageInfo( userFullName, imageId, imageName, imageDescription, imageSizeBytes,
imageArch, imagePlatform,
Expand Down
Expand Up @@ -231,10 +231,10 @@ public enum VmStateSet implements Predicate<VmInstance> {

@Override
public boolean apply( final VmInstance arg0 ) {
return super.apply( arg0 ) || !arg0.eachVolumeAttachment( new Predicate<AttachedVolume>( ) {
return super.apply( arg0 ) || !arg0.eachVolumeAttachment( new Predicate<VmVolumeAttachment>( ) {
@Override
public boolean apply( final AttachedVolume arg0 ) {
return !arg0.getStatus( ).endsWith( "ing" );
public boolean apply( final VmVolumeAttachment input ) {
return !input.getStatus( ).endsWith( "ing" );
}
} );
}
Expand Down Expand Up @@ -1372,25 +1372,37 @@ public AttachedVolume lookupVolumeAttachment( final String volumeId ) {
/**
* @param attachVol
*/
public void addVolumeAttachment( final AttachedVolume vol ) {
public void addTransientVolume( AttachedVolume attachVol ) {
final EntityTransaction db = Entities.get( VmInstance.class );
try {
final VmInstance entity = Entities.merge( this );
vol.setStatus( "attaching" );
entity.getTransientVolumeState( ).addVolumeAttachment( VmVolumeAttachment.fromAttachedVolume( entity ).apply( vol ) );
attachVol.setStatus( "attaching" );
entity.getTransientVolumeState( ).addVolumeAttachment( VmVolumeAttachment.fromTransientAttachedVolume( entity ).apply( attachVol ) );
db.commit( );
} catch ( final Exception ex ) {
Logs.exhaust( ).error( ex, ex );
db.rollback( );
}

}

public void addPersistentVolume( final String deviceName, final Volume vol ) {
final EntityTransaction db = Entities.get( VmInstance.class );
try {
final VmInstance entity = Entities.merge( this );
final VmVolumeAttachment volumeAttachment = new VmVolumeAttachment( entity, vol.getDisplayName( ), deviceName, vol.getRemoteDevice( ), "attached", new Date( ) );
final VmVolumeAttachment volumeAttachment = new VmVolumeAttachment( entity, vol.getDisplayName( ), deviceName, vol.getRemoteDevice( ), "attached", new Date( ), true );
entity.bootRecord.getPersistentVolumes( ).add( volumeAttachment );
db.commit( );
} catch ( final Exception ex ) {
Logs.exhaust( ).error( ex, ex );
db.rollback( );
}
}

public void addPermanentVolume( final String deviceName, final Volume vol ) {
final EntityTransaction db = Entities.get( VmInstance.class );
try {
final VmInstance entity = Entities.merge( this );
final VmVolumeAttachment volumeAttachment = new VmVolumeAttachment( entity, vol.getDisplayName( ), deviceName, vol.getRemoteDevice( ), "attached", new Date( ), false );
entity.bootRecord.getPersistentVolumes( ).add( volumeAttachment );
db.commit( );
} catch ( final Exception ex ) {
Expand All @@ -1403,22 +1415,22 @@ public void addPersistentVolume( final String deviceName, final Volume vol ) {
* @param predicate
* @return
*/
public boolean eachVolumeAttachment( final Predicate<AttachedVolume> predicate ) {
public boolean eachVolumeAttachment( final Predicate<VmVolumeAttachment> predicate ) {
final EntityTransaction db = Entities.get( VmInstance.class );
try {
final VmInstance entity = Entities.merge( this );
boolean ret = entity.getTransientVolumeState( ).eachVolumeAttachment( new Predicate<VmVolumeAttachment>( ) {

@Override
public boolean apply( final VmVolumeAttachment arg0 ) {
return predicate.apply( VmVolumeAttachment.asAttachedVolume( entity ).apply( arg0 ) );
return predicate.apply( arg0 );
}
} );
ret |= Iterables.all( entity.getBootRecord( ).getPersistentVolumes( ), new Predicate<VmVolumeAttachment>( ) {

@Override
public boolean apply( final VmVolumeAttachment arg0 ) {
return predicate.apply( VmVolumeAttachment.asAttachedVolume( entity ).apply( arg0 ) );
return predicate.apply( arg0 );
}
} );
db.commit( );
Expand Down Expand Up @@ -1655,9 +1667,7 @@ public RunningInstancesItemType apply( final VmInstance v ) {

runningInstance.setLaunchTime( input.getLaunchRecord( ).getLaunchTime( ) );

if ( !input.getBootRecord( ).hasPersistentVolumes( ) ) {
runningInstance.getBlockDevices( ).add( new InstanceBlockDeviceMapping( "/dev/sda1" ) );
} else {
if ( input.getBootRecord( ).hasPersistentVolumes( ) ) {
for ( final VmVolumeAttachment attachedVol : input.getBootRecord( ).getPersistentVolumes( ) ) {
runningInstance.getBlockDevices( ).add( new InstanceBlockDeviceMapping( attachedVol.getDevice( ), attachedVol.getVolumeId( ),
attachedVol.getStatus( ),
Expand Down Expand Up @@ -1795,5 +1805,6 @@ public Integer getLaunchIndex( ) {
public SshKeyPair getKeyPair( ) {
return this.getBootRecord( ).getSshKeyPair( );
}


}

0 comments on commit 917f7a3

Please sign in to comment.