Skip to content

Commit

Permalink
Fixes EUCA-2208
Browse files Browse the repository at this point in the history
Add support to restart instance once bundling is completed
  • Loading branch information
gelinasc committed Oct 5, 2012
1 parent 8f7b796 commit 2aa5bdd
Show file tree
Hide file tree
Showing 25 changed files with 835 additions and 146 deletions.
Expand Up @@ -131,6 +131,35 @@ public void fire( CancelBundleTaskResponseType reply ) {
}
}

public static MessageCallback bundleRestartInstanceCallback( BundleRestartInstanceType request ) {
return new BundleRestartInstanceCallback( request );
}

public static class BundleRestartInstanceCallback extends MessageCallback<BundleRestartInstanceType, BundleRestartInstanceResponseType> {
private BundleRestartInstanceCallback( BundleRestartInstanceType request ) {
super( request );
}

@Override
public void fire( BundleRestartInstanceResponseType reply ) {
if ( !reply.get_return( ) ) {
LOG.info( "Attempt to restart bundle instance " + this.getRequest( ).getInstanceId( ) + " has failed." );
} else {
EntityTransaction db = Entities.get( VmInstance.class );
try {
VmInstance vm = VmInstances.lookup( this.getRequest( ).getInstanceId( ) );
vm.getRuntimeState( ).restartBundleTask( );
EventRecord.here( CancelBundleCallback.class, EventType.BUNDLE_RESTART, this.getRequest( ).toSimpleString( ), vm.getRuntimeState( ).getBundleTask( ).getBundleId( ),
vm.getInstanceId( ) ).info( );
db.commit( );
} catch ( Exception ex ) {
Logs.exhaust( ).error( ex, ex );
db.rollback( );
}
}
}
}

public static class BundleCallback extends MessageCallback<BundleInstanceType, BundleInstanceResponseType> {
private BundleCallback( BundleInstanceType request ) {
super( request );
Expand Down
Expand Up @@ -103,6 +103,14 @@ public class BundleInstanceType extends VmBundleMessage {
public class BundleInstanceResponseType extends VmBundleMessage {
BundleTask task;
}

public class BundleRestartInstanceType extends VmBundleMessage {
String instanceId;
}
public class BundleRestartInstanceResponseType extends VmBundleMessage {
BundleTask task;
}

public class CancelBundleTaskType extends VmBundleMessage {
String bundleId;
String instanceId;
Expand Down
Expand Up @@ -73,7 +73,7 @@
@Embeddable
public class VmBundleTask {
public enum BundleState {
none( "none" ), pending( null ), storing( "bundling" ), canceling( null ), complete( "succeeded" ), failed( "failed" );
none( "none" ), pending( null ), storing( "bundling" ), canceling( null ), cancelled( "cancelled" ), complete( "succeeded" ), failed( "failed" );
private String mappedState;

BundleState( final String mappedState ) {
Expand Down
Expand Up @@ -396,32 +396,44 @@ public Boolean cancelBundleTask( ) {
}
}

public Boolean submittedBundleTask( ) {
if ( this.getBundleTask( ) != null && this.getBundleTask( ).getState( ).ordinal( ) >= BundleState.storing.ordinal( ) ) {
this.getBundleTask( ).setState( BundleState.storing );
EventRecord.here( VmRuntimeState.class, EventType.BUNDLE_STARTING,
this.vmInstance.getOwner( ).toString( ),
this.getBundleTask( ).getBundleId( ),
this.getVmInstance( ).getInstanceId( ),
"" + this.getBundleTask( ).getState( ) ).info( );
return true;
} else if ( BundleState.canceling.equals( this.getBundleTaskState( ) ) ) {
EventRecord.here( VmRuntimeState.class, EventType.BUNDLE_CANCELLED, this.vmInstance.getOwner( ).toString( ), this.getBundleTask( ).getBundleId( ),
public Boolean restartBundleTask( ) {
if ( this.getBundleTask( ) != null ) {
this.getBundleTask( ).setState( BundleState.none );
EventRecord.here( VmRuntimeState.class, EventType.BUNDLE_RESTART, this.vmInstance.getOwner( ).toString( ), this.getBundleTask( ).getBundleId( ),
this.getVmInstance( ).getInstanceId( ),
"" + this.getBundleTask( ).getState( ) ).info( );
this.resetBundleTask( );
return true;
} else {
return false;
}
return false;
}

public Boolean submittedBundleTask( ) {
if ( this.getBundleTask( ) != null ) {
if ( BundleState.cancelled.equals( this.getBundleTaskState( ) ) ) {
EventRecord.here( VmRuntimeState.class, EventType.BUNDLE_CANCELLED, this.vmInstance.getOwner( ).toString( ), this.getBundleTask( ).getBundleId( ),
this.getVmInstance( ).getInstanceId( ),
"" + this.getBundleTask( ).getState( ) ).info( );
this.resetBundleTask( );
return true;
} else if ( this.getBundleTask( ).getState( ).ordinal( ) >= BundleState.storing.ordinal( ) ) {
this.getBundleTask( ).setState( BundleState.storing );
EventRecord.here( VmRuntimeState.class, EventType.BUNDLE_STARTING,
this.vmInstance.getOwner( ).toString( ),
this.getBundleTask( ).getBundleId( ),
this.getVmInstance( ).getInstanceId( ),
"" + this.getBundleTask( ).getState( ) ).info( );
return true;
}
}
return false;
}

public Boolean startBundleTask( final VmBundleTask task ) {
if ( !this.isBundling( ) ) {
this.bundleTask = task;
return true;
} else {
if ( ( this.getBundleTask( ) != null ) && ( BundleState.failed.equals( task.getState() ) || BundleState.canceling.equals( task.getState() ) ) ) {
if ( ( this.getBundleTask( ) != null ) && ( BundleState.failed.equals( task.getState() ) || BundleState.canceling.equals( task.getState() ) || BundleState.cancelled.equals( task.getState() ) ) ) {
this.resetBundleTask( );
this.bundleTask = task;
return true;
Expand Down Expand Up @@ -496,14 +508,43 @@ public void updateBundleTaskState( String state ) {
updateBundleTaskState( next );
}

public void bundleRestartInstance(VmBundleTask bundleTask) {
BundleState state = bundleTask.getState();
if(BundleState.complete.equals(state) || BundleState.failed.equals(state) || BundleState.cancelled.equals(state)) {
final BundleRestartInstanceType request = new BundleRestartInstanceType();
final BundleRestartInstanceResponseType reply = request.getReply();

reply.set_return(true);
try {
LOG.info(EventRecord.here(BundleCallback.class, EventType.BUNDLE_RESTART, vmInstance.getOwner().getUserName(),
bundleTask.getBundleId(),
vmInstance.getInstanceId()));

ServiceConfiguration ccConfig = Topology.lookup(ClusterController.class, vmInstance.lookupPartition());
final Cluster cluster = Clusters.lookup(ccConfig );

request.setInstanceId(vmInstance.getInstanceId());
reply.setTask(Bundles.transform(bundleTask));
AsyncRequests.newRequest(Bundles.bundleRestartInstanceCallback(request)).dispatch(cluster.getConfiguration());
} catch (final Exception e) {
Logs.extreme().trace("Failed to find bundle task: " + bundleTask.getBundleId());
}
}
}

public void updateBundleTaskState( BundleState state ) {
if ( this.getBundleTask( ) != null ) {
final BundleState current = this.getBundleTask( ).getState( );
if ( BundleState.complete.equals( state ) && !BundleState.complete.equals( current ) ) {
if ( BundleState.complete.equals( state ) && !BundleState.complete.equals( current ) && !BundleState.none.equals( current )) {
this.getBundleTask( ).setState( state );
bundleRestartInstance(this.getBundleTask());
} else if ( BundleState.failed.equals( state ) && !BundleState.failed.equals( current ) && !BundleState.none.equals( current )) {
this.getBundleTask( ).setState( state );
} else if ( BundleState.failed.equals( state ) && !BundleState.failed.equals( current ) ) {
bundleRestartInstance(this.getBundleTask());
} else if ( BundleState.cancelled.equals( state ) && !BundleState.cancelled.equals( current ) && !BundleState.none.equals( current )) {
this.getBundleTask( ).setState( state );
} else if ( BundleState.canceling.equals( current ) || BundleState.canceling.equals( state ) ) {
bundleRestartInstance(this.getBundleTask());
} else if ( BundleState.canceling.equals( state ) || BundleState.canceling.equals( current ) ) {
//
} else if ( BundleState.pending.equals( current ) && !BundleState.none.equals( state ) ) {
this.getBundleTask( ).setState( state );
Expand Down
Expand Up @@ -112,6 +112,7 @@ public enum EventType {
BUNDLE_RESET,
BUNDLE_STARTED,
BUNDLE_STARTING,
BUNDLE_RESTART,
BUNDLE_TRANSITION,
CERTIFICATE_WRITE,
CHANNEL_WRITE,
Expand Down
8 changes: 7 additions & 1 deletion clc/modules/msgs/src/main/resources/cc-vms.xml
Expand Up @@ -225,6 +225,12 @@
<mapping name="BundleInstanceResponse" class="com.eucalyptus.vm.BundleInstanceResponseType" extends="edu.ucsb.eucalyptus.msgs.EucalyptusMessage">
<structure map-as="edu.ucsb.eucalyptus.msgs.EucalyptusMessage" />
</mapping>
<mapping name="BundleRestartInstance" class="com.eucalyptus.vm.BundleRestartInstanceType" extends="edu.ucsb.eucalyptus.msgs.EucalyptusMessage">
<value name="instanceId" field="instanceId" usage="required" />
</mapping>
<mapping name="BundleRestartInstanceResponse" class="com.eucalyptus.vm.BundleRestartInstanceResponseType" extends="edu.ucsb.eucalyptus.msgs.EucalyptusMessage">
<structure map-as="edu.ucsb.eucalyptus.msgs.EucalyptusMessage" />
</mapping>
<mapping name="CancelBundleTask" class="com.eucalyptus.vm.CancelBundleTaskType" extends="edu.ucsb.eucalyptus.msgs.EucalyptusMessage">
<value name="instanceId" field="instanceId" usage="required" />
</mapping>
Expand All @@ -240,4 +246,4 @@
<structure map-as="edu.ucsb.eucalyptus.msgs.EucalyptusMessage" />
<value name="consoleOutput" field="output" />
</mapping>
</binding>
</binding>
6 changes: 6 additions & 0 deletions cluster/CCclient.c
Expand Up @@ -344,6 +344,12 @@ int main(int argc, char **argv) {
printf("cc_bundleInstance() failed\n");
exit(1);
}
} else if (!strcmp(argv[2], "bundleRestartInstance")) {
rc = cc_bundleRestartInstance(argv[3], env, stub);
if (rc != 0) {
printf("cc_bundleRestartInstance() failed\n");
exit(1);
}
} else if (!strcmp(argv[2], "createImage")) {
rc = cc_createImage(argv[3], argv[4], argv[5], env, stub);
if (rc != 0) {
Expand Down
39 changes: 39 additions & 0 deletions cluster/cc-client-marshal-adb.c
Expand Up @@ -570,6 +570,45 @@ int cc_bundleInstance(char *instanceId, char *bucketName, char *filePrefix, char
return(0);
}

int cc_bundleRestartInstance(char *instanceId, axutil_env_t *env, axis2_stub_t *stub) {
int i = 0;
adb_BundleRestartInstance_t *input = NULL;
adb_BundleRestartInstanceResponse_t *output = NULL;
adb_bundleRestartInstanceType_t *sn = NULL;
adb_bundleRestartInstanceResponseType_t *snrt = NULL;

sn = adb_bundleRestartInstanceType_create(env);
input = adb_BundleRestartInstance_create(env);

adb_bundleRestartInstanceType_set_userId(sn, env, "eucalyptus");
{
char cidstr[9] = { 0 };

bzero(cidstr, 9);
srand(time(NULL) + getpid());

for (i = 0; i < 8; i++) {
cidstr[i] = rand() % 26 + 'a';
}

adb_bundleRestartInstanceType_set_correlationId(sn, env, cidstr);
}
adb_bundleRestartInstanceType_set_instanceId(sn, env, instanceId);
adb_BundleRestartInstance_set_BundleRestartInstance(input, env, sn);

if ((output = axis2_stub_op_EucalyptusCC_BundleRestartInstance(stub, env, input)) == NULL) {
printf("ERROR: bundleRestartInstance returned NULL\n");
return(1);
}

snrt = adb_BundleRestartInstanceResponse_get_BundleRestartInstanceResponse(output, env);
printf("bundleRestartInstance returned status %d\n", adb_bundleRestartInstanceResponseType_get_return(snrt, env));

snrt = adb_BundleRestartInstanceResponse_get_BundleRestartInstanceResponse(output, env);
printf("bundleRestartInstance returned status %d\n", adb_bundleRestartInstanceResponseType_get_return(snrt, env));
return(0);
}

int cc_assignAddress(char *src, char *dst, axutil_env_t *env, axis2_stub_t *stub) {
int i;
// char meh[32];
Expand Down
1 change: 1 addition & 0 deletions cluster/cc-client-marshal.h
Expand Up @@ -82,6 +82,7 @@ int cc_attachVolume(char *volumeId, char *instanceId, char *remoteDev, char *loc
int cc_detachVolume(char *volumeId, char *instanceId, char *remoteDev, char *localDev, int force, axutil_env_t *env, axis2_stub_t *stub);

int cc_bundleInstance(char *instanceId, char *bucketName, char *filePrefix, char *walrusURL, char *userPublicKey, axutil_env_t *env, axis2_stub_t *stub);
int cc_bundleRestartInstance(char *instanceId, axutil_env_t *env, axis2_stub_t *stub);

int cc_createImage(char *volumeId, char *instanceId, char *remoteDev, axutil_env_t *env, axis2_stub_t *stub);
int cc_describeSensors (int historySize, long long collectionIntervalTimeMs, char **instIds, int instIdsLen, char **sensorIds, int sensorIdsLen, sensorResource ***outResources, int *outResourcesLen, axutil_env_t *env, axis2_stub_t *stub);
Expand Down
63 changes: 63 additions & 0 deletions cluster/handlers.c
Expand Up @@ -198,6 +198,66 @@ int doBundleInstance(ncMetadata *ccMeta, char *instanceId, char *bucketName, cha
return(ret);
}

int doBundleRestartInstance(ncMetadata *ccMeta, char *instanceId) {
int j = 0;
int rc = 0;
int start = 0;
int stop = 0;
int ret = 0;
int timeout = 0;
int done = 0;
ccInstance *myInstance = NULL;
time_t op_start = time(NULL);
ccResourceCache resourceCacheLocal;

rc = initialize(ccMeta);
if (rc || ccIsEnabled())
return(1);

logprintfl(EUCAINFO, "BundleRestartInstance(): called \n");
logprintfl(EUCADEBUG, "BundleRestartInstance(): params: userId=%s, instanceId=%s\n", SP(ccMeta ? ccMeta->userId : "UNSET"), SP(instanceId));
if (instanceId == NULL) {
logprintfl(EUCAERROR, "BundleRestartInstance(): bad input params\n");
return(1);
}

sem_mywait(RESCACHE);
{
memcpy(&resourceCacheLocal, resourceCache, sizeof(ccResourceCache));
}
sem_mypost(RESCACHE);

if ((rc = find_instanceCacheId(instanceId, &myInstance)) == 0) {
// found the instance in the cache
if (myInstance) {
start = myInstance->ncHostIdx;
stop = start + 1;
free(myInstance);
myInstance = NULL;
}
}
else {
start = 0;
stop = resourceCacheLocal.numResources;
}

done = 0;
for (j = start; ((j < stop) && !done); j++) {
timeout = ncGetTimeout(op_start, OP_TIMEOUT, (stop - start), j);
rc = ncClientCall(ccMeta, timeout, resourceCacheLocal.resources[j].lockidx, resourceCacheLocal.resources[j].ncURL, "ncBundleRestartInstance", instanceId);
if (rc) {
ret = 1;
} else {
ret = 0;
done++;
}
}

logprintfl(EUCADEBUG,"BundleRestartInstance(): done. \n");
shawn();
return(ret);
}

int doCancelBundleTask(ncMetadata *ccMeta, char *instanceId) {
int i, rc, start = 0, stop = 0, ret=0, done, timeout;
ccInstance *myInstance;
Expand Down Expand Up @@ -510,6 +570,9 @@ int ncClientCall(ncMetadata *meta, int timeout, int ncLock, char *ncURL, char *n
char *S3PolicySig = va_arg(al, char *);

rc = ncBundleInstanceStub(ncs, localmeta, instanceId, bucketName, filePrefix, walrusURL, userPublicKey, S3Policy, S3PolicySig);
} else if (!strcmp(ncOp, "ncBundleRestartInstance")) {
char *instanceId = va_arg(al, char *);
rc = ncBundleRestartInstanceStub(ncs, localmeta, instanceId);
} else if (!strcmp(ncOp, "ncCancelBundleTask")) {
char *instanceId = va_arg(al, char *);

Expand Down
1 change: 1 addition & 0 deletions cluster/handlers.h
Expand Up @@ -250,6 +250,7 @@ int doAttachVolume(ncMetadata *ccMeta, char *volumeId, char *instanceId, char *r
int doDetachVolume(ncMetadata *ccMeta, char *volumeId, char *instanceId, char *remoteDev, char *localDev, int force);

int doBundleInstance(ncMetadata *ccMeta, char *instanceId, char *bucketName, char *filePrefix, char *walrusURL, char *userPublicKey, char *S3Policy, char *S3PolicySig);
int doBundleRestartInstance(ncMetadata *ccMeta, char *instanceId);
int doCancelBundleTask(ncMetadata *ccMeta, char *instanceId);

int doAssignAddress(ncMetadata *ccMeta, char *uuid, char *src, char *dst);
Expand Down
37 changes: 37 additions & 0 deletions cluster/server-marshal.c
Expand Up @@ -227,6 +227,43 @@ adb_BundleInstanceResponse_t *BundleInstanceMarshal(adb_BundleInstance_t *bundle
return(ret);
}

adb_BundleRestartInstanceResponse_t * BundleRestartInstanceMarshal(adb_BundleRestartInstance_t *bundleInstance, const axutil_env_t *env) {
int rc = 0;
axis2_bool_t status = AXIS2_TRUE;
char statusMessage[256] = { 0 };
char *instanceId = NULL;
ncMetadata ccMeta = { 0 };
adb_BundleRestartInstanceResponse_t *ret = NULL;
adb_bundleRestartInstanceResponseType_t *birt = NULL;
adb_bundleRestartInstanceType_t *bit = NULL;

bit = adb_BundleRestartInstance_get_BundleRestartInstance(bundleInstance, env);

EUCA_MESSAGE_UNMARSHAL(bundleRestartInstanceType, bit, (&ccMeta));

instanceId = adb_bundleRestartInstanceType_get_instanceId(bit, env);
status = AXIS2_TRUE;
if (!DONOTHING) {
if ((rc = rc = doBundleRestartInstance(&ccMeta, instanceId)) != 0) {
logprintf("ERROR: doBundleRestartInstance() returned FAIL\n");
status = AXIS2_FALSE;
snprintf(statusMessage, 255, "ERROR");
}
}

birt = adb_bundleRestartInstanceResponseType_create(env);
adb_bundleRestartInstanceResponseType_set_return(birt, env, status);
if (status == AXIS2_FALSE)
adb_bundleRestartInstanceResponseType_set_statusMessage(birt, env, statusMessage);

adb_bundleRestartInstanceResponseType_set_correlationId(birt, env, ccMeta.correlationId);
adb_bundleRestartInstanceResponseType_set_userId(birt, env, ccMeta.userId);

ret = adb_BundleRestartInstanceResponse_create(env);
adb_BundleRestartInstanceResponse_set_BundleRestartInstanceResponse(ret, env, birt);
return(ret);
}

adb_CancelBundleTaskResponse_t *CancelBundleTaskMarshal(adb_CancelBundleTask_t *cancelBundleTask, const axutil_env_t *env) {
adb_CancelBundleTaskResponse_t *ret=NULL;
adb_cancelBundleTaskResponseType_t *birt=NULL;
Expand Down
1 change: 1 addition & 0 deletions cluster/server-marshal.h
Expand Up @@ -88,6 +88,7 @@ adb_ConfigureNetworkResponse_t *ConfigureNetworkMarshal(adb_ConfigureNetwork_t *
adb_AttachVolumeResponse_t *AttachVolumeMarshal(adb_AttachVolume_t *attachVolume, const axutil_env_t *env);
adb_DetachVolumeResponse_t *DetachVolumeMarshal(adb_DetachVolume_t *detachVolume, const axutil_env_t *env);
adb_BundleInstanceResponse_t *BundleInstanceMarshal(adb_BundleInstance_t *bundleInstance, const axutil_env_t *env);
adb_BundleRestartInstanceResponse_t *BundleRestartInstanceMarshal(adb_BundleRestartInstance_t *bundleInstance, const axutil_env_t *env);
adb_CancelBundleTaskResponse_t *CancelBundleTaskMarshal(adb_CancelBundleTask_t *cancelBundleInstance, const axutil_env_t *env);
adb_DescribeSensorsResponse_t *DescribeSensorsMarshal(adb_DescribeSensors_t *describeSensors, const axutil_env_t *env);

Expand Down

0 comments on commit 2aa5bdd

Please sign in to comment.