mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
add copycommand at resouce side
This commit is contained in:
parent
29687663e8
commit
b8c5c67fbc
@ -47,8 +47,11 @@ import java.util.concurrent.Callable;
|
|||||||
|
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataTO;
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataTO;
|
||||||
|
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
|
||||||
import org.apache.cloudstack.storage.command.CopyCommand;
|
import org.apache.cloudstack.storage.command.CopyCommand;
|
||||||
|
import org.apache.cloudstack.storage.to.TemplateObjectTO;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.cloud.agent.api.Answer;
|
import com.cloud.agent.api.Answer;
|
||||||
@ -222,7 +225,9 @@ SecondaryStorageResource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Answer downloadFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3,
|
|
||||||
|
protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3,
|
||||||
|
|
||||||
DataTO destData, NfsTO destImageStore) {
|
DataTO destData, NfsTO destImageStore) {
|
||||||
final String storagePath = destImageStore.getUrl();
|
final String storagePath = destImageStore.getUrl();
|
||||||
final String destPath = destData.getPath();
|
final String destPath = destData.getPath();
|
||||||
@ -240,10 +245,10 @@ SecondaryStorageResource {
|
|||||||
+ "download directory %1$s for download from S3.", downloadDirectory.getName()
|
+ "download directory %1$s for download from S3.", downloadDirectory.getName()
|
||||||
);
|
);
|
||||||
s_logger.error(errMsg);
|
s_logger.error(errMsg);
|
||||||
return new Answer(cmd, false, errMsg);
|
return new CopyCmdAnswer(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDirectory(s3, s3.getBucketName(),
|
List<File> files = getDirectory(s3, s3.getBucketName(),
|
||||||
destPath,
|
destPath,
|
||||||
downloadDirectory, new FileNamingStrategy() {
|
downloadDirectory, new FileNamingStrategy() {
|
||||||
@Override
|
@Override
|
||||||
@ -252,20 +257,42 @@ SecondaryStorageResource {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return new Answer(cmd, true, format("Successfully downloaded "
|
//find out template name
|
||||||
+ "from S3 to directory %2$s",
|
File destFile = null;
|
||||||
downloadDirectory.getName()));
|
for (File f : files) {
|
||||||
|
if (!f.getName().endsWith(".properties")) {
|
||||||
|
destFile = f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (destFile == null) {
|
||||||
|
return new CopyCmdAnswer("Can't find template");
|
||||||
|
}
|
||||||
|
|
||||||
|
DataTO newDestTO = null;
|
||||||
|
|
||||||
|
if (destData.getObjectType() == DataObjectType.TEMPLATE) {
|
||||||
|
TemplateObjectTO newTemplTO = new TemplateObjectTO();
|
||||||
|
newTemplTO.setPath(destPath + File.separator + destFile.getName());
|
||||||
|
newTemplTO.setName(destFile.getName());
|
||||||
|
newDestTO = newTemplTO;
|
||||||
|
} else {
|
||||||
|
return new CopyCmdAnswer("not implemented yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CopyCmdAnswer(newDestTO);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
||||||
final String errMsg = format("Failed to download"
|
final String errMsg = format("Failed to download"
|
||||||
+ "due to $2%s", e.getMessage());
|
+ "due to $2%s", e.getMessage());
|
||||||
s_logger.error(errMsg, e);
|
s_logger.error(errMsg, e);
|
||||||
return new Answer(cmd, false, errMsg);
|
return new CopyCmdAnswer(errMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Answer downloadFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO srcImageStore,
|
protected Answer copyFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO srcImageStore,
|
||||||
|
|
||||||
DataTO destData, NfsTO destImageStore) {
|
DataTO destData, NfsTO destImageStore) {
|
||||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||||
}
|
}
|
||||||
@ -286,10 +313,10 @@ SecondaryStorageResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (srcDataStore instanceof S3TO) {
|
if (srcDataStore instanceof S3TO) {
|
||||||
return downloadFromS3ToNfs(cmd, srcData, (S3TO)srcDataStore,
|
return copyFromS3ToNfs(cmd, srcData, (S3TO)srcDataStore,
|
||||||
destData, (NfsTO)destDataStore);
|
destData, (NfsTO)destDataStore);
|
||||||
} else if (srcDataStore instanceof SwiftTO) {
|
} else if (srcDataStore instanceof SwiftTO) {
|
||||||
return downloadFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore,
|
return copyFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore,
|
||||||
destData, (NfsTO)destDataStore);
|
destData, (NfsTO)destDataStore);
|
||||||
} else {
|
} else {
|
||||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||||
|
|||||||
@ -16,18 +16,23 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.storage.command;
|
package org.apache.cloudstack.storage.command;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataTO;
|
||||||
|
|
||||||
import com.cloud.agent.api.Answer;
|
import com.cloud.agent.api.Answer;
|
||||||
import com.cloud.agent.api.Command;
|
|
||||||
|
|
||||||
public class CopyCmdAnswer extends Answer {
|
public class CopyCmdAnswer extends Answer {
|
||||||
private final String path;
|
private DataTO newData;
|
||||||
|
|
||||||
public CopyCmdAnswer(Command cmd, String path) {
|
public CopyCmdAnswer(DataTO newData) {
|
||||||
super(cmd);
|
super(null);
|
||||||
this.path = path;
|
this.newData = newData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPath() {
|
public DataTO getNewData() {
|
||||||
return this.path;
|
return this.newData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CopyCmdAnswer(String errMsg) {
|
||||||
|
super(null, false, errMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,27 +23,13 @@ import com.cloud.agent.api.Command;
|
|||||||
public class CopyCommand extends Command implements StorageSubSystemCommand {
|
public class CopyCommand extends Command implements StorageSubSystemCommand {
|
||||||
private DataTO srcTO;
|
private DataTO srcTO;
|
||||||
private DataTO destTO;
|
private DataTO destTO;
|
||||||
private int timeout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the timeout
|
|
||||||
*/
|
|
||||||
public int getTimeout() {
|
|
||||||
return timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param timeout the timeout to set
|
|
||||||
*/
|
|
||||||
public void setTimeout(int timeout) {
|
|
||||||
this.timeout = timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CopyCommand(DataTO srcUri, DataTO destUri, int timeout) {
|
public CopyCommand(DataTO srcUri, DataTO destUri, int timeout) {
|
||||||
super();
|
super();
|
||||||
this.srcTO = srcUri;
|
this.srcTO = srcUri;
|
||||||
this.destTO = destUri;
|
this.destTO = destUri;
|
||||||
this.timeout = timeout;
|
this.setWait(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTO getDestTO() {
|
public DataTO getDestTO() {
|
||||||
|
|||||||
@ -25,12 +25,15 @@ import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo;
|
|||||||
import com.cloud.agent.api.to.DataStoreTO;
|
import com.cloud.agent.api.to.DataStoreTO;
|
||||||
|
|
||||||
public class TemplateObjectTO implements DataTO {
|
public class TemplateObjectTO implements DataTO {
|
||||||
private final String path;
|
private String path;
|
||||||
private final String uuid;
|
private String uuid;
|
||||||
private DiskFormat diskType;
|
private DiskFormat diskType;
|
||||||
private final ImageStoreTO imageDataStore;
|
private ImageStoreTO imageDataStore;
|
||||||
private final String name;
|
private String name;
|
||||||
|
|
||||||
|
public TemplateObjectTO() {
|
||||||
|
|
||||||
|
}
|
||||||
public TemplateObjectTO(TemplateInfo template) {
|
public TemplateObjectTO(TemplateInfo template) {
|
||||||
this.path = template.getUri();
|
this.path = template.getUri();
|
||||||
this.uuid = template.getUuid();
|
this.uuid = template.getUuid();
|
||||||
@ -72,4 +75,13 @@ public class TemplateObjectTO implements DataTO {
|
|||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
public void setPath(String path) {
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
public void setUuid(String uuid) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
}
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,13 +24,18 @@ import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat;
|
|||||||
import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType;
|
import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType;
|
||||||
|
|
||||||
public class VolumeObjectTO implements DataTO {
|
public class VolumeObjectTO implements DataTO {
|
||||||
private final String uuid;
|
private String uuid;
|
||||||
private final String path;
|
private VolumeType volumeType;
|
||||||
private VolumeType volumeType;
|
private DiskFormat diskType;
|
||||||
private DiskFormat diskType;
|
|
||||||
private PrimaryDataStoreTO dataStore;
|
private PrimaryDataStoreTO dataStore;
|
||||||
private String name;
|
private String name;
|
||||||
private final long size;
|
private long size;
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
public VolumeObjectTO() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public VolumeObjectTO(VolumeInfo volume) {
|
public VolumeObjectTO(VolumeInfo volume) {
|
||||||
this.uuid = volume.getUuid();
|
this.uuid = volume.getUuid();
|
||||||
this.path = volume.getUri();
|
this.path = volume.getUri();
|
||||||
@ -80,4 +85,21 @@ public class VolumeObjectTO implements DataTO {
|
|||||||
public DataObjectType getObjectType() {
|
public DataObjectType getObjectType() {
|
||||||
return DataObjectType.VOLUME;
|
return DataObjectType.VOLUME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setUuid(String uuid) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSize(long size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPath(String path) {
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import javax.inject.Inject;
|
|||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
|
import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
@ -116,11 +117,11 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager {
|
|||||||
|
|
||||||
|
|
||||||
private class CreateCacheObjectContext<T> extends AsyncRpcConext<T> {
|
private class CreateCacheObjectContext<T> extends AsyncRpcConext<T> {
|
||||||
final AsyncCallFuture<CopyCmdAnswer> future;
|
final AsyncCallFuture<CopyCommandResult> future;
|
||||||
/**
|
/**
|
||||||
* @param callback
|
* @param callback
|
||||||
*/
|
*/
|
||||||
public CreateCacheObjectContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<CopyCmdAnswer> future) {
|
public CreateCacheObjectContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<CopyCommandResult> future) {
|
||||||
super(callback);
|
super(callback);
|
||||||
this.future = future;
|
this.future = future;
|
||||||
}
|
}
|
||||||
@ -131,22 +132,22 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager {
|
|||||||
public DataObject createCacheObject(DataObject data, Scope scope) {
|
public DataObject createCacheObject(DataObject data, Scope scope) {
|
||||||
DataStore cacheStore = this.getCacheStorage(scope);
|
DataStore cacheStore = this.getCacheStorage(scope);
|
||||||
DataObject objOnCacheStore = cacheStore.create(data);
|
DataObject objOnCacheStore = cacheStore.create(data);
|
||||||
AsyncCallFuture<CopyCmdAnswer> future = new AsyncCallFuture<CopyCmdAnswer>();
|
AsyncCallFuture<CopyCommandResult> future = new AsyncCallFuture<CopyCommandResult>();
|
||||||
CreateCacheObjectContext<CopyCmdAnswer> context = new CreateCacheObjectContext<CopyCmdAnswer>(null, future);
|
CreateCacheObjectContext<CopyCommandResult> context = new CreateCacheObjectContext<CopyCommandResult>(null, future);
|
||||||
AsyncCallbackDispatcher<StorageCacheManagerImpl, CopyCmdAnswer> caller = AsyncCallbackDispatcher.create(this);
|
AsyncCallbackDispatcher<StorageCacheManagerImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
||||||
caller.setContext(context);
|
caller.setContext(context);
|
||||||
|
|
||||||
CopyCmdAnswer result = null;
|
CopyCommandResult result = null;
|
||||||
try {
|
try {
|
||||||
objOnCacheStore.processEvent(Event.CreateOnlyRequested);
|
objOnCacheStore.processEvent(Event.CreateOnlyRequested);
|
||||||
|
|
||||||
dataMotionSvr.copyAsync(data, objOnCacheStore, caller);
|
dataMotionSvr.copyAsync(data, objOnCacheStore, caller);
|
||||||
result = future.get();
|
result = future.get();
|
||||||
|
|
||||||
if (!result.getResult()) {
|
if (result.isFailed()) {
|
||||||
cacheStore.delete(data);
|
cacheStore.delete(data);
|
||||||
} else {
|
} else {
|
||||||
objOnCacheStore.processEvent(Event.OperationSuccessed, result);
|
objOnCacheStore.processEvent(Event.OperationSuccessed, result.getAnswer());
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
s_logger.debug("create cache storage failed: " + e.toString());
|
s_logger.debug("create cache storage failed: " + e.toString());
|
||||||
@ -163,9 +164,9 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Void createCacheObjectCallBack(AsyncCallbackDispatcher<StorageCacheManagerImpl, CopyCmdAnswer> callback,
|
protected Void createCacheObjectCallBack(AsyncCallbackDispatcher<StorageCacheManagerImpl, CopyCommandResult> callback,
|
||||||
CreateCacheObjectContext<CopyCmdAnswer> context) {
|
CreateCacheObjectContext<CopyCommandResult> context) {
|
||||||
AsyncCallFuture<CopyCmdAnswer> future = context.future;
|
AsyncCallFuture<CopyCommandResult> future = context.future;
|
||||||
future.complete(callback.getResult());
|
future.complete(callback.getResult());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -317,51 +317,16 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Answer cloneVolume(DataObject template, DataObject volume) {
|
protected Answer cloneVolume(DataObject template, DataObject volume) {
|
||||||
VolumeInfo volInfo = (VolumeInfo)volume;
|
CopyCommand cmd = new CopyCommand(template.getTO(), volume.getTO(), 0);
|
||||||
DiskOfferingVO offering = diskOfferingDao.findById(volInfo.getDiskOfferingId());
|
|
||||||
VMTemplateStoragePoolVO tmpltStoredOn = templatePoolDao.findByPoolTemplate(template.getDataStore().getId(), template.getId());
|
|
||||||
|
|
||||||
DiskProfile diskProfile = new DiskProfile(volInfo, offering,
|
|
||||||
null);
|
|
||||||
CreateCommand cmd = new CreateCommand(diskProfile,
|
|
||||||
tmpltStoredOn.getLocalDownloadPath(),
|
|
||||||
new StorageFilerTO((StoragePool)template.getDataStore()));
|
|
||||||
Answer answer = null;
|
|
||||||
StoragePool pool = (StoragePool)volume.getDataStore();
|
StoragePool pool = (StoragePool)volume.getDataStore();
|
||||||
String errMsg = null;
|
|
||||||
try {
|
try {
|
||||||
answer = storageMgr.sendToPool(pool, null, cmd);
|
Answer answer = storageMgr.sendToPool(pool, null, cmd);
|
||||||
|
return answer;
|
||||||
} catch (StorageUnavailableException e) {
|
} catch (StorageUnavailableException e) {
|
||||||
s_logger.debug("Failed to send to storage pool", e);
|
s_logger.debug("Failed to send to storage pool", e);
|
||||||
throw new CloudRuntimeException("Failed to send to storage pool", e);
|
throw new CloudRuntimeException("Failed to send to storage pool", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (answer.getResult()) {
|
|
||||||
VolumeVO vol = this.volDao.findById(volume.getId());
|
|
||||||
CreateAnswer createAnswer = (CreateAnswer) answer;
|
|
||||||
vol.setFolder(pool.getPath());
|
|
||||||
vol.setPath(createAnswer.getVolume().getPath());
|
|
||||||
vol.setSize(createAnswer.getVolume().getSize());
|
|
||||||
vol.setPoolType(pool.getPoolType());
|
|
||||||
vol.setPoolId(pool.getId());
|
|
||||||
vol.setPodId(pool.getPodId());
|
|
||||||
this.volDao.update(vol.getId(), vol);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (tmpltStoredOn != null
|
|
||||||
&& (answer instanceof CreateAnswer)
|
|
||||||
&& ((CreateAnswer) answer)
|
|
||||||
.templateReloadRequested()) {
|
|
||||||
if (!templateMgr
|
|
||||||
.resetTemplateDownloadStateOnPool(tmpltStoredOn
|
|
||||||
.getId())) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
errMsg = answer.getDetails();
|
|
||||||
}
|
|
||||||
|
|
||||||
return answer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Answer copyVolumeBetweenPools(DataObject srcData, DataObject destData) {
|
protected Answer copyVolumeBetweenPools(DataObject srcData, DataObject destData) {
|
||||||
|
|||||||
@ -181,22 +181,24 @@ public class TemplateObject implements TemplateInfo {
|
|||||||
public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) {
|
public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) {
|
||||||
try {
|
try {
|
||||||
if (this.getDataStore().getRole() == DataStoreRole.Primary) {
|
if (this.getDataStore().getRole() == DataStoreRole.Primary) {
|
||||||
if (answer != null && answer instanceof CopyCmdAnswer) {
|
if (answer instanceof CopyCmdAnswer) {
|
||||||
CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
|
CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
|
||||||
|
TemplateObjectTO newTemplate = (TemplateObjectTO)cpyAnswer.getNewData();
|
||||||
VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(this.getDataStore().getId(), this.getId());
|
VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(this.getDataStore().getId(), this.getId());
|
||||||
templatePoolRef.setDownloadPercent(100);
|
templatePoolRef.setDownloadPercent(100);
|
||||||
templatePoolRef.setDownloadState(Status.DOWNLOADED);
|
templatePoolRef.setDownloadState(Status.DOWNLOADED);
|
||||||
templatePoolRef.setLocalDownloadPath(cpyAnswer.getPath());
|
templatePoolRef.setLocalDownloadPath(newTemplate.getPath());
|
||||||
templatePoolRef.setInstallPath(cpyAnswer.getPath());
|
templatePoolRef.setInstallPath(newTemplate.getPath());
|
||||||
templatePoolDao.update(templatePoolRef.getId(), templatePoolRef);
|
templatePoolDao.update(templatePoolRef.getId(), templatePoolRef);
|
||||||
}
|
}
|
||||||
} else if (this.getDataStore().getRole() == DataStoreRole.Image ||
|
} else if (this.getDataStore().getRole() == DataStoreRole.Image ||
|
||||||
this.getDataStore().getRole() == DataStoreRole.ImageCache) {
|
this.getDataStore().getRole() == DataStoreRole.ImageCache) {
|
||||||
if (answer != null && answer instanceof CopyCmdAnswer) {
|
if (answer instanceof CopyCmdAnswer) {
|
||||||
CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
|
CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
|
||||||
|
TemplateObjectTO newTemplate = (TemplateObjectTO)cpyAnswer.getNewData();
|
||||||
TemplateDataStoreVO templateStoreRef = this.templateStoreDao.findByStoreTemplate(this.getDataStore().getId(),
|
TemplateDataStoreVO templateStoreRef = this.templateStoreDao.findByStoreTemplate(this.getDataStore().getId(),
|
||||||
this.getId());
|
this.getId());
|
||||||
templateStoreRef.setInstallPath(cpyAnswer.getPath());
|
templateStoreRef.setInstallPath(newTemplate.getPath());
|
||||||
templateStoreDao.update(templateStoreRef.getId(), templateStoreRef);
|
templateStoreDao.update(templateStoreRef.getId(), templateStoreRef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -187,6 +187,7 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tapLoadingAgents(Long hostId, TapAgentsAction action) {
|
public boolean tapLoadingAgents(Long hostId, TapAgentsAction action) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataTO;
|
|||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat;
|
import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat;
|
||||||
|
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
|
||||||
import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
|
import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
|
||||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
@ -102,6 +103,7 @@ public class VolumeObject implements VolumeInfo {
|
|||||||
public boolean stateTransit(Volume.Event event) {
|
public boolean stateTransit(Volume.Event event) {
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
try {
|
try {
|
||||||
|
volumeVO = volumeDao.findById(volumeVO.getId());
|
||||||
result = _volStateMachine.transitTo(volumeVO, event, null, volumeDao);
|
result = _volStateMachine.transitTo(volumeVO, event, null, volumeDao);
|
||||||
volumeVO = volumeDao.findById(volumeVO.getId());
|
volumeVO = volumeDao.findById(volumeVO.getId());
|
||||||
} catch (NoTransitionException e) {
|
} catch (NoTransitionException e) {
|
||||||
@ -345,8 +347,18 @@ public class VolumeObject implements VolumeInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processEvent(org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event event, Answer answer) {
|
public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) {
|
||||||
// TODO Auto-generated method stub
|
if (this.dataStore.getRole() == DataStoreRole.Primary) {
|
||||||
|
if (answer instanceof CopyCmdAnswer) {
|
||||||
|
CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
|
||||||
|
VolumeVO vol = this.volumeDao.findById(this.getId());
|
||||||
|
VolumeObjectTO newVol = (VolumeObjectTO)cpyAnswer.getNewData();
|
||||||
|
vol.setPath(newVol.getPath());
|
||||||
|
vol.setSize(newVol.getSize());
|
||||||
|
volumeDao.update(vol.getId(), vol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.processEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -398,7 +398,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed);
|
templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed, result.getAnswer());
|
||||||
createVolumeFromBaseImageAsync(context.volume, templateOnPrimaryStoreObj, context.dataStore, future);
|
createVolumeFromBaseImageAsync(context.volume, templateOnPrimaryStoreObj, context.dataStore, future);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -447,10 +447,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
VolumeApiResult volResult = new VolumeApiResult(vo);
|
VolumeApiResult volResult = new VolumeApiResult(vo);
|
||||||
|
|
||||||
if (result.isSuccess()) {
|
if (result.isSuccess()) {
|
||||||
if (result.getPath() != null) {
|
vo.processEvent(Event.OperationSuccessed, result.getAnswer());
|
||||||
vo.setPath(result.getPath());
|
|
||||||
}
|
|
||||||
vo.processEvent(Event.OperationSuccessed);
|
|
||||||
} else {
|
} else {
|
||||||
vo.processEvent(Event.OperationFailed);
|
vo.processEvent(Event.OperationFailed);
|
||||||
volResult.setResult(result.getResult());
|
volResult.setResult(result.getResult());
|
||||||
|
|||||||
@ -55,15 +55,19 @@ import org.apache.xmlrpc.XmlRpcException;
|
|||||||
|
|
||||||
import com.cloud.agent.api.Answer;
|
import com.cloud.agent.api.Answer;
|
||||||
import com.cloud.agent.api.Command;
|
import com.cloud.agent.api.Command;
|
||||||
|
import com.cloud.agent.api.storage.CreateAnswer;
|
||||||
import com.cloud.agent.api.storage.DeleteVolumeCommand;
|
import com.cloud.agent.api.storage.DeleteVolumeCommand;
|
||||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
|
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
|
||||||
import com.cloud.agent.api.to.DataStoreTO;
|
import com.cloud.agent.api.to.DataStoreTO;
|
||||||
|
import com.cloud.agent.api.to.StorageFilerTO;
|
||||||
|
import com.cloud.agent.api.to.VolumeTO;
|
||||||
import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType;
|
import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType;
|
||||||
import com.cloud.storage.DataStoreRole;
|
import com.cloud.storage.DataStoreRole;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
import com.cloud.utils.storage.encoding.DecodedDataObject;
|
import com.cloud.utils.storage.encoding.DecodedDataObject;
|
||||||
import com.cloud.utils.storage.encoding.DecodedDataStore;
|
import com.cloud.utils.storage.encoding.DecodedDataStore;
|
||||||
import com.cloud.utils.storage.encoding.Decoder;
|
import com.cloud.utils.storage.encoding.Decoder;
|
||||||
|
import com.cloud.vm.DiskProfile;
|
||||||
import com.xensource.xenapi.Connection;
|
import com.xensource.xenapi.Connection;
|
||||||
import com.xensource.xenapi.Host;
|
import com.xensource.xenapi.Host;
|
||||||
import com.xensource.xenapi.PBD;
|
import com.xensource.xenapi.PBD;
|
||||||
@ -548,7 +552,7 @@ public class XenServerStorageResource {
|
|||||||
//downloadHttpToLocalFile(vdiPath, template.getPath());
|
//downloadHttpToLocalFile(vdiPath, template.getPath());
|
||||||
hypervisorResource.callHostPlugin(conn, "storagePlugin", "downloadTemplateFromUrl", "destPath", vdiPath, "srcUrl", srcObj.getPath());
|
hypervisorResource.callHostPlugin(conn, "storagePlugin", "downloadTemplateFromUrl", "destPath", vdiPath, "srcUrl", srcObj.getPath());
|
||||||
result = true;
|
result = true;
|
||||||
return new CopyCmdAnswer(cmd, vdi.getUuid(conn));
|
//return new CopyCmdAnswer(cmd, vdi.getUuid(conn));
|
||||||
} catch (BadServerResponse e) {
|
} catch (BadServerResponse e) {
|
||||||
s_logger.debug("Failed to download template", e);
|
s_logger.debug("Failed to download template", e);
|
||||||
} catch (XenAPIException e) {
|
} catch (XenAPIException e) {
|
||||||
@ -673,7 +677,7 @@ public class XenServerStorageResource {
|
|||||||
return parentUuid;
|
return parentUuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PrimaryStorageDownloadAnswer copyTemplateToPrimaryStorage(DataTO srcData, DataTO destData, int wait) {
|
protected CopyCmdAnswer copyTemplateToPrimaryStorage(DataTO srcData, DataTO destData, int wait) {
|
||||||
DataStoreTO srcStore = srcData.getDataStore();
|
DataStoreTO srcStore = srcData.getDataStore();
|
||||||
try {
|
try {
|
||||||
if (srcStore.getRole() == DataStoreRole.ImageCache && srcData.getObjectType() == DataObjectType.TEMPLATE) {
|
if (srcStore.getRole() == DataStoreRole.ImageCache && srcData.getObjectType() == DataObjectType.TEMPLATE) {
|
||||||
@ -681,7 +685,7 @@ public class XenServerStorageResource {
|
|||||||
TemplateObjectTO srcTemplate = (TemplateObjectTO)srcData;
|
TemplateObjectTO srcTemplate = (TemplateObjectTO)srcData;
|
||||||
String storeUrl = srcImageStore.getUri();
|
String storeUrl = srcImageStore.getUri();
|
||||||
if (!storeUrl.startsWith("nfs")) {
|
if (!storeUrl.startsWith("nfs")) {
|
||||||
return new PrimaryStorageDownloadAnswer("only nfs image cache store supported");
|
return new CopyCmdAnswer("only nfs image cache store supported");
|
||||||
}
|
}
|
||||||
String tmplpath = storeUrl + ":" + srcData.getPath();
|
String tmplpath = storeUrl + ":" + srcData.getPath();
|
||||||
PrimaryDataStoreTO destStore = (PrimaryDataStoreTO)destData.getDataStore();
|
PrimaryDataStoreTO destStore = (PrimaryDataStoreTO)destData.getDataStore();
|
||||||
@ -693,7 +697,7 @@ public class XenServerStorageResource {
|
|||||||
if (srs.size() != 1) {
|
if (srs.size() != 1) {
|
||||||
String msg = "There are " + srs.size() + " SRs with same name: " + poolName;
|
String msg = "There are " + srs.size() + " SRs with same name: " + poolName;
|
||||||
s_logger.warn(msg);
|
s_logger.warn(msg);
|
||||||
return new PrimaryStorageDownloadAnswer(msg);
|
return new CopyCmdAnswer(msg);
|
||||||
} else {
|
} else {
|
||||||
poolsr = srs.iterator().next();
|
poolsr = srs.iterator().next();
|
||||||
}
|
}
|
||||||
@ -713,66 +717,79 @@ public class XenServerStorageResource {
|
|||||||
Thread.sleep(5000);
|
Thread.sleep(5000);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
return new PrimaryStorageDownloadAnswer(snapshotvdi.getUuid(conn), phySize);
|
|
||||||
|
VolumeObjectTO newVol = new VolumeObjectTO();
|
||||||
|
newVol.setUuid(snapshotvdi.getUuid(conn));
|
||||||
|
newVol.setSize(phySize);
|
||||||
|
newVol.setPath(newVol.getUuid());
|
||||||
|
return new CopyCmdAnswer(newVol);
|
||||||
}
|
}
|
||||||
}catch (Exception e) {
|
}catch (Exception e) {
|
||||||
String msg = "Catch Exception " + e.getClass().getName() + " for template + " + " due to " + e.toString();
|
String msg = "Catch Exception " + e.getClass().getName() + " for template + " + " due to " + e.toString();
|
||||||
s_logger.warn(msg, e);
|
s_logger.warn(msg, e);
|
||||||
return new PrimaryStorageDownloadAnswer(msg);
|
return new CopyCmdAnswer(msg);
|
||||||
|
}
|
||||||
|
return new CopyCmdAnswer("not implemented yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CreateObjectAnswer createVolume(DataTO data) {
|
||||||
|
/*
|
||||||
|
VDI.Record vdir = new VDI.Record();
|
||||||
|
vdir.nameLabel = dskch.getName();
|
||||||
|
vdir.SR = poolSr;
|
||||||
|
vdir.type = Types.VdiType.USER;
|
||||||
|
|
||||||
|
vdir.virtualSize = dskch.getSize();
|
||||||
|
vdi = VDI.create(conn, vdir);
|
||||||
|
VDI.Record vdir;
|
||||||
|
vdir = vdi.getRecord(conn);
|
||||||
|
s_logger.debug("Succesfully created VDI for " + cmd + ". Uuid = " + vdir.uuid);*/
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
protected CopyCmdAnswer cloneVolumeFromBaseTemplate(DataTO srcData, DataTO destData) {
|
||||||
|
Connection conn = hypervisorResource.getConnection();
|
||||||
|
PrimaryDataStoreTO pool = (PrimaryDataStoreTO)destData.getDataStore();
|
||||||
|
VolumeObjectTO volume = (VolumeObjectTO)destData;
|
||||||
|
VDI vdi = null;
|
||||||
|
try {
|
||||||
|
VDI tmpltvdi = null;
|
||||||
|
|
||||||
|
tmpltvdi = getVDIbyUuid(conn, srcData.getPath());
|
||||||
|
vdi = tmpltvdi.createClone(conn, new HashMap<String, String>());
|
||||||
|
vdi.setNameLabel(conn, volume.getName());
|
||||||
|
|
||||||
|
|
||||||
|
VDI.Record vdir;
|
||||||
|
vdir = vdi.getRecord(conn);
|
||||||
|
s_logger.debug("Succesfully created VDI: Uuid = " + vdir.uuid);
|
||||||
|
|
||||||
|
VolumeObjectTO newVol = new VolumeObjectTO();
|
||||||
|
newVol.setName(vdir.nameLabel);
|
||||||
|
newVol.setSize(vdir.virtualSize);
|
||||||
|
newVol.setPath(vdir.uuid);
|
||||||
|
|
||||||
|
return new CopyCmdAnswer(newVol);
|
||||||
|
} catch (Exception e) {
|
||||||
|
s_logger.warn("Unable to create volume; Pool=" + pool + "; Disk: ", e);
|
||||||
|
return new CopyCmdAnswer(e.toString());
|
||||||
}
|
}
|
||||||
return new PrimaryStorageDownloadAnswer("not implemented yet");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected Answer execute(CopyCommand cmd) {
|
protected Answer execute(CopyCommand cmd) {
|
||||||
DataTO srcData = cmd.getSrcTO();
|
DataTO srcData = cmd.getSrcTO();
|
||||||
DataTO destData = cmd.getDestTO();
|
DataTO destData = cmd.getDestTO();
|
||||||
|
DataStoreTO srcDataStore = srcData.getDataStore();
|
||||||
if (srcData.getObjectType() == DataObjectType.TEMPLATE && destData.getDataStore().getRole() == DataStoreRole.Primary) {
|
DataStoreTO destDataStore = destData.getDataStore();
|
||||||
|
|
||||||
|
if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcData.getDataStore().getRole() == DataStoreRole.ImageCache && destData.getDataStore().getRole() == DataStoreRole.Primary) {
|
||||||
//copy template to primary storage
|
//copy template to primary storage
|
||||||
return copyTemplateToPrimaryStorage(srcData, destData, cmd.getTimeout());
|
return copyTemplateToPrimaryStorage(srcData, destData, cmd.getWait());
|
||||||
|
} else if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcDataStore.getRole() == DataStoreRole.Primary && destDataStore.getRole() == DataStoreRole.Primary) {
|
||||||
|
//clone template to a volume
|
||||||
|
return cloneVolumeFromBaseTemplate(srcData, destData);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Answer(cmd, false, "not implemented yet");
|
return new Answer(cmd, false, "not implemented yet");
|
||||||
/*
|
}
|
||||||
String tmplturl = cmd.getUrl();
|
|
||||||
String poolName = cmd.getPoolUuid();
|
|
||||||
int wait = cmd.getWait();
|
|
||||||
try {
|
|
||||||
URI uri = new URI(tmplturl);
|
|
||||||
String tmplpath = uri.getHost() + ":" + uri.getPath();
|
|
||||||
Connection conn = hypervisorResource.getConnection();
|
|
||||||
SR poolsr = null;
|
|
||||||
Set<SR> srs = SR.getByNameLabel(conn, poolName);
|
|
||||||
if (srs.size() != 1) {
|
|
||||||
String msg = "There are " + srs.size() + " SRs with same name: " + poolName;
|
|
||||||
s_logger.warn(msg);
|
|
||||||
return new PrimaryStorageDownloadAnswer(msg);
|
|
||||||
} else {
|
|
||||||
poolsr = srs.iterator().next();
|
|
||||||
}
|
|
||||||
String pUuid = poolsr.getUuid(conn);
|
|
||||||
boolean isISCSI = IsISCSI(poolsr.getType(conn));
|
|
||||||
String uuid = copy_vhd_from_secondarystorage(conn, tmplpath, pUuid, wait);
|
|
||||||
VDI tmpl = getVDIbyUuid(conn, uuid);
|
|
||||||
VDI snapshotvdi = tmpl.snapshot(conn, new HashMap<String, String>());
|
|
||||||
String snapshotUuid = snapshotvdi.getUuid(conn);
|
|
||||||
snapshotvdi.setNameLabel(conn, "Template " + cmd.getName());
|
|
||||||
String parentuuid = getVhdParent(conn, pUuid, snapshotUuid, isISCSI);
|
|
||||||
VDI parent = getVDIbyUuid(conn, parentuuid);
|
|
||||||
Long phySize = parent.getPhysicalUtilisation(conn);
|
|
||||||
tmpl.destroy(conn);
|
|
||||||
poolsr.scan(conn);
|
|
||||||
try{
|
|
||||||
Thread.sleep(5000);
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
return new PrimaryStorageDownloadAnswer(snapshotvdi.getUuid(conn), phySize);
|
|
||||||
} catch (Exception e) {
|
|
||||||
String msg = "Catch Exception " + e.getClass().getName() + " on host:" + _host.uuid + " for template: "
|
|
||||||
+ tmplturl + " due to " + e.toString();
|
|
||||||
s_logger.warn(msg, e);
|
|
||||||
return new PrimaryStorageDownloadAnswer(msg);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -175,7 +175,8 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
|
|||||||
AsyncCallbackDispatcher<CloudStackImageStoreDriverImpl, DownloadAnswer> caller =
|
AsyncCallbackDispatcher<CloudStackImageStoreDriverImpl, DownloadAnswer> caller =
|
||||||
AsyncCallbackDispatcher.create(this);
|
AsyncCallbackDispatcher.create(this);
|
||||||
caller.setContext(context);
|
caller.setContext(context);
|
||||||
caller.setCallback(this.createAsyncCallback(null, null));
|
caller.setCallback(caller.getTarget().createAsyncCallback(null, null));
|
||||||
|
|
||||||
|
|
||||||
if (data.getType() == DataObjectType.TEMPLATE) {
|
if (data.getType() == DataObjectType.TEMPLATE) {
|
||||||
TemplateObject tData = (TemplateObject)data;
|
TemplateObject tData = (TemplateObject)data;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user