Bug 11648 - OVM - volume > create template FAIL

status 11648: resolved fixed
This commit is contained in:
frank 2011-10-11 17:40:44 -07:00
parent dce4e74b58
commit 1710c2f684
6 changed files with 137 additions and 36 deletions

View File

@ -112,4 +112,17 @@ def raiseExceptionIfFail(res):
def ipToHeartBeatFileName(ip):
return ip.replace('.', '_') + "_HEARTBEAT"
def parseVmConfigureFile(cfgPath):
if not isfile(cfgPath): return {}
res = {}
fd = open(cfgPath)
for i in fd.readlines():
(key, value) = i.split("=", 1)
key = key.strip().strip("'")
value = value.strip().strip("'")
res[key] = value
fd.close()
return res

View File

@ -38,6 +38,8 @@ errCode = {
"OvmStoragePool.getDetailsByUuid":OvmStoragePoolErrCodeStub+2,
"OvmStoragePool.downloadTemplate":OvmStoragePoolErrCodeStub+3,
"OvmStoragePool.prepareOCFS2Nodes":OvmStoragePoolErrCodeStub+4,
"OvmStoragePool.createTemplateFromVolume":OvmStoragePoolErrCodeStub+5,
"OvmStoragePool._umount":OvmStoragePoolErrCodeStub+6,
"OvmNetwork.createBridge":OvmNetworkErrCodeStub+1,
"OvmNetwork.deleteBridge":OvmNetworkErrCodeStub+2,

View File

@ -74,12 +74,25 @@ class OvmStoragePool(OvmObject):
res = doCmd(['mount'])
return (path in res)
def _mount(self, target, mountpoint):
def _mount(self, target, mountpoint, readonly=False):
if not exists(mountpoint):
os.makedirs(mountpoint)
if not OvmStoragePool()._isMounted(mountpoint):
doCmd(['mount', target, mountpoint, '-r'])
if readonly:
doCmd(['mount', target, mountpoint, '-r'])
else:
doCmd(['mount', target, mountpoint])
def _umount(self, mountpoint):
umountCmd = ['umount', '-f', mountpoint]
doCmd(umountCmd)
ls = os.listdir(mountpoint)
if len(ls) == 0:
rmDirCmd = ['rm', '-r', mountpoint]
doCmd(rmDirCmd)
else:
logger.warning(OvmStoragePool._umount, "Something wrong when umount %s, there are still files in directory:%s", mountpoint, " ".join(ls))
@staticmethod
def create(jStr):
@ -174,14 +187,7 @@ class OvmStoragePool(OvmObject):
finally:
if exists(secMountPoint):
try:
umountCmd = ['umount', '-f', secMountPoint]
doCmd(umountCmd)
ls = os.listdir(secMountPoint)
if len(ls) == 0:
rmDirCmd = ['rm', '-r', secMountPoint]
doCmd(rmDirCmd)
else:
logger.warning(OvmStoragePool.downloadTemplate, "Something wrong when umount %s, there are still files in directory:%s", secMountPoint, " ".join(ls))
OvmStoragePool()._umount(secMountPoint)
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmStoragePool.downloadTemplate, 'unmount secondary storage at %s failed, %s'%(secMountPoint, errmsg))
@ -314,6 +320,48 @@ class OvmStoragePool(OvmObject):
errmsg = fmt_err_msg(e)
logger.error(OvmStoragePool.prepareOCFS2Nodes, errmsg)
raise XmlRpcFault(toErrCode(OvmStoragePool, OvmStoragePool.prepareOCFS2Nodes), errmsg)
@staticmethod
def createTemplateFromVolume(secStorageMountPath, installPath, volumePath):
try:
secMountPoint = ""
if not isfile(volumePath): raise Exception("Cannot find %s"%volumePath)
vmCfg = join(dirname(volumePath), 'vm.cfg')
cfgs = parseVmConfigureFile(vmCfg)
if len(cfgs) == 0: raise Exception("Cannot find vm.cfg, this volume(%s) seems not the ROOT volume. We don't support create template from non-ROOT volume"%volumePath)
vmName = cfgs['name']
if vmName in doCmd(['xm', 'list']):
raise Exception("%s is still running, please stop it first then create template again"%vmName)
tmpUuid = get_uuid()
secMountPoint = join("/var/cloud/", tmpUuid)
OvmStoragePool()._mount(secStorageMountPath, secMountPoint)
installPath = installPath.lstrip('/')
destPath = join(secMountPoint, installPath)
if exists(destPath):
logger.warning("%s is already here, delete it since it is most likely stale"%destPath)
doCmd(['rm', '-rf', destPath])
OvmStoragePool()._checkDirSizeForImage(secMountPoint, volumePath)
os.makedirs(destPath)
newName = get_uuid() + ".raw"
destName = join(destPath, newName)
doCmd(['cp', volumePath, destName])
size = os.path.getsize(destName)
resInstallPath = join(installPath, newName)
OvmStoragePool()._umount(secMountPoint)
rs = toGson({"installPath":resInstallPath, "templateFileName":newName, "virtualSize":size, "physicalSize":size})
return rs
except Exception, e:
try:
if exists(secMountPoint):
OvmStoragePool()._umount(secMountPoint)
except Exception, e:
logger.warning(OvmStoragePool.createTemplateFromVolume, "umount %s failed"%secMountPoint)
errmsg = fmt_err_msg(e)
logger.error(OvmStoragePool.createTemplateFromVolume, errmsg)
raise XmlRpcFault(toErrCode(OvmStoragePool, OvmStoragePool.createTemplateFromVolume), errmsg)

2
ovm/scripts/vm/hypervisor/ovm/OvmVmModule.py Normal file → Executable file
View File

@ -73,7 +73,7 @@ class OvmVm(OvmObject):
name = ''
bootDev = ''
type = ''
def _getVifs(self, vmName):
vmPath = OvmHost()._vmNameToPath(vmName)
domId = OvmHost()._getDomainIdByName(vmName)

View File

@ -25,7 +25,9 @@ import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.CleanupNetworkRulesCmd;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.CreateStoragePoolCommand;
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.FenceAnswer;
import com.cloud.agent.api.FenceCommand;
import com.cloud.agent.api.GetHostStatsAnswer;
@ -64,6 +66,7 @@ import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.VmStatsEntry;
import com.cloud.agent.api.storage.CreateAnswer;
import com.cloud.agent.api.storage.CreateCommand;
import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
import com.cloud.agent.api.storage.DestroyCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
@ -87,6 +90,7 @@ import com.cloud.ovm.object.OvmVm;
import com.cloud.ovm.object.OvmVolume;
import com.cloud.resource.ServerResource;
import com.cloud.resource.hypervisor.HypervisorResource;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.Volume;
import com.cloud.storage.template.TemplateInfo;
@ -1163,56 +1167,83 @@ public class OvmResourceBase implements ServerResource, HypervisorResource {
}
}
protected CreatePrivateTemplateAnswer execute(final CreatePrivateTemplateFromVolumeCommand cmd) {
String secondaryStoragePoolURL = cmd.getSecondaryStorageURL();
String volumePath = cmd.getVolumePath();
Long accountId = cmd.getAccountId();
Long templateId = cmd.getTemplateId();
int wait = cmd.getWait();
if (wait == 0) {
/* Defaut timeout 2 hours */
wait = 7200;
}
try {
URI uri;
uri = new URI(secondaryStoragePoolURL);
String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
String installPath = "template/tmpl/" + accountId + "/" + templateId;
Map<String, String> res = OvmStoragePool.createTemplateFromVolume(_conn, secondaryStorageMountPath, installPath, volumePath, wait);
return new CreatePrivateTemplateAnswer(cmd, true, null, res.get("installPath"), Long.valueOf(res.get("virtualSize")), Long.valueOf(res.get("physicalSize")), res.get("templateFileName"), ImageFormat.RAW);
} catch (Exception e) {
s_logger.debug("Create template failed", e);
return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage());
}
}
@Override
public Answer executeRequest(Command cmd) {
if (cmd instanceof ReadyCommand) {
Class<? extends Command> clazz = cmd.getClass();
if (clazz == ReadyCommand.class) {
return execute((ReadyCommand)cmd);
} else if (cmd instanceof CreateStoragePoolCommand) {
} else if (clazz == CreateStoragePoolCommand.class) {
return execute((CreateStoragePoolCommand)cmd);
} else if (cmd instanceof ModifyStoragePoolCommand) {
} else if (clazz == ModifyStoragePoolCommand.class) {
return execute((ModifyStoragePoolCommand)cmd);
} else if (cmd instanceof PrimaryStorageDownloadCommand) {
} else if (clazz == PrimaryStorageDownloadCommand.class) {
return execute((PrimaryStorageDownloadCommand)cmd);
} else if (cmd instanceof CreateCommand) {
} else if (clazz == CreateCommand.class) {
return execute((CreateCommand)cmd);
} else if (cmd instanceof GetHostStatsCommand) {
} else if (clazz == GetHostStatsCommand.class) {
return execute((GetHostStatsCommand)cmd);
} else if (cmd instanceof StopCommand) {
} else if (clazz == StopCommand.class) {
return execute((StopCommand)cmd);
} else if (cmd instanceof RebootCommand) {
} else if (clazz == RebootCommand.class) {
return execute((RebootCommand)cmd);
} else if (cmd instanceof GetStorageStatsCommand) {
} else if (clazz == GetStorageStatsCommand.class) {
return execute((GetStorageStatsCommand)cmd);
} else if (cmd instanceof GetVmStatsCommand) {
} else if (clazz == GetVmStatsCommand.class) {
return execute((GetVmStatsCommand)cmd);
} else if (cmd instanceof AttachVolumeCommand) {
} else if (clazz == AttachVolumeCommand.class) {
return execute((AttachVolumeCommand)cmd);
} else if (cmd instanceof DestroyCommand) {
} else if (clazz == DestroyCommand.class) {
return execute((DestroyCommand)cmd);
} else if (cmd instanceof PrepareForMigrationCommand) {
} else if (clazz == PrepareForMigrationCommand.class) {
return execute((PrepareForMigrationCommand)cmd);
} else if (cmd instanceof MigrateCommand) {
} else if (clazz == MigrateCommand.class) {
return execute((MigrateCommand)cmd);
} else if (cmd instanceof CheckVirtualMachineCommand) {
} else if (clazz == CheckVirtualMachineCommand.class) {
return execute((CheckVirtualMachineCommand)cmd);
} else if (cmd instanceof MaintainCommand) {
} else if (clazz == MaintainCommand.class) {
return execute((MaintainCommand)cmd);
} else if (cmd instanceof StartCommand) {
} else if (clazz == StartCommand.class) {
return execute((StartCommand)cmd);
} else if (cmd instanceof GetVncPortCommand) {
} else if (clazz == GetVncPortCommand.class) {
return execute((GetVncPortCommand)cmd);
} else if (cmd instanceof PingTestCommand) {
} else if (clazz == PingTestCommand.class) {
return execute((PingTestCommand)cmd);
} else if (cmd instanceof FenceCommand) {
} else if (clazz == FenceCommand.class) {
return execute((FenceCommand)cmd);
} else if (cmd instanceof AttachIsoCommand) {
} else if (clazz == AttachIsoCommand.class) {
return execute((AttachIsoCommand)cmd);
} else if (cmd instanceof SecurityIngressRulesCmd) {
} else if (clazz == SecurityIngressRulesCmd.class) {
return execute((SecurityIngressRulesCmd) cmd);
} else if (cmd instanceof CleanupNetworkRulesCmd) {
} else if (clazz == CleanupNetworkRulesCmd.class) {
return execute((CleanupNetworkRulesCmd) cmd);
} else if (cmd instanceof PrepareOCFS2NodesCommand) {
} else if (clazz == PrepareOCFS2NodesCommand.class) {
return execute((PrepareOCFS2NodesCommand)cmd);
} else if (clazz == CreatePrivateTemplateFromVolumeCommand.class) {
return execute((CreatePrivateTemplateFromVolumeCommand)cmd);
}else {
return Answer.createUnsupportedCommandAnswer(cmd);
}

View File

@ -67,4 +67,11 @@ public class OvmStoragePool extends OvmObject {
Object[] params = {clusterName, nodes};
c.call("OvmStoragePool.prepareOCFS2Nodes", params);
}
public static Map<String, String> createTemplateFromVolume(Connection c, String secStorageMountPath, String installPath, String volumePath, int timeout) throws XmlRpcException {
Object[] params = {secStorageMountPath, installPath, volumePath};
String res = (String) c.callTimeoutInSec("OvmStoragePool.createTemplateFromVolume", params, timeout);
Map info = Coder.mapFromJson(res);
return info;
}
}