make create template from volume/snapshot work

This commit is contained in:
Edison Su 2013-05-07 17:46:10 -07:00
parent ac1b75dc9f
commit 5aeca646ae
10 changed files with 407 additions and 41 deletions

View File

@ -53,6 +53,7 @@ import org.apache.cloudstack.storage.command.CopyCommand;
import org.apache.cloudstack.storage.command.DownloadCommand;
import org.apache.cloudstack.storage.command.DownloadProgressCommand;
import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
import org.apache.cloudstack.storage.to.TemplateObjectTO;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
@ -103,6 +104,7 @@ import com.cloud.agent.api.to.SwiftTO;
import com.cloud.exception.InternalErrorException;
import com.cloud.host.Host;
import com.cloud.host.Host.Type;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.resource.ServerResourceBase;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.StorageLayer;
@ -110,10 +112,14 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.template.DownloadManager;
import com.cloud.storage.template.DownloadManagerImpl;
import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser;
import com.cloud.storage.template.Processor.FormatInfo;
import com.cloud.storage.template.Processor;
import com.cloud.storage.template.QCOW2Processor;
import com.cloud.storage.template.TemplateLocation;
import com.cloud.storage.template.TemplateProp;
import com.cloud.storage.template.UploadManager;
import com.cloud.storage.template.UploadManagerImpl;
import com.cloud.storage.template.VhdProcessor;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.S3Utils;
import com.cloud.utils.S3Utils.FileNamingStrategy;
@ -161,6 +167,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
final private String _parent = "/mnt/SecStorage";
final private String _tmpltDir = "/var/cloudstack/template";
final private String _tmpltpp = "template.properties";
private String createTemplateFromSnapshotXenScript;
@Override
public void disconnected() {
@ -281,34 +288,102 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
}
}
protected Answer copyFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO srcImageStore,
DataTO destData, NfsTO destImageStore) {
protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) {
String srcMountPoint = this.getRootDir(srcDataStore.getUrl());
String snapshotPath = srcData.getPath();
int index = snapshotPath.lastIndexOf("/");
String snapshotName = snapshotPath.substring(index + 1);
if (!snapshotName.startsWith("VHD-") && !snapshotName.endsWith(".vhd")) {
snapshotName = snapshotName + ".vhd";
}
snapshotPath = snapshotPath.substring(0, index);
snapshotPath = srcMountPoint + snapshotPath;
String destMountPoint = this.getRootDir(destDataStore.getUrl());
String destPath = destMountPoint + destData.getPath();
String errMsg = null;
try {
this._storage.mkdir(destPath);
String templateUuid = UUID.randomUUID().toString();
String templateName = templateUuid + ".vhd";
Script command = new Script(this.createTemplateFromSnapshotXenScript, cmd.getWait(), s_logger);
command.add("-p", snapshotPath);
command.add("-s", snapshotName);
command.add("-n", templateName);
command.add("-t", destPath);
command.execute();
Map<String, Object> params = new HashMap<String, Object>();
params.put(StorageLayer.InstanceConfigKey, _storage);
Processor processor = new VhdProcessor();
processor.configure("Vhd Processor", params);
FormatInfo info = processor.process(destPath, null,
templateUuid);
TemplateLocation loc = new TemplateLocation(_storage, destPath);
loc.create(1, true, templateName);
loc.addFormat(info);
loc.save();
TemplateObjectTO newTemplate = new TemplateObjectTO();
newTemplate.setPath(destData.getPath() + File.separator + templateUuid);
return new CopyCmdAnswer(newTemplate);
} catch (ConfigurationException e) {
s_logger.debug("Failed to create template from snapshot: " + e.toString());
errMsg = e.toString();
} catch (InternalErrorException e) {
s_logger.debug("Failed to create template from snapshot: " + e.toString());
errMsg = e.toString();
} catch (IOException e) {
s_logger.debug("Failed to create template from snapshot: " + e.toString());
errMsg = e.toString();
}
return new CopyCmdAnswer(errMsg);
}
protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) {
if (srcData.getHypervisorType() == HypervisorType.XenServer) {
return copySnapshotToTemplateFromNfsToNfsXenserver(cmd, srcData, srcDataStore, destData, destDataStore);
}
return new CopyCmdAnswer("");
}
protected Answer createTemplateFromSnapshot(CopyCommand cmd) {
DataTO srcData = cmd.getSrcTO();
DataTO destData = cmd.getDestTO();
DataStoreTO srcDataStore = srcData.getDataStore();
DataStoreTO destDataStore = destData.getDataStore();
if (srcDataStore.getRole() == DataStoreRole.Image || srcDataStore.getRole() == DataStoreRole.ImageCache) {
if (!(srcDataStore instanceof NfsTO)) {
s_logger.debug("only support nfs storage as src, when create template from snapshot");
return Answer.createUnsupportedCommandAnswer(cmd);
}
if (destDataStore instanceof NfsTO){
return copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, (NfsTO)destDataStore);
}
}
return new CopyCmdAnswer("");
}
protected Answer execute(CopyCommand cmd) {
DataTO srcData = cmd.getSrcTO();
DataTO destData = cmd.getDestTO();
DataStoreTO srcDataStore = srcData.getDataStore();
DataStoreTO destDataStore = destData.getDataStore();
if (srcDataStore.getRole() == DataStoreRole.Image && destDataStore.getRole() == DataStoreRole.ImageCache) {
if (!(destDataStore instanceof NfsTO)) {
s_logger.debug("only support nfs as cache storage");
return Answer.createUnsupportedCommandAnswer(cmd);
if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.TEMPLATE) {
return createTemplateFromSnapshot(cmd);
}
if (srcDataStore instanceof S3TO) {
return copyFromS3ToNfs(cmd, srcData, (S3TO) srcDataStore, destData, (NfsTO) destDataStore);
} else if (srcDataStore instanceof SwiftTO) {
return copyFromSwiftToNfs(cmd, srcData, (SwiftTO) srcDataStore, destData, (NfsTO) destDataStore);
} else {
return Answer.createUnsupportedCommandAnswer(cmd);
}
}
return Answer.createUnsupportedCommandAnswer(cmd);
}
@ -1653,6 +1728,11 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
s_logger.info("_configIpFirewallScr found in " + _configIpFirewallScr);
}
createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), "create_privatetemplate_from_snapshot_xen.sh");
if (createTemplateFromSnapshotXenScript == null) {
throw new ConfigurationException("create_privatetemplate_from_snapshot_xen.sh not found in " + getDefaultScriptsDir());
}
_role = (String) params.get("role");
if (_role == null)
_role = SecondaryStorageVm.Role.templateProcessor.toString();

View File

@ -5,6 +5,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataTO;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
public class SnapshotObjectTO implements DataTO {
private String path;
@ -13,6 +14,7 @@ public class SnapshotObjectTO implements DataTO {
private DataStoreTO dataStore;
private String vmName;
private String name;
private HypervisorType hypervisorType;
private long id;
public SnapshotObjectTO() {
@ -29,6 +31,7 @@ public class SnapshotObjectTO implements DataTO {
}
this.dataStore = snapshot.getDataStore().getTO();
this.setName(snapshot.getName());
this.hypervisorType = snapshot.getHypervisorType();
}
@Override
@ -89,4 +92,12 @@ public class SnapshotObjectTO implements DataTO {
public void setName(String name) {
this.name = name;
}
public HypervisorType getHypervisorType() {
return hypervisorType;
}
public void setHypervisorType(HypervisorType hypervisorType) {
this.hypervisorType = hypervisorType;
}
}

View File

@ -327,7 +327,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
.parseInt(Config.CreatePrivateTemplateFromSnapshotWait
.getDefaultValue()));
if (srcData.getDataStore().getRole() != DataStoreRole.ImageCache && destData.getDataStore().getRole() != DataStoreRole.ImageCache) {
if (needCacheStorage(srcData, destData)) {
SnapshotInfo snapshot = (SnapshotInfo)srcData;
srcData = cacheSnapshotChain(snapshot);
}

View File

@ -94,6 +94,9 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests {
this.s3TemplateBucket = s3_template_bucket;
this.s3UseHttps = Boolean.parseBoolean(s3_usehttps);
this.scriptPath = scriptPath;
if (this.scriptPath != null) {
System.setProperty("paths.script", this.getScriptPath());
}
}
protected String getHostGuid() {

View File

@ -29,6 +29,7 @@ import javax.inject.Inject;
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.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
@ -45,6 +46,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk;
import org.apache.cloudstack.framework.async.AsyncCallFuture;
import org.apache.cloudstack.storage.LocalHostEndpoint;
import org.apache.cloudstack.storage.MockLocalNfsSecondaryStorageResource;
import org.apache.cloudstack.storage.RemoteHostEndPoint;
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
@ -144,6 +147,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
SnapshotDao snapshotDao;
@Inject
EndPointSelector epSelector;
long primaryStoreId;
VMTemplateVO image;
String imageStoreName = "testImageStore";
@ -196,7 +200,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
imageStore = new ImageStoreVO();
imageStore.setName(imageStoreName);
imageStore.setDataCenterId(dcId);
imageStore.setProviderName("CloudStack ImageStore Provider");
imageStore.setProviderName(DataStoreProvider.NFS_IMAGE);
imageStore.setRole(DataStoreRole.Image);
imageStore.setUrl(this.getSecondaryStorage());
imageStore.setUuid(UUID.randomUUID().toString());
@ -301,7 +305,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
pool.setPoolType(StoragePoolType.NetworkFilesystem);
pool.setPodId(podId);
pool.setScope(ScopeType.CLUSTER);
pool.setStorageProviderName("cloudstack primary data store provider");
pool.setStorageProviderName(DataStoreProvider.DEFAULT_PRIMARY);
pool = this.primaryStoreDao.persist(pool);
DataStore store = this.dataStoreMgr.getPrimaryDataStore(pool.getId());
return store;
@ -360,14 +364,48 @@ public class SnapshotTest extends CloudStackTestNGBase {
}
}
//@Test
public void testCreateDataDisk() {
DataStore primaryStore = createPrimaryDataStore();
primaryStoreId = primaryStore.getId();
primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
VolumeVO volume = createVolume(null, primaryStore.getId());
VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
this.volumeService.createVolumeAsync(volInfo, primaryStore);
private VMTemplateVO createTemplateInDb() {
image = new VMTemplateVO();
image.setTemplateType(TemplateType.USER);
image.setUniqueName(UUID.randomUUID().toString());
image.setName(UUID.randomUUID().toString());
image.setPublicTemplate(true);
image.setFeatured(true);
image.setRequiresHvm(true);
image.setBits(64);
image.setFormat(Storage.ImageFormat.VHD);
image.setEnablePassword(true);
image.setEnableSshKey(true);
image.setGuestOSId(1);
image.setBootable(true);
image.setPrepopulate(true);
image.setCrossZones(true);
image.setExtractable(true);
image = imageDataDao.persist(image);
return image;
}
@Test
public void createTemplateFromSnapshot() {
VolumeInfo vol = createCopyBaseImage();
SnapshotVO snapshotVO = createSnapshotInDb(vol);
SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
boolean result = false;
for (SnapshotStrategy strategy : this.snapshotStrategies) {
if (strategy.canHandle(snapshot)) {
snapshot = strategy.takeSnapshot(snapshot);
result = true;
}
}
AssertJUnit.assertTrue(result);
LocalHostEndpoint ep = new LocalHostEndpoint();
ep.setResource(new MockLocalNfsSecondaryStorageResource());
Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep);
VMTemplateVO templateVO = createTemplateInDb();
TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId());
DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId);
this.imageService.createTemplateFromSnapshotAsync(snapshot, tmpl, imageStore);
}
}

View File

@ -68,7 +68,7 @@ public class TemplateTest extends CloudStackTestNGBase {
@Test(priority = -1)
public void setUp() {
ComponentContext.initComponentsLifeCycle();
System.setProperty("paths.script", this.getScriptPath());
//create data center
DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24",
null, null, NetworkType.Basic, null, null, true, true, null, null);

View File

@ -379,4 +379,55 @@ public class VolumeTest extends CloudStackTestNGBase {
}
}
private VMTemplateVO createTemplateInDb() {
image = new VMTemplateVO();
image.setTemplateType(TemplateType.USER);
image.setUniqueName(UUID.randomUUID().toString());
image.setName(UUID.randomUUID().toString());
image.setPublicTemplate(true);
image.setFeatured(true);
image.setRequiresHvm(true);
image.setBits(64);
image.setFormat(Storage.ImageFormat.VHD);
image.setEnablePassword(true);
image.setEnableSshKey(true);
image.setGuestOSId(1);
image.setBootable(true);
image.setPrepopulate(true);
image.setCrossZones(true);
image.setExtractable(true);
image = imageDataDao.persist(image);
return image;
}
@Test
public void testCreateTemplateFromVolume() {
DataStore primaryStore = createPrimaryDataStore();
primaryStoreId = primaryStore.getId();
primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
VolumeVO volume = createVolume(null, primaryStore.getId());
VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeAsync(volInfo, primaryStore);
try {
VolumeApiResult result = future.get();
AssertJUnit.assertTrue(result.isSuccess());
volInfo = result.getVolume();
VMTemplateVO templateVO = createTemplateInDb();
TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId());
DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId);
this.imageService.createTemplateFromVolumeAsync(volInfo, tmpl, imageStore);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View File

@ -84,6 +84,16 @@ public class DefaultEndPointSelector implements EndPointSelector {
}
}
protected boolean moveBetweenImages(DataStore srcStore, DataStore destStore) {
DataStoreRole srcRole = srcStore.getRole();
DataStoreRole destRole = destStore.getRole();
if (srcRole == DataStoreRole.Image && destRole == DataStoreRole.Image) {
return true;
} else {
return false;
}
}
@DB
protected EndPoint findEndPointInScope(Scope scope, String sqlBase) {
StringBuilder sbuilder = new StringBuilder();
@ -162,11 +172,10 @@ public class DefaultEndPointSelector implements EndPointSelector {
if (moveBetweenPrimaryImage(srcStore, destStore)) {
return findEndPointForImageMove(srcStore, destStore);
} else if (moveBetweenCacheAndImage(srcStore, destStore)) {
EndPoint ep = findEndPointForImageMove(srcStore, destStore);
if (ep == null) {
//if there is no ssvm agent running, use mgt server
ep = new LocalHostEndpoint();
}
EndPoint ep = findEndpointForImageStorage(destStore);
return ep;
} else if (moveBetweenImages(srcStore, destStore)) {
EndPoint ep = findEndpointForImageStorage(destStore);
return ep;
}
// TODO Auto-generated method stub

View File

@ -70,6 +70,7 @@ import com.cloud.agent.api.ManageSnapshotAnswer;
import com.cloud.agent.api.ManageSnapshotCommand;
import com.cloud.agent.api.storage.CopyVolumeAnswer;
import com.cloud.agent.api.storage.CreateAnswer;
import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
import com.cloud.agent.api.storage.DeleteVolumeCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
import com.cloud.agent.api.to.DataStoreTO;
@ -81,6 +82,7 @@ import com.cloud.agent.api.to.VolumeTO;
import com.cloud.exception.InternalErrorException;
import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.utils.S3Utils;
import com.cloud.utils.StringUtils;
import com.cloud.utils.exception.CloudRuntimeException;
@ -1200,7 +1202,7 @@ public class XenServerStorageResource {
destroySnapshotOnPrimaryStorageExceptThis(conn, volumeUuid, snapshotUuid);
SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
newSnapshot.setPath(snapshotBackupUuid);
newSnapshot.setPath(folder + File.separator + snapshotBackupUuid);
if (fullbackup) {
newSnapshot.setParentSnapshotPath(null);
} else {
@ -1218,6 +1220,76 @@ public class XenServerStorageResource {
return new CopyCmdAnswer(details);
}
protected CopyCmdAnswer createTemplateFromVolume(DataTO srcData, DataTO destData, int wait) {
Connection conn = this.hypervisorResource.getConnection();
VolumeObjectTO volume = (VolumeObjectTO)srcData;
TemplateObjectTO template = (TemplateObjectTO)destData;
NfsTO destStore = (NfsTO)destData.getDataStore();
String secondaryStoragePoolURL = destStore.getUrl();
String volumeUUID = volume.getPath();
String userSpecifiedName = template.getName();
String details = null;
SR tmpltSR = null;
boolean result = false;
String secondaryStorageMountPath = null;
String installPath = null;
try {
URI uri = new URI(secondaryStoragePoolURL);
secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
installPath = template.getPath();
if( !this.hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath)) {
details = " Filed to create folder " + installPath + " in secondary storage";
s_logger.warn(details);
return new CopyCmdAnswer(details);
}
VDI vol = getVDIbyUuid(conn, volumeUUID);
// create template SR
URI tmpltURI = new URI(secondaryStoragePoolURL + "/" + installPath);
tmpltSR = this.hypervisorResource.createNfsSRbyURI(conn, tmpltURI, false);
// copy volume to template SR
VDI tmpltVDI = this.hypervisorResource.cloudVDIcopy(conn, vol, tmpltSR, wait);
// scan makes XenServer pick up VDI physicalSize
tmpltSR.scan(conn);
if (userSpecifiedName != null) {
tmpltVDI.setNameLabel(conn, userSpecifiedName);
}
String tmpltUUID = tmpltVDI.getUuid(conn);
String tmpltFilename = tmpltUUID + ".vhd";
long virtualSize = tmpltVDI.getVirtualSize(conn);
long physicalSize = tmpltVDI.getPhysicalUtilisation(conn);
// create the template.properties file
String templatePath = secondaryStorageMountPath + "/" + installPath;
result = this.hypervisorResource.postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, virtualSize, template.getId());
if (!result) {
throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir: " + tmpltURI);
}
installPath = installPath + "/" + tmpltFilename;
this.hypervisorResource.removeSR(conn, tmpltSR);
tmpltSR = null;
TemplateObjectTO newTemplate = new TemplateObjectTO();
newTemplate.setPath(installPath);
CopyCmdAnswer answer = new CopyCmdAnswer(newTemplate);
return answer;
} catch (Exception e) {
if (tmpltSR != null) {
this.hypervisorResource.removeSR(conn, tmpltSR);
}
if ( secondaryStorageMountPath != null) {
this.hypervisorResource.deleteSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath);
}
details = "Creating template from volume " + volumeUUID + " failed due to " + e.toString();
s_logger.error(details, e);
}
return new CopyCmdAnswer(details);
}
protected Answer execute(CopyCommand cmd) {
DataTO srcData = cmd.getSrcTO();
DataTO destData = cmd.getDestTO();
@ -1235,11 +1307,15 @@ public class XenServerStorageResource {
} else if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcDataStore.getRole() == DataStoreRole.Primary && destDataStore.getRole() == DataStoreRole.Primary) {
//clone template to a volume
return cloneVolumeFromBaseTemplate(srcData, destData);
} else if (srcData.getObjectType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.ImageCache) {
} else if (srcData.getObjectType() == DataObjectType.VOLUME && (srcData.getDataStore().getRole() == DataStoreRole.ImageCache || srcDataStore.getRole() == DataStoreRole.Image)) {
//copy volume from image cache to primary
return copyVolumeFromImageCacheToPrimary(srcData, destData, cmd.getWait());
} else if (srcData.getObjectType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Primary) {
if (destData.getObjectType() == DataObjectType.VOLUME) {
return copyVolumeFromPrimaryToSecondary(srcData, destData, cmd.getWait());
} else if (destData.getObjectType() == DataObjectType.TEMPLATE) {
return createTemplateFromVolume(srcData, destData, cmd.getWait());
}
} else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && srcData.getDataStore().getRole() == DataStoreRole.Primary) {
DataTO cacheData = cmd.getCacheTO();
return backupSnasphot(srcData, destData, cacheData, cmd.getWait());

View File

@ -0,0 +1,98 @@
#!/bin/bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#set -x
usage() {
printf "Usage: %s -t [template path] -n [template name] -s [snapshot name] -p [snapshot path] \n" $(basename $0)
}
snapshotPath=
snapshotName=
templatePath=
templateName=
while getopts ':s:n:t:p:' OPTION
do
case $OPTION in
t) tflag=1
templatePath="$OPTARG"
;;
n) nflag=1
templateName="$OPTARG"
;;
s) sflag=1
snapshotName="$OPTARG"
;;
p) pflag=1
snapshotPath="$OPTARG"
;;
?) usage
exit 2
;;
esac
done
if [ "$sflag$nflag$tflag$pflag" != "1111" ]
then
usage
exit 1
fi
VHDUTIL="/bin/vhd-util"
desvhd=$templatePath/$templateName
srcvhd=$snapshotPath/$snapshotName
copyvhd()
{
local desvhd=$1
local srcvhd=$2
local parent=
parent=`$VHDUTIL query -p -n $srcvhd`
if [ $? -ne 0 ]; then
echo "30#failed to query $srcvhd"
exit 2
fi
if [[ "${parent}" =~ " no parent" ]]; then
dd if=$srcvhd of=$desvhd bs=2M
if [ $? -ne 0 ]; then
echo "31#failed to dd $srcvhd to $desvhd"
rm -rf $desvhd > /dev/null
exit 0
fi
else
copyvhd $desvhd $parent
$VHDUTIL coalesce -p $desvhd -n $srcvhd
if [ $? -ne 0 ]; then
echo "32#failed to coalesce $desvhd to $srcvhd"
rm -rf $desvhd > /dev/null
exit 0
fi
fi
}
copyvhd $desvhd $srcvhd
imgsize=$(ls -l $desvhd| awk -F" " '{print $5}')
propertyFile=/$templatePath/template.properties
touch $propertyFile
echo -n "" > $propertyFile
echo "filename=$templateName" > $propertyFile
echo "hvm=$hvm" >> $propertyFile
echo "size=$imgsize" >> $propertyFile
exit 0